style: fix linting issues met Prettier
This commit is contained in:
		
							parent
							
								
									7f670030a7
								
							
						
					
					
						commit
						0c47546814
					
				
					 30 changed files with 233 additions and 262 deletions
				
			
		|  | @ -2,10 +2,10 @@ import { UnauthorizedException } from '../exceptions/unauthorized-exception.js'; | ||||||
| import { getLogger } from '../logging/initalize.js'; | import { getLogger } from '../logging/initalize.js'; | ||||||
| import { AuthenticatedRequest } from '../middleware/auth/authenticated-request.js'; | import { AuthenticatedRequest } from '../middleware/auth/authenticated-request.js'; | ||||||
| import { envVars, getEnvVar } from '../util/envVars.js'; | import { envVars, getEnvVar } from '../util/envVars.js'; | ||||||
| import {createOrUpdateStudent, createStudent} from "../services/students"; | import { createOrUpdateStudent, createStudent } from '../services/students'; | ||||||
| import {AuthenticationInfo} from "../middleware/auth/authentication-info"; | import { AuthenticationInfo } from '../middleware/auth/authentication-info'; | ||||||
| import {Request, Response} from "express"; | import { Request, Response } from 'express'; | ||||||
| import {createOrUpdateTeacher, createTeacher} from "../services/teachers"; | import { createOrUpdateTeacher, createTeacher } from '../services/teachers'; | ||||||
| 
 | 
 | ||||||
| interface FrontendIdpConfig { | interface FrontendIdpConfig { | ||||||
|     authority: string; |     authority: string; | ||||||
|  | @ -47,20 +47,26 @@ export function handleGetFrontendAuthConfig(_req: Request, res: Response): void | ||||||
| 
 | 
 | ||||||
| export async function handleHello(req: AuthenticatedRequest): Promise<void> { | export async function handleHello(req: AuthenticatedRequest): Promise<void> { | ||||||
|     const auth: AuthenticationInfo = req.auth!; |     const auth: AuthenticationInfo = req.auth!; | ||||||
|     if (auth.accountType === "teacher") { |     if (auth.accountType === 'teacher') { | ||||||
|         await createTeacher({ |         await createTeacher( | ||||||
|             id: auth.username, |             { | ||||||
|             username: auth.username, |                 id: auth.username, | ||||||
|             firstName: auth.firstName ?? "", |                 username: auth.username, | ||||||
|             lastName: auth.lastName ?? "", |                 firstName: auth.firstName ?? '', | ||||||
|         }, true); |                 lastName: auth.lastName ?? '', | ||||||
|  |             }, | ||||||
|  |             true | ||||||
|  |         ); | ||||||
|     } else { |     } else { | ||||||
|         await createStudent({ |         await createStudent( | ||||||
|             id: auth.username, |             { | ||||||
|             username: auth.username, |                 id: auth.username, | ||||||
|             firstName: auth.firstName ?? "", |                 username: auth.username, | ||||||
|             lastName: auth.lastName ?? "", |                 firstName: auth.firstName ?? '', | ||||||
|         }, true); |                 lastName: auth.lastName ?? '', | ||||||
|  |             }, | ||||||
|  |             true | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Request, Response } from 'express'; | ||||||
| import { requireFields } from './error-helper.js'; | import { requireFields } from './error-helper.js'; | ||||||
| import { createInvitation, deleteInvitation, getAllInvitations, getInvitation, updateInvitation } from '../services/teacher-invitations.js'; | import { createInvitation, deleteInvitation, getAllInvitations, getInvitation, updateInvitation } from '../services/teacher-invitations.js'; | ||||||
| import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation'; | import { TeacherInvitationData } from '@dwengo-1/common/interfaces/teacher-invitation'; | ||||||
| import {ConflictException} from "../exceptions/conflict-exception"; | import { ConflictException } from '../exceptions/conflict-exception'; | ||||||
| 
 | 
 | ||||||
| export async function getAllInvitationsHandler(req: Request, res: Response): Promise<void> { | export async function getAllInvitationsHandler(req: Request, res: Response): Promise<void> { | ||||||
|     const username = req.params.username; |     const username = req.params.username; | ||||||
|  | @ -31,8 +31,8 @@ export async function createInvitationHandler(req: Request, res: Response): Prom | ||||||
|     const classId = req.body.class; |     const classId = req.body.class; | ||||||
|     requireFields({ sender, receiver, classId }); |     requireFields({ sender, receiver, classId }); | ||||||
| 
 | 
 | ||||||
|     if (sender === receiver){ |     if (sender === receiver) { | ||||||
|         throw new ConflictException("Cannot send an invitation to yourself"); |         throw new ConflictException('Cannot send an invitation to yourself'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const data = req.body as TeacherInvitationData; |     const data = req.body as TeacherInvitationData; | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ export function mapToUserDTO(user: User): UserDTO { | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function mapToUsername(user: {username: string}): string { | export function mapToUsername(user: { username: string }): string { | ||||||
|     return user.username; |     return user.username; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| import {envVars, getEnvVar} from '../../util/envVars.js'; | import { envVars, getEnvVar } from '../../util/envVars.js'; | ||||||
| import {expressjwt} from 'express-jwt'; | import { expressjwt } from 'express-jwt'; | ||||||
| import * as jwt from 'jsonwebtoken'; | import * as jwt from 'jsonwebtoken'; | ||||||
| import {JwtPayload} from 'jsonwebtoken'; | import { JwtPayload } from 'jsonwebtoken'; | ||||||
| import jwksClient from 'jwks-rsa'; | import jwksClient from 'jwks-rsa'; | ||||||
| import * as express from 'express'; | import * as express from 'express'; | ||||||
| import {AuthenticatedRequest} from './authenticated-request.js'; | import { AuthenticatedRequest } from './authenticated-request.js'; | ||||||
| import {AuthenticationInfo} from './authentication-info.js'; | import { AuthenticationInfo } from './authentication-info.js'; | ||||||
| import { UnauthorizedException } from '../../exceptions/unauthorized-exception.js'; | import { UnauthorizedException } from '../../exceptions/unauthorized-exception.js'; | ||||||
| 
 | 
 | ||||||
| const JWKS_CACHE = true; | const JWKS_CACHE = true; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { Request } from 'express'; | import { Request } from 'express'; | ||||||
| import { JwtPayload } from 'jsonwebtoken'; | import { JwtPayload } from 'jsonwebtoken'; | ||||||
| import { AuthenticationInfo } from './authentication-info.js'; | import { AuthenticationInfo } from './authentication-info.js'; | ||||||
| import * as core from "express-serve-static-core"; | import * as core from 'express-serve-static-core'; | ||||||
| 
 | 
 | ||||||
| export interface AuthenticatedRequest< | export interface AuthenticatedRequest< | ||||||
|     P = core.ParamsDictionary, |     P = core.ParamsDictionary, | ||||||
|  | @ -9,7 +9,7 @@ export interface AuthenticatedRequest< | ||||||
|     ReqBody = unknown, |     ReqBody = unknown, | ||||||
|     ReqQuery = core.Query, |     ReqQuery = core.Query, | ||||||
|     Locals extends Record<string, unknown> = Record<string, unknown>, |     Locals extends Record<string, unknown> = Record<string, unknown>, | ||||||
| > extends Request<P,ResBody,ReqBody,ReqQuery,Locals> { | > extends Request<P, ResBody, ReqBody, ReqQuery, Locals> { | ||||||
|     // Properties are optional since the user is not necessarily authenticated.
 |     // Properties are optional since the user is not necessarily authenticated.
 | ||||||
|     jwtPayload?: JwtPayload; |     jwtPayload?: JwtPayload; | ||||||
|     auth?: AuthenticationInfo; |     auth?: AuthenticationInfo; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {fetchClass} from "../../../services/classes"; | import { fetchClass } from '../../../services/classes'; | ||||||
| import {fetchAllGroups} from "../../../services/groups"; | import { fetchAllGroups } from '../../../services/groups'; | ||||||
| import {mapToUsername} from "../../../interfaces/user"; | import { mapToUsername } from '../../../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Expects the path to contain the path parameters 'classId' and 'id' (meaning the ID of the assignment). |  * Expects the path to contain the path parameters 'classId' and 'id' (meaning the ID of the assignment). | ||||||
|  | @ -9,15 +9,12 @@ import {mapToUsername} from "../../../interfaces/user"; | ||||||
|  * - either teachers of the class the assignment was posted in, |  * - either teachers of the class the assignment was posted in, | ||||||
|  * - or students in a group of the assignment. |  * - or students in a group of the assignment. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowIfHasAccessToAssignment = authorize( | export const onlyAllowIfHasAccessToAssignment = authorize(async (auth, req) => { | ||||||
|     async (auth, req) => { |     const { classid: classId, id: assignmentId } = req.params as { classid: string; id: number }; | ||||||
|         const { classid: classId, id: assignmentId } = req.params as { classid: string, id: number }; |     if (auth.accountType === 'teacher') { | ||||||
|         if (auth.accountType === "teacher") { |         const clazz = await fetchClass(classId); | ||||||
|             const clazz = await fetchClass(classId); |         return clazz.teachers.map(mapToUsername).includes(auth.username); | ||||||
|             return clazz.teachers.map(mapToUsername).includes(auth.username); |  | ||||||
|         }  |  | ||||||
|             const groups = await fetchAllGroups(classId, assignmentId); |  | ||||||
|             return groups.some(group => group.members.map((member) => member.username).includes(auth.username) ); |  | ||||||
|          |  | ||||||
|     } |     } | ||||||
| ); |     const groups = await fetchAllGroups(classId, assignmentId); | ||||||
|  |     return groups.some((group) => group.members.map((member) => member.username).includes(auth.username)); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| import * as express from "express"; | import * as express from 'express'; | ||||||
| import {UnauthorizedException} from "../../../exceptions/unauthorized-exception"; | import { UnauthorizedException } from '../../../exceptions/unauthorized-exception'; | ||||||
| import {ForbiddenException} from "../../../exceptions/forbidden-exception"; | import { ForbiddenException } from '../../../exceptions/forbidden-exception'; | ||||||
| import {RequestHandler} from "express"; | import { RequestHandler } from 'express'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Middleware which rejects unauthenticated users (with HTTP 401) and authenticated users which do not fulfill |  * Middleware which rejects unauthenticated users (with HTTP 401) and authenticated users which do not fulfill | ||||||
|  | @ -11,13 +11,17 @@ import {RequestHandler} from "express"; | ||||||
|  * @param accessCondition Predicate over the current AuthenticationInfo. Access is only granted when this evaluates |  * @param accessCondition Predicate over the current AuthenticationInfo. Access is only granted when this evaluates | ||||||
|  *                        to true. |  *                        to true. | ||||||
|  */ |  */ | ||||||
| export function authorize<P,ResBody,ReqBody,ReqQuery,Locals extends Record<string, unknown>>( | export function authorize<P, ResBody, ReqBody, ReqQuery, Locals extends Record<string, unknown>>( | ||||||
|     accessCondition: (auth: AuthenticationInfo, req: AuthenticatedRequest<P,ResBody,ReqBody,ReqQuery,Locals>) => boolean | Promise<boolean> |     accessCondition: (auth: AuthenticationInfo, req: AuthenticatedRequest<P, ResBody, ReqBody, ReqQuery, Locals>) => boolean | Promise<boolean> | ||||||
| ): RequestHandler<P,ResBody,ReqBody,ReqQuery,Locals> { | ): RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> { | ||||||
|     return async (req: AuthenticatedRequest<P,ResBody,ReqBody,ReqQuery,Locals>, _res: express.Response, next: express.NextFunction): Promise<void> => { |     return async ( | ||||||
|  |         req: AuthenticatedRequest<P, ResBody, ReqBody, ReqQuery, Locals>, | ||||||
|  |         _res: express.Response, | ||||||
|  |         next: express.NextFunction | ||||||
|  |     ): Promise<void> => { | ||||||
|         if (!req.auth) { |         if (!req.auth) { | ||||||
|             throw new UnauthorizedException(); |             throw new UnauthorizedException(); | ||||||
|         } else if (!await accessCondition(req.auth, req)) { |         } else if (!(await accessCondition(req.auth, req))) { | ||||||
|             throw new ForbiddenException(); |             throw new ForbiddenException(); | ||||||
|         } else { |         } else { | ||||||
|             next(); |             next(); | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| import {fetchClass} from "../../../services/classes"; | import { fetchClass } from '../../../services/classes'; | ||||||
| import {mapToUsername} from "../../../interfaces/user"; | import { mapToUsername } from '../../../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| async function teaches(teacherUsername: string, classId: string): Promise<boolean> { | async function teaches(teacherUsername: string, classId: string): Promise<boolean> { | ||||||
|     const clazz = await fetchClass(classId); |     const clazz = await fetchClass(classId); | ||||||
|  | @ -14,53 +14,45 @@ async function teaches(teacherUsername: string, classId: string): Promise<boolea | ||||||
|  * Only allows requests whose username parameter is equal to the username of the user who is logged in and requests |  * Only allows requests whose username parameter is equal to the username of the user who is logged in and requests | ||||||
|  * whose classId parameter references a class the logged-in user is a teacher of. |  * whose classId parameter references a class the logged-in user is a teacher of. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowStudentHimselfAndTeachersOfClass = authorize( | export const onlyAllowStudentHimselfAndTeachersOfClass = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     if (req.params.username === auth.username) { | ||||||
|         if (req.params.username === auth.username) { |         return true; | ||||||
|             return true; |     } else if (auth.accountType === 'teacher') { | ||||||
|         } else if (auth.accountType === "teacher") { |         return teaches(auth.username, req.params.classId); | ||||||
|             return teaches(auth.username, req.params.classId); |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| ); |     return false; | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Only let the request pass through if its path parameter "username" is the username of the currently logged-in |  * Only let the request pass through if its path parameter "username" is the username of the currently logged-in | ||||||
|  * teacher and the path parameter "classId" refers to a class the teacher teaches. |  * teacher and the path parameter "classId" refers to a class the teacher teaches. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowTeacherOfClass = authorize( | export const onlyAllowTeacherOfClass = authorize( | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => |     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => req.params.username === auth.username && teaches(auth.username, req.params.classId) | ||||||
|         req.params.username === auth.username && teaches(auth.username, req.params.classId), |  | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Only let the request pass through if the class id in it refers to a class the current user is in (as a student |  * Only let the request pass through if the class id in it refers to a class the current user is in (as a student | ||||||
|  * or teacher) |  * or teacher) | ||||||
|  */ |  */ | ||||||
| export const onlyAllowIfInClass = authorize( | export const onlyAllowIfInClass = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const classId = req.params.classId ?? req.params.classid ?? req.params.id; | ||||||
|         const classId = req.params.classId ?? req.params.classid ?? req.params.id; |     const clazz = await fetchClass(classId); | ||||||
|         const clazz = await fetchClass(classId); |     if (auth.accountType === 'teacher') { | ||||||
|         if (auth.accountType === "teacher") { |         return clazz.teachers.map(mapToUsername).includes(auth.username); | ||||||
|             return clazz.teachers.map(mapToUsername).includes(auth.username); |  | ||||||
|         } |  | ||||||
|         return clazz.students.map(mapToUsername).includes(auth.username); |  | ||||||
|     } |     } | ||||||
| ); |     return clazz.students.map(mapToUsername).includes(auth.username); | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Only allows the request to pass if the 'class' property in its body is a class the current user is a member of. |  * Only allows the request to pass if the 'class' property in its body is a class the current user is a member of. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowOwnClassInBody = authorize( | export const onlyAllowOwnClassInBody = authorize(async (auth, req) => { | ||||||
|     async (auth, req) => { |     const classId = (req.body as { class: string })?.class; | ||||||
|         const classId = (req.body as {class: string})?.class; |     const clazz = await fetchClass(classId); | ||||||
|         const clazz = await fetchClass(classId); |  | ||||||
| 
 | 
 | ||||||
|         if (auth.accountType === "teacher") { |     if (auth.accountType === 'teacher') { | ||||||
|             return clazz.teachers.map(mapToUsername).includes(auth.username); |         return clazz.teachers.map(mapToUsername).includes(auth.username); | ||||||
|         } |  | ||||||
|         return clazz.students.map(mapToUsername).includes(auth.username); |  | ||||||
|     } |     } | ||||||
| ); |     return clazz.students.map(mapToUsername).includes(auth.username); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {fetchClass} from "../../../services/classes"; | import { fetchClass } from '../../../services/classes'; | ||||||
| import {fetchGroup} from "../../../services/groups"; | import { fetchGroup } from '../../../services/groups'; | ||||||
| import {mapToUsername} from "../../../interfaces/user"; | import { mapToUsername } from '../../../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Expects the path to contain the path parameters 'classid', 'assignmentid' and 'groupid'. |  * Expects the path to contain the path parameters 'classid', 'assignmentid' and 'groupid'. | ||||||
|  | @ -9,17 +9,17 @@ import {mapToUsername} from "../../../interfaces/user"; | ||||||
|  * - either teachers of the class the assignment for the group was posted in, |  * - either teachers of the class the assignment for the group was posted in, | ||||||
|  * - or students in the group |  * - or students in the group | ||||||
|  */ |  */ | ||||||
| export const onlyAllowIfHasAccessToGroup = authorize( | export const onlyAllowIfHasAccessToGroup = authorize(async (auth, req) => { | ||||||
|     async (auth, req) => { |     const { | ||||||
|         const { classid: classId, assignmentid: assignmentId, groupid: groupId } = |         classid: classId, | ||||||
|             req.params as { classid: string, assignmentid: number, groupid: number }; |         assignmentid: assignmentId, | ||||||
|  |         groupid: groupId, | ||||||
|  |     } = req.params as { classid: string; assignmentid: number; groupid: number }; | ||||||
| 
 | 
 | ||||||
|         if (auth.accountType === "teacher") { |     if (auth.accountType === 'teacher') { | ||||||
|             const clazz = await fetchClass(classId); |         const clazz = await fetchClass(classId); | ||||||
|             return clazz.teachers.map(mapToUsername).includes(auth.username); |         return clazz.teachers.map(mapToUsername).includes(auth.username); | ||||||
|         }  // User is student
 |     } // User is student
 | ||||||
|             const group = await fetchGroup(classId, assignmentId, groupId); |     const group = await fetchGroup(classId, assignmentId, groupId); | ||||||
|             return group.members.map(mapToUsername).includes(auth.username); |     return group.members.map(mapToUsername).includes(auth.username); | ||||||
|          | }); | ||||||
|     } |  | ||||||
| ); |  | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Only allows requests whose learning path personalization query parameters ('forGroup' / 'assignmentNo' / 'classId') |  * Only allows requests whose learning path personalization query parameters ('forGroup' / 'assignmentNo' / 'classId') | ||||||
|  | @ -9,15 +9,12 @@ import {AuthenticatedRequest} from "../authenticated-request"; | ||||||
|  * - or set to a group the user is in, |  * - or set to a group the user is in, | ||||||
|  * - or set to anything if the user is a teacher. |  * - or set to anything if the user is a teacher. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowPersonalizationForOwnGroup = authorize( | export const onlyAllowPersonalizationForOwnGroup = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const { forGroup, assignmentNo, classId } = req.params; | ||||||
|         const {forGroup, assignmentNo, classId} = req.params; |     if (auth.accountType === 'student' && forGroup && assignmentNo && classId) { | ||||||
|         if (auth.accountType === "student" && forGroup && assignmentNo && classId) { |         // TODO: groupNumber?
 | ||||||
|             // TODO: groupNumber? 
 |         // Const group = await fetchGroup(Number(classId), Number(assignmentNo), )
 | ||||||
|             // Const group = await fetchGroup(Number(classId), Number(assignmentNo), )
 |         return false; | ||||||
|             return false; |  | ||||||
|         }  |  | ||||||
|             return true; |  | ||||||
|          |  | ||||||
|     } |     } | ||||||
| ); |     return true; | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,72 +1,65 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| import {requireFields} from "../../../controllers/error-helper"; | import { requireFields } from '../../../controllers/error-helper'; | ||||||
| import {getLearningObjectId, getQuestionId} from "../../../controllers/questions"; | import { getLearningObjectId, getQuestionId } from '../../../controllers/questions'; | ||||||
| import {fetchQuestion} from "../../../services/questions"; | import { fetchQuestion } from '../../../services/questions'; | ||||||
| import {FALLBACK_SEQ_NUM} from "../../../config"; | import { FALLBACK_SEQ_NUM } from '../../../config'; | ||||||
| import {fetchAnswer} from "../../../services/answers"; | import { fetchAnswer } from '../../../services/answers'; | ||||||
| import {mapToUsername} from "../../../interfaces/user"; | import { mapToUsername } from '../../../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| export const onlyAllowAuthor = authorize( | export const onlyAllowAuthor = authorize( | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { author: string }).author === auth.username |     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { author: string }).author === auth.username | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| export const onlyAllowAuthorRequest = authorize( | export const onlyAllowAuthorRequest = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const hruid = req.params.hruid; | ||||||
|         const hruid = req.params.hruid; |     const version = req.params.version; | ||||||
|         const version = req.params.version; |     const language = req.query.lang as string; | ||||||
|         const language = req.query.lang as string; |     const seq = req.params.seq; | ||||||
|         const seq = req.params.seq; |     requireFields({ hruid }); | ||||||
|         requireFields({ hruid }); |  | ||||||
| 
 | 
 | ||||||
|         const learningObjectId = getLearningObjectId(hruid, version, language); |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         const questionId = getQuestionId(learningObjectId, seq); |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
| 
 | 
 | ||||||
|         const question = await fetchQuestion(questionId); |     const question = await fetchQuestion(questionId); | ||||||
| 
 | 
 | ||||||
|         return question.author.username === auth.username; |     return question.author.username === auth.username; | ||||||
|     } | }); | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| export const onlyAllowAuthorRequestAnswer = authorize( | export const onlyAllowAuthorRequestAnswer = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const hruid = req.params.hruid; | ||||||
|         const hruid = req.params.hruid; |     const version = req.params.version; | ||||||
|         const version = req.params.version; |     const language = req.query.lang as string; | ||||||
|         const language = req.query.lang as string; |     const seq = req.params.seq; | ||||||
|         const seq = req.params.seq; |     const seqAnswer = req.params.seqAnswer; | ||||||
|         const seqAnswer = req.params.seqAnswer; |     requireFields({ hruid }); | ||||||
|         requireFields({ hruid }); |  | ||||||
| 
 | 
 | ||||||
|         const learningObjectId = getLearningObjectId(hruid, version, language); |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         const questionId = getQuestionId(learningObjectId, seq); |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
| 
 | 
 | ||||||
|         const sequenceNumber = Number(seqAnswer) || FALLBACK_SEQ_NUM; |     const sequenceNumber = Number(seqAnswer) || FALLBACK_SEQ_NUM; | ||||||
|         const answer = await fetchAnswer(questionId, sequenceNumber); |     const answer = await fetchAnswer(questionId, sequenceNumber); | ||||||
| 
 | 
 | ||||||
|         return answer.author.username === auth.username; |     return answer.author.username === auth.username; | ||||||
|     } | }); | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| export const onlyAllowIfHasAccessToQuestion = authorize( | export const onlyAllowIfHasAccessToQuestion = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const hruid = req.params.hruid; | ||||||
|         const hruid = req.params.hruid; |     const version = req.params.version; | ||||||
|         const version = req.params.version; |     const language = req.query.lang as string; | ||||||
|         const language = req.query.lang as string; |     const seq = req.params.seq; | ||||||
|         const seq = req.params.seq; |     requireFields({ hruid }); | ||||||
|         requireFields({ hruid }); |  | ||||||
| 
 | 
 | ||||||
|         const learningObjectId = getLearningObjectId(hruid, version, language); |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         const questionId = getQuestionId(learningObjectId, seq); |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
| 
 | 
 | ||||||
|         const question = await fetchQuestion(questionId); |     const question = await fetchQuestion(questionId); | ||||||
|         const group = question.inGroup; |     const group = question.inGroup; | ||||||
| 
 | 
 | ||||||
|         if (auth.accountType === "teacher") { |     if (auth.accountType === 'teacher') { | ||||||
|             const cls = group.assignment.within; // TODO check if contains full objects
 |         const cls = group.assignment.within; // TODO check if contains full objects
 | ||||||
|             return cls.teachers.map(mapToUsername).includes(auth.username); |         return cls.teachers.map(mapToUsername).includes(auth.username); | ||||||
|         }  // User is student
 |     } // User is student
 | ||||||
|             return group.members.map(mapToUsername).includes(auth.username); |     return group.members.map(mapToUsername).includes(auth.username); | ||||||
|          | }); | ||||||
|     } |  | ||||||
| ); |  | ||||||
|  |  | ||||||
|  | @ -1,29 +1,27 @@ | ||||||
| import { languageMap } from "dwengo-1-common/util/language"; | import { languageMap } from 'dwengo-1-common/util/language'; | ||||||
| import { LearningObjectIdentifier } from "../../../entities/content/learning-object-identifier"; | import { LearningObjectIdentifier } from '../../../entities/content/learning-object-identifier'; | ||||||
| import { fetchSubmission } from "../../../services/submissions"; | import { fetchSubmission } from '../../../services/submissions'; | ||||||
| import { AuthenticatedRequest } from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| import { AuthenticationInfo } from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import { authorize } from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import { FALLBACK_LANG } from "../../../config"; | import { FALLBACK_LANG } from '../../../config'; | ||||||
| import { mapToUsername } from "../../../interfaces/user"; | import { mapToUsername } from '../../../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| export const onlyAllowSubmitter = authorize( | export const onlyAllowSubmitter = authorize( | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { submitter: string }).submitter === auth.username |     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { submitter: string }).submitter === auth.username | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| export const onlyAllowIfHasAccessToSubmission = authorize( | export const onlyAllowIfHasAccessToSubmission = authorize(async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { | ||||||
|     async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { |     const { hruid: lohruid, id: submissionNumber } = req.params; | ||||||
|         const { hruid: lohruid, id: submissionNumber } = req.params; |     const { language: lang, version: version } = req.query; | ||||||
|         const { language: lang, version: version } = req.query; |  | ||||||
| 
 | 
 | ||||||
|         const loId = new LearningObjectIdentifier(lohruid,  languageMap[lang as string] ?? FALLBACK_LANG, Number(version)) |     const loId = new LearningObjectIdentifier(lohruid, languageMap[lang as string] ?? FALLBACK_LANG, Number(version)); | ||||||
|         const submission = await fetchSubmission(loId, Number(submissionNumber)); |     const submission = await fetchSubmission(loId, Number(submissionNumber)); | ||||||
| 
 | 
 | ||||||
|         if (auth.accountType === "teacher") { |     if (auth.accountType === 'teacher') { | ||||||
|             // Dit kan niet werken om dat al deze objecten niet gepopulate zijn. 
 |         // Dit kan niet werken om dat al deze objecten niet gepopulate zijn.
 | ||||||
|             return submission.onBehalfOf.assignment.within.teachers.map(mapToUsername).includes(auth.username); |         return submission.onBehalfOf.assignment.within.teachers.map(mapToUsername).includes(auth.username); | ||||||
|         }  |  | ||||||
| 
 |  | ||||||
|         return submission.onBehalfOf.members.map(mapToUsername).includes(auth.username); |  | ||||||
|     } |     } | ||||||
| ) | 
 | ||||||
|  |     return submission.onBehalfOf.members.map(mapToUsername).includes(auth.username); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,23 +1,17 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| 
 | 
 | ||||||
| export const onlyAllowSenderOrReceiver = authorize( | export const onlyAllowSenderOrReceiver = authorize( | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => |     (auth: AuthenticationInfo, req: AuthenticatedRequest) => req.params.sender === auth.username || req.params.receiver === auth.username | ||||||
|         req.params.sender === auth.username || req.params.receiver === auth.username |  | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| export const onlyAllowSender = authorize( | export const onlyAllowSender = authorize((auth: AuthenticationInfo, req: AuthenticatedRequest) => req.params.sender === auth.username); | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => |  | ||||||
|         req.params.sender === auth.username |  | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| export const onlyAllowSenderBody = authorize( | export const onlyAllowSenderBody = authorize( | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => |     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { sender: string }).sender === auth.username | ||||||
|         (req.body as { sender: string }).sender === auth.username |  | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| export const onlyAllowReceiverBody = authorize( | export const onlyAllowReceiverBody = authorize( | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => |     (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { receiver: string }).receiver === auth.username | ||||||
|         (req.body as { receiver: string }).receiver === auth.username |  | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | @ -1,10 +1,8 @@ | ||||||
| import {authorize} from "./auth-checks"; | import { authorize } from './auth-checks'; | ||||||
| import {AuthenticationInfo} from "../authentication-info"; | import { AuthenticationInfo } from '../authentication-info'; | ||||||
| import {AuthenticatedRequest} from "../authenticated-request"; | import { AuthenticatedRequest } from '../authenticated-request'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Only allow the user whose username is in the path parameter "username" to access the endpoint. |  * Only allow the user whose username is in the path parameter "username" to access the endpoint. | ||||||
|  */ |  */ | ||||||
| export const onlyAllowUserHimself = authorize( | export const onlyAllowUserHimself = authorize((auth: AuthenticationInfo, req: AuthenticatedRequest) => req.params.username === auth.username); | ||||||
|     (auth: AuthenticationInfo, req: AuthenticatedRequest) => req.params.username === auth.username |  | ||||||
| ); |  | ||||||
|  |  | ||||||
|  | @ -1,12 +1,7 @@ | ||||||
| import express from 'express'; | import express from 'express'; | ||||||
| import { createAnswerHandler, deleteAnswerHandler, getAnswerHandler, getAllAnswersHandler, updateAnswerHandler } from '../controllers/answers.js'; | import { createAnswerHandler, deleteAnswerHandler, getAnswerHandler, getAllAnswersHandler, updateAnswerHandler } from '../controllers/answers.js'; | ||||||
| import {adminOnly, teachersOnly} from "../middleware/auth/checks/auth-checks"; | import { adminOnly, teachersOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import { | import { onlyAllowAuthor, onlyAllowAuthorRequestAnswer, onlyAllowIfHasAccessToQuestion } from '../middleware/auth/checks/question-checks'; | ||||||
|     onlyAllowAuthor, |  | ||||||
|     onlyAllowAuthorRequestAnswer, |  | ||||||
|     onlyAllowIfHasAccessToQuestion |  | ||||||
| } from "../middleware/auth/checks/question-checks"; |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,9 +8,9 @@ import { | ||||||
|     putAssignmentHandler, |     putAssignmentHandler, | ||||||
| } from '../controllers/assignments.js'; | } from '../controllers/assignments.js'; | ||||||
| import groupRouter from './groups.js'; | import groupRouter from './groups.js'; | ||||||
| import {teachersOnly} from "../middleware/auth/checks/auth-checks"; | import { teachersOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import {onlyAllowIfInClass} from "../middleware/auth/checks/class-auth-checks"; | import { onlyAllowIfInClass } from '../middleware/auth/checks/class-auth-checks'; | ||||||
| import {onlyAllowIfHasAccessToAssignment} from "../middleware/auth/checks/assignment-auth-checks"; | import { onlyAllowIfHasAccessToAssignment } from '../middleware/auth/checks/assignment-auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,8 +14,8 @@ import { | ||||||
|     putClassHandler, |     putClassHandler, | ||||||
| } from '../controllers/classes.js'; | } from '../controllers/classes.js'; | ||||||
| import assignmentRouter from './assignments.js'; | import assignmentRouter from './assignments.js'; | ||||||
| import {adminOnly, teachersOnly} from "../middleware/auth/checks/auth-checks"; | import { adminOnly, teachersOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import {onlyAllowIfInClass} from "../middleware/auth/checks/class-auth-checks"; | import { onlyAllowIfInClass } from '../middleware/auth/checks/class-auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,9 +7,9 @@ import { | ||||||
|     getGroupSubmissionsHandler, |     getGroupSubmissionsHandler, | ||||||
|     putGroupHandler, |     putGroupHandler, | ||||||
| } from '../controllers/groups.js'; | } from '../controllers/groups.js'; | ||||||
| import {onlyAllowIfHasAccessToGroup} from "../middleware/auth/checks/group-auth-checker"; | import { onlyAllowIfHasAccessToGroup } from '../middleware/auth/checks/group-auth-checker'; | ||||||
| import {teachersOnly} from "../middleware/auth/checks/auth-checks"; | import { teachersOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import {onlyAllowIfHasAccessToAssignment} from "../middleware/auth/checks/assignment-auth-checks"; | import { onlyAllowIfHasAccessToAssignment } from '../middleware/auth/checks/assignment-auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import { getAllLearningObjects, getAttachment, getLearningObject, getLearningObj | ||||||
| 
 | 
 | ||||||
| import submissionRoutes from './submissions.js'; | import submissionRoutes from './submissions.js'; | ||||||
| import questionRoutes from './questions.js'; | import questionRoutes from './questions.js'; | ||||||
| import {authenticatedOnly} from "../middleware/auth/checks/auth-checks"; | import { authenticatedOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import express from 'express'; | import express from 'express'; | ||||||
| import { getLearningPaths } from '../controllers/learning-paths.js'; | import { getLearningPaths } from '../controllers/learning-paths.js'; | ||||||
| import {authenticatedOnly} from "../middleware/auth/checks/auth-checks"; | import { authenticatedOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,13 +1,9 @@ | ||||||
| import express from 'express'; | import express from 'express'; | ||||||
| import { createQuestionHandler, deleteQuestionHandler, getAllQuestionsHandler, getQuestionHandler } from '../controllers/questions.js'; | import { createQuestionHandler, deleteQuestionHandler, getAllQuestionsHandler, getQuestionHandler } from '../controllers/questions.js'; | ||||||
| import answerRoutes from './answers.js'; | import answerRoutes from './answers.js'; | ||||||
| import {adminOnly, studentsOnly} from "../middleware/auth/checks/auth-checks"; | import { adminOnly, studentsOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import {updateAnswerHandler} from "../controllers/answers"; | import { updateAnswerHandler } from '../controllers/answers'; | ||||||
| import { | import { onlyAllowAuthor, onlyAllowAuthorRequest, onlyAllowIfHasAccessToQuestion } from '../middleware/auth/checks/question-checks'; | ||||||
|     onlyAllowAuthor, |  | ||||||
|     onlyAllowAuthorRequest, |  | ||||||
|     onlyAllowIfHasAccessToQuestion |  | ||||||
| } from "../middleware/auth/checks/question-checks"; |  | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
|  | @ -23,7 +19,7 @@ router.get('/:seq', onlyAllowIfHasAccessToQuestion, getQuestionHandler); | ||||||
| 
 | 
 | ||||||
| router.delete('/:seq', studentsOnly, onlyAllowAuthorRequest, deleteQuestionHandler); | router.delete('/:seq', studentsOnly, onlyAllowAuthorRequest, deleteQuestionHandler); | ||||||
| 
 | 
 | ||||||
| router.put("/:seq", studentsOnly, onlyAllowAuthorRequest, updateAnswerHandler); | router.put('/:seq', studentsOnly, onlyAllowAuthorRequest, updateAnswerHandler); | ||||||
| 
 | 
 | ||||||
| router.use('/:seq/answers', answerRoutes); | router.use('/:seq/answers', answerRoutes); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,8 +5,8 @@ import { | ||||||
|     getStudentRequestHandler, |     getStudentRequestHandler, | ||||||
|     getStudentRequestsHandler, |     getStudentRequestsHandler, | ||||||
| } from '../controllers/students.js'; | } from '../controllers/students.js'; | ||||||
| import {onlyAllowUserHimself} from "../middleware/auth/checks/user-auth-checks"; | import { onlyAllowUserHimself } from '../middleware/auth/checks/user-auth-checks'; | ||||||
| import {onlyAllowStudentHimselfAndTeachersOfClass} from "../middleware/auth/checks/class-auth-checks"; | import { onlyAllowStudentHimselfAndTeachersOfClass } from '../middleware/auth/checks/class-auth-checks'; | ||||||
| 
 | 
 | ||||||
| // Under /:username/joinRequests/
 | // Under /:username/joinRequests/
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,8 +11,8 @@ import { | ||||||
|     getStudentSubmissionsHandler, |     getStudentSubmissionsHandler, | ||||||
| } from '../controllers/students.js'; | } from '../controllers/students.js'; | ||||||
| import joinRequestRouter from './student-join-requests.js'; | import joinRequestRouter from './student-join-requests.js'; | ||||||
| import {onlyAllowUserHimself} from "../middleware/auth/checks/user-auth-checks"; | import { onlyAllowUserHimself } from '../middleware/auth/checks/user-auth-checks'; | ||||||
| import {adminOnly} from "../middleware/auth/checks/auth-checks"; | import { adminOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,18 +6,19 @@ import { | ||||||
|     getInvitationHandler, |     getInvitationHandler, | ||||||
|     updateInvitationHandler, |     updateInvitationHandler, | ||||||
| } from '../controllers/teacher-invitations'; | } from '../controllers/teacher-invitations'; | ||||||
| import {onlyAllowUserHimself} from "../middleware/auth/checks/user-auth-checks"; | import { onlyAllowUserHimself } from '../middleware/auth/checks/user-auth-checks'; | ||||||
| import { | import { | ||||||
|     onlyAllowReceiverBody, onlyAllowSender, |     onlyAllowReceiverBody, | ||||||
|  |     onlyAllowSender, | ||||||
|     onlyAllowSenderBody, |     onlyAllowSenderBody, | ||||||
|     onlyAllowSenderOrReceiver |     onlyAllowSenderOrReceiver, | ||||||
| } from "../middleware/auth/checks/teacher-invitation-checks"; | } from '../middleware/auth/checks/teacher-invitation-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router({ mergeParams: true }); | const router = express.Router({ mergeParams: true }); | ||||||
| 
 | 
 | ||||||
| router.get('/:username', onlyAllowUserHimself, getAllInvitationsHandler); | router.get('/:username', onlyAllowUserHimself, getAllInvitationsHandler); | ||||||
| 
 | 
 | ||||||
| router.get('/:sender/:receiver/:classId', onlyAllowSenderOrReceiver ,getInvitationHandler); | router.get('/:sender/:receiver/:classId', onlyAllowSenderOrReceiver, getInvitationHandler); | ||||||
| 
 | 
 | ||||||
| router.post('/', onlyAllowSenderBody, createInvitationHandler); | router.post('/', onlyAllowSenderBody, createInvitationHandler); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,9 +12,9 @@ import { | ||||||
| } from '../controllers/teachers.js'; | } from '../controllers/teachers.js'; | ||||||
| import invitationRouter from './teacher-invitations.js'; | import invitationRouter from './teacher-invitations.js'; | ||||||
| 
 | 
 | ||||||
| import {adminOnly} from "../middleware/auth/checks/auth-checks"; | import { adminOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| import {onlyAllowUserHimself} from "../middleware/auth/checks/user-auth-checks"; | import { onlyAllowUserHimself } from '../middleware/auth/checks/user-auth-checks'; | ||||||
| import {onlyAllowTeacherOfClass} from "../middleware/auth/checks/class-auth-checks"; | import { onlyAllowTeacherOfClass } from '../middleware/auth/checks/class-auth-checks'; | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
| // Root endpoint used to search objects
 | // Root endpoint used to search objects
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import express from 'express'; | import express from 'express'; | ||||||
| import { getThemesHandler, getHruidsByThemeHandler } from '../controllers/themes.js'; | import { getThemesHandler, getHruidsByThemeHandler } from '../controllers/themes.js'; | ||||||
| import {authenticatedOnly} from "../middleware/auth/checks/auth-checks"; | import { authenticatedOnly } from '../middleware/auth/checks/auth-checks'; | ||||||
| 
 | 
 | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; | ||||||
| import { fetchStudent } from './students.js'; | import { fetchStudent } from './students.js'; | ||||||
| import { NotFoundException } from '../exceptions/not-found-exception.js'; | import { NotFoundException } from '../exceptions/not-found-exception.js'; | ||||||
| import { FALLBACK_VERSION_NUM } from '../config.js'; | import { FALLBACK_VERSION_NUM } from '../config.js'; | ||||||
| import {ConflictException} from "../exceptions/conflict-exception"; | import { ConflictException } from '../exceptions/conflict-exception'; | ||||||
| 
 | 
 | ||||||
| export async function getQuestionsAboutLearningObjectInAssignment( | export async function getQuestionsAboutLearningObjectInAssignment( | ||||||
|     loId: LearningObjectIdentifier, |     loId: LearningObjectIdentifier, | ||||||
|  | @ -91,12 +91,12 @@ export async function createQuestion(loId: LearningObjectIdentifier, questionDat | ||||||
|     const assignment = mapToAssignment(questionData.inGroup.assignment as AssignmentDTO, clazz!); |     const assignment = mapToAssignment(questionData.inGroup.assignment as AssignmentDTO, clazz!); | ||||||
|     const group = await getGroupRepository().findByAssignmentAndGroupNumber(assignment, questionData.inGroup.groupNumber); |     const group = await getGroupRepository().findByAssignmentAndGroupNumber(assignment, questionData.inGroup.groupNumber); | ||||||
| 
 | 
 | ||||||
|     if (!group){ |     if (!group) { | ||||||
|         throw new NotFoundException("Group with id and assignment not found"); |         throw new NotFoundException('Group with id and assignment not found'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (! group.members.contains(author)) { |     if (!group.members.contains(author)) { | ||||||
|         throw new ConflictException("Author is not part of this group"); |         throw new ConflictException('Author is not part of this group'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const question = await questionRepository.createQuestion({ |     const question = await questionRepository.createQuestion({ | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | ||||||
| import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | ||||||
| import { ConflictException } from '../exceptions/conflict-exception.js'; | import { ConflictException } from '../exceptions/conflict-exception.js'; | ||||||
| import { Submission } from '../entities/assignments/submission.entity'; | import { Submission } from '../entities/assignments/submission.entity'; | ||||||
| import {mapToUsername} from "../interfaces/user"; | import { mapToUsername } from '../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| export async function getAllStudents(full: boolean): Promise<StudentDTO[] | string[]> { | export async function getAllStudents(full: boolean): Promise<StudentDTO[] | string[]> { | ||||||
|     const studentRepository = getStudentRepository(); |     const studentRepository = getStudentRepository(); | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ export async function createInvitation(data: TeacherInvitationData): Promise<Tea | ||||||
|         throw new ConflictException('The teacher sending the invite is not part of the class'); |         throw new ConflictException('The teacher sending the invite is not part of the class'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (cls.teachers.contains(receiver)){ |     if (cls.teachers.contains(receiver)) { | ||||||
|         throw new ConflictException('The teacher receiving the invite is already part of the class'); |         throw new ConflictException('The teacher receiving the invite is already part of the class'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,7 +30,7 @@ import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | ||||||
| import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | import { ClassJoinRequestDTO } from '@dwengo-1/common/interfaces/class-join-request'; | ||||||
| import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | import { ClassStatus } from '@dwengo-1/common/util/class-join-request'; | ||||||
| import { ConflictException } from '../exceptions/conflict-exception.js'; | import { ConflictException } from '../exceptions/conflict-exception.js'; | ||||||
| import {mapToUsername} from "../interfaces/user"; | import { mapToUsername } from '../interfaces/user'; | ||||||
| 
 | 
 | ||||||
| export async function getAllTeachers(full: boolean): Promise<TeacherDTO[] | string[]> { | export async function getAllTeachers(full: boolean): Promise<TeacherDTO[] | string[]> { | ||||||
|     const teacherRepository: TeacherRepository = getTeacherRepository(); |     const teacherRepository: TeacherRepository = getTeacherRepository(); | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Lint Action
						Lint Action