From 1a6c780de5916a4ae9c70172100df137cfb57f53 Mon Sep 17 00:00:00 2001 From: Stefan-5422 Date: Tue, 7 Jun 2022 18:22:55 +0000 Subject: [PATCH] [create-pull-request] push formatted files --- src/Controllers/admin.controller.ts | 4 +- src/Controllers/discipline.controller.ts | 9 +- src/Controllers/group.controllers.ts | 32 ++-- src/Controllers/media.controller.ts | 1 - src/Controllers/participant.controller.ts | 10 +- src/Controllers/role.controller.ts | 6 +- src/Controllers/team.controller.ts | 13 +- src/Middleware/auth/auth.ts | 210 +++++++++++----------- src/Middleware/auth/teamleaderAuth.ts | 94 +++++----- src/Routes/event.routes.ts | 8 +- src/Routes/media.routes.ts | 43 +++-- src/Routes/role.routes.ts | 2 +- 12 files changed, 222 insertions(+), 210 deletions(-) diff --git a/src/Controllers/admin.controller.ts b/src/Controllers/admin.controller.ts index f942845..cca123f 100644 --- a/src/Controllers/admin.controller.ts +++ b/src/Controllers/admin.controller.ts @@ -29,7 +29,9 @@ export const getAllAdmins = async (req: Request, res: Response) => { } // TODO: Add exception handling - const users = await prisma.admin.findMany({ select: { pid: true, name: true, permission_level: true, groups: { select: { pid: true } } } }); + const users = await prisma.admin.findMany({ + select: { pid: true, name: true, permission_level: true, groups: { select: { pid: true } } }, + }); res.status(200).json({ type: "success", diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index 5727202..7caafe0 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -168,7 +168,14 @@ export const createDiscipline = async (req: Request<{ eventPid: string }, {}, Cr try { const discipline = await prisma.discipline.create({ - data: { name, minTeamSize, maxTeamSize, briefDescription, fullDescription, event: { connect: { pid: req.params.eventPid } } }, + data: { + name, + minTeamSize, + maxTeamSize, + briefDescription, + fullDescription, + event: { connect: { pid: req.params.eventPid } }, + }, select: basicDiscipline, }); diff --git a/src/Controllers/group.controllers.ts b/src/Controllers/group.controllers.ts index 6c2c2ea..c77ac6b 100644 --- a/src/Controllers/group.controllers.ts +++ b/src/Controllers/group.controllers.ts @@ -38,7 +38,7 @@ const detailedGroup = { organisation: { select: { pid: true, name: true } }, participants: { select: { pid: true, firstName: true, lastName: true } }, admins: { select: { pid: true, name: true } }, -} +}; export const _getAllGroups = async (res: Response, organisationId: string | undefined) => { const groups = await prisma.group.findMany({ @@ -88,12 +88,12 @@ export const getGroup = async (req: Request, res: Response) where: { pid }, select: req.auth?.isAuthenticated ? { - pid: true, - name: true, - organisation: { select: { pid: true, name: true } }, - admins: { select: { pid: true, name: true } }, - participants: { select: { pid: true } }, - } + pid: true, + name: true, + organisation: { select: { pid: true, name: true } }, + admins: { select: { pid: true, name: true } }, + participants: { select: { pid: true } }, + } : basicGroup, }); @@ -112,15 +112,15 @@ export const getGroup = async (req: Request, res: Response) }, ...(req.auth?.isAuthenticated ? { - admins: group.admins?.map((admin) => ({ - ...admin, - _links: [{ rel: "self", type: "GET", href: `/api/admins/${admin.pid}` }], - })), - participants: group.participants?.map((participant) => ({ - ...participant, - _links: [{ rel: "self", type: "GET", href: `/api/participant/${participant.pid}` }], - })), - } + admins: group.admins?.map((admin) => ({ + ...admin, + _links: [{ rel: "self", type: "GET", href: `/api/admins/${admin.pid}` }], + })), + participants: group.participants?.map((participant) => ({ + ...participant, + _links: [{ rel: "self", type: "GET", href: `/api/participant/${participant.pid}` }], + })), + } : {}), }, }, diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index d5b4b36..57f231e 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -224,7 +224,6 @@ export const linkMedia = async (req: Request<{ pid: string }, {}, { mediaPid: st throw e; } - }; export const unlinkMedia = async (req: Request<{ pid: string; mediaPid: string }>, res: Response) => { diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 307dcba..08bf4db 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -64,13 +64,13 @@ export const createParticipant = async (req: Request<{ teamPid: string }>, res: try { const discipline = await prisma.team.findUnique({ where: { pid: teamPid }, - select: { discipline: true } + select: { discipline: true }, }); const maxteamsize = discipline?.discipline.maxTeamSize; const userCount = await prisma.participant.count({ - where: { team: { pid: teamPid } } + where: { team: { pid: teamPid } }, }); if (maxteamsize == userCount) { @@ -88,7 +88,7 @@ export const createParticipant = async (req: Request<{ teamPid: string }>, res: select: returnedParticipant, }); - return res.status(201).json({ type: "success", payload: { participant }, }); + return res.status(201).json({ type: "success", payload: { participant } }); } catch (e) { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { return res @@ -176,9 +176,7 @@ export const deleteParticipant = async (req: Request<{ pid: string }>, res: Resp }; export async function getGroupByParticipantPid(partPid: string) { - const parti = ( - await prisma.participant.findUnique({ where: { pid: partPid }, select: { group: true } }) - )?.group.pid; + const parti = (await prisma.participant.findUnique({ where: { pid: partPid }, select: { group: true } }))?.group.pid; if (!parti) { throw new NotFoundError("participant", partPid); diff --git a/src/Controllers/role.controller.ts b/src/Controllers/role.controller.ts index 1c761e6..8860f52 100644 --- a/src/Controllers/role.controller.ts +++ b/src/Controllers/role.controller.ts @@ -106,7 +106,11 @@ export async function assignParticipantToRole(req: Request<{ pid: string }>, res } try { - const schema = await prisma.role.update({ where: { pid }, data: { participant: { connect: { pid: participantPid } } }, select: detailedRole }); + const schema = await prisma.role.update({ + where: { pid }, + data: { participant: { connect: { pid: participantPid } } }, + select: detailedRole, + }); return res.status(200).json({ type: "success", diff --git a/src/Controllers/team.controller.ts b/src/Controllers/team.controller.ts index 16dd84a..7b685a0 100644 --- a/src/Controllers/team.controller.ts +++ b/src/Controllers/team.controller.ts @@ -119,7 +119,7 @@ export const deleteTeam = async (req: Request, res: Response) => { } if (req.auth?.permission_level == "STANDARD") { - throw new AuthError("STANDARD Admins are not allowed to delete Teams!") + throw new AuthError("STANDARD Admins are not allowed to delete Teams!"); } try { @@ -137,7 +137,7 @@ export const deleteTeam = async (req: Request, res: Response) => { export async function checkTeamExistence(teamPid: string) { const teamCount = await prisma.team.count({ - where: { pid: teamPid, } + where: { pid: teamPid }, }); if (teamCount == 0) { throw new NotFoundError("team", teamPid); @@ -145,13 +145,14 @@ export async function checkTeamExistence(teamPid: string) { } export async function getGroupsByTeamPid(teamPid: string) { - const team = ( - await prisma.team.findUnique({ where: { pid: teamPid }, select: { participants: { select: { group: true } } } }) - ); + const team = await prisma.team.findUnique({ + where: { pid: teamPid }, + select: { participants: { select: { group: true } } }, + }); let groups: string[] = []; - team?.participants.forEach(participant => { + team?.participants.forEach((participant) => { groups.push(participant.group.pid); }); diff --git a/src/Middleware/auth/auth.ts b/src/Middleware/auth/auth.ts index 5026edb..3ef66a9 100644 --- a/src/Middleware/auth/auth.ts +++ b/src/Middleware/auth/auth.ts @@ -18,82 +18,42 @@ export const getBearerToken = (authorization: string) => authorization.slice(7); const _requireAdminAuthentication = (config: { optional?: Boolean; controlled?: Boolean } = { optional: false, controlled: false }) => - async (req: Request, res: Response, next: NextFunction) => { - if (!JWT_SECRET) { - throw new Error("JWT_SECRET not set"); + async (req: Request, res: Response, next: NextFunction) => { + if (!JWT_SECRET) { + throw new Error("JWT_SECRET not set"); + } + + const { authorization } = req.headers; + + if (!authorization) { + if (config.optional) { + return false; } - const { authorization } = req.headers; + return res.status(403).send({ + type: "error", + payload: { + message: "The requeset did not include the Authorization header", + }, + }); + } - if (!authorization) { - if (config.optional) { - return false; - } + if (!verifyAuthorizationFormat(authorization)) { + return res.status(400).send({ + type: "error", + payload: { + message: "Malformed Authorization header", + format: "Bearer ", + }, + }); + } - return res.status(403).send({ - type: "error", - payload: { - message: "The requeset did not include the Authorization header", - }, - }); - } + let token_payload_: string | JwtPayload; - if (!verifyAuthorizationFormat(authorization)) { - return res.status(400).send({ - type: "error", - payload: { - message: "Malformed Authorization header", - format: "Bearer ", - }, - }); - } - - let token_payload_: string | JwtPayload; - - try { - token_payload_ = jwt.verify(getBearerToken(authorization), JWT_SECRET); - } catch (e) { - if (e instanceof JsonWebTokenError) { - return res.status(403).json({ - type: "error", - payload: { - message: "Token could not be verified; It might be expired", - }, - }); - } - - throw e; - } - - const token_payload = token_payload_ as AuthJWTPayload; - - if (!token_payload.permission_level || !token_payload.pid || !token_payload.revision) { - if (typeof (token_payload as unknown as TeamleaderJWTPayload).team === "string") { - if (config.controlled) { - return false; - } - throw new AuthError("Teamleader authentication is not supported for this operation!"); - } - - throw new AuthError("The token did not include the required information!"); - } - - const { pid, revision } = token_payload; - - let db_revision = await authClient.get(pid); - - if (db_revision === null) { - // Load the revision ID from the main DB and cache it in redis - const user = await prisma.admin.findUnique({ where: { pid }, select: { revision: true } }); - - if (user) { - db_revision = user.revision.toISOString(); - - await authClient.set(pid, db_revision); - } - } - - if (revision !== db_revision || !revision || !db_revision) { + try { + token_payload_ = jwt.verify(getBearerToken(authorization), JWT_SECRET); + } catch (e) { + if (e instanceof JsonWebTokenError) { return res.status(403).json({ type: "error", payload: { @@ -102,22 +62,62 @@ const _requireAdminAuthentication = }); } - req.auth = { - isAuthenticated: true, - pid: token_payload.pid, - name: token_payload.name, - permission_level: token_payload.permission_level, - groups: token_payload.groups, - revision: token_payload.revision, - }; + throw e; + } - if (!config.controlled) { - next(); + const token_payload = token_payload_ as AuthJWTPayload; + + if (!token_payload.permission_level || !token_payload.pid || !token_payload.revision) { + if (typeof (token_payload as unknown as TeamleaderJWTPayload).team === "string") { + if (config.controlled) { + return false; + } + throw new AuthError("Teamleader authentication is not supported for this operation!"); } - return true; + throw new AuthError("The token did not include the required information!"); + } + + const { pid, revision } = token_payload; + + let db_revision = await authClient.get(pid); + + if (db_revision === null) { + // Load the revision ID from the main DB and cache it in redis + const user = await prisma.admin.findUnique({ where: { pid }, select: { revision: true } }); + + if (user) { + db_revision = user.revision.toISOString(); + + await authClient.set(pid, db_revision); + } + } + + if (revision !== db_revision || !revision || !db_revision) { + return res.status(403).json({ + type: "error", + payload: { + message: "Token could not be verified; It might be expired", + }, + }); + } + + req.auth = { + isAuthenticated: true, + pid: token_payload.pid, + name: token_payload.name, + permission_level: token_payload.permission_level, + groups: token_payload.groups, + revision: token_payload.revision, }; + if (!config.controlled) { + next(); + } + + return true; + }; + export const requireAuthentication = _requireAdminAuthentication({ optional: false, controlled: false }); type AuthType = "admin" | "teamleader"; @@ -144,37 +144,37 @@ function getAuthTypes(type: AuthType | AuthTypeConfig): AuthType[] { export const requireConfiguredAuthentication = (config: AuthConfiguration = { optional: false, type: "admin" }) => - async (req: Request, res: Response, next: NextFunction) => { - const types = getAuthTypes(config.type); - const optional = config.optional; + async (req: Request, res: Response, next: NextFunction) => { + const types = getAuthTypes(config.type); + const optional = config.optional; - let adminFinished = false; - let teamleaderFinished = false; + let adminFinished = false; + let teamleaderFinished = false; - if (types.includes("admin")) { - adminFinished = Boolean(await _requireAdminAuthentication({ optional: true, controlled: true })(req, res, next)); + if (types.includes("admin")) { + adminFinished = Boolean(await _requireAdminAuthentication({ optional: true, controlled: true })(req, res, next)); - if (adminFinished) { - return next(); - } + if (adminFinished) { + return next(); } + } - if (types.includes("teamleader")) { - teamleaderFinished = Boolean( - _requireTeamleaderAuthentication({ optional: true, controlled: true })(req, res, next) - ); + if (types.includes("teamleader")) { + teamleaderFinished = Boolean( + _requireTeamleaderAuthentication({ optional: true, controlled: true })(req, res, next) + ); - if (teamleaderFinished) { - return next(); - } + if (teamleaderFinished) { + return next(); } + } - if (!config.optional) { - throw new AuthError("No sufficient authorization was provided for this operation"); - } + if (!config.optional) { + throw new AuthError("No sufficient authorization was provided for this operation"); + } - next(); - }; + next(); + }; export function requireResponsibleForGroups(auth: AuthJWTPayload | undefined, groupPids: string[] | string) { if (auth?.permission_level === "ELEVATED") { @@ -182,7 +182,7 @@ export function requireResponsibleForGroups(auth: AuthJWTPayload | undefined, gr } if (Array.isArray(groupPids)) { - groupPids.forEach(gr => { + groupPids.forEach((gr) => { if (auth?.groups.includes(gr)) { return; } diff --git a/src/Middleware/auth/teamleaderAuth.ts b/src/Middleware/auth/teamleaderAuth.ts index 1052ed8..0af4e3a 100644 --- a/src/Middleware/auth/teamleaderAuth.ts +++ b/src/Middleware/auth/teamleaderAuth.ts @@ -26,63 +26,63 @@ export function generateTeamleaderJWT(teamleader: Team) { export const _requireTeamleaderAuthentication = (config: { optional: Boolean; controlled: Boolean } = { optional: false, controlled: false }) => - (req: Request, res: Response, next: NextFunction) => { - if (!JWT_SECRET) { - throw new Error("JWT_SECRET not set"); + (req: Request, res: Response, next: NextFunction) => { + if (!JWT_SECRET) { + throw new Error("JWT_SECRET not set"); + } + + const { authorization } = req.headers; + + if (!authorization) { + if (config.optional) { + return false; } - const { authorization } = req.headers; + return res.status(403).send({ + type: "error", + payload: { + message: + "The request did not include the Authorization header (Only the team leader can perform this operation)", + }, + }); + } - if (!authorization) { - if (config.optional) { - return false; - } + if (!verifyAuthorizationFormat(authorization)) { + return res.status(400).send({ + type: "error", + payload: { + message: "Malformed Authorization header", + format: "Bearer ", + }, + }); + } - return res.status(403).send({ + try { + const token_payload = jwt.verify(getBearerToken(authorization), JWT_SECRET) as TeamleaderJWTPayload; + + req.teamleader = { + isAuthenticated: true, + team: token_payload.team, + }; + + if (!config.controlled) { + next(); + } + + return true; + } catch (e) { + if (e instanceof JsonWebTokenError) { + return res.status(403).json({ type: "error", payload: { - message: - "The request did not include the Authorization header (Only the team leader can perform this operation)", + message: "Token could not be verified; It might be expired", }, }); } - if (!verifyAuthorizationFormat(authorization)) { - return res.status(400).send({ - type: "error", - payload: { - message: "Malformed Authorization header", - format: "Bearer ", - }, - }); - } - - try { - const token_payload = jwt.verify(getBearerToken(authorization), JWT_SECRET) as TeamleaderJWTPayload; - - req.teamleader = { - isAuthenticated: true, - team: token_payload.team, - }; - - if (!config.controlled) { - next(); - } - - return true; - } catch (e) { - if (e instanceof JsonWebTokenError) { - return res.status(403).json({ - type: "error", - payload: { - message: "Token could not be verified; It might be expired", - }, - }); - } - - throw e; - } - }; + throw e; + } + }; export const requireTeamleaderAuthentication = _requireTeamleaderAuthentication({ optional: false, controlled: false }); diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index 7c2d34d..ef6e6e4 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -1,12 +1,6 @@ import Express from "express"; import { string } from "zod"; -import { - addEvent, - deleteEvent, - getAllEvents, - getEvent, - updateEvent, -} from "../Controllers/event.controller"; +import { addEvent, deleteEvent, getAllEvents, getEvent, updateEvent } from "../Controllers/event.controller"; import { requireAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index e4c633a..6785f7b 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -1,7 +1,14 @@ import express from "express"; import fileUpload from "express-fileupload"; import { requireAuthentication } from "../Middleware/auth/auth"; -import { deleteMedia, getAllMedia, getMediaMeta, linkMedia, unlinkMedia, uploadImage } from "../Controllers/media.controller"; +import { + deleteMedia, + getAllMedia, + getMediaMeta, + linkMedia, + unlinkMedia, + uploadImage, +} from "../Controllers/media.controller"; import eventRouter from "./event.routes"; import disciplineRouter from "./discipline.routes"; import roleSchemaRouter from "./role_schema.routes"; @@ -19,28 +26,28 @@ router.get("/:pid/meta", getMediaMeta); router.delete("/:pid", requireAuthentication, deleteMedia); -eventRouter.post<"/:pid/media", { pid: string }>( - "/:pid/media", requireAuthentication, linkMedia +eventRouter.post<"/:pid/media", { pid: string }>("/:pid/media", requireAuthentication, linkMedia); + +eventRouter.delete<"/:pid/media/:mediaPid", { pid: string; mediaPid: string }>( + "/:pid/media/:mediaPid", + requireAuthentication, + unlinkMedia ); -eventRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( - "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia +disciplineRouter.post<"/:pid/media", { pid: string }>("/:pid/media", requireAuthentication, linkMedia); + +disciplineRouter.delete<"/:pid/media/:mediaPid", { pid: string; mediaPid: string }>( + "/:pid/media/:mediaPid", + requireAuthentication, + unlinkMedia ); -disciplineRouter.post<"/:pid/media", { pid: string }>( - "/:pid/media", requireAuthentication, linkMedia -); +roleSchemaRouter.post<"/:pid/media", { pid: string }>("/:pid/media", requireAuthentication, linkMedia); -disciplineRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( - "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia -); - -roleSchemaRouter.post<"/:pid/media", { pid: string }>( - "/:pid/media", requireAuthentication, linkMedia -); - -roleSchemaRouter.delete<"/:pid/media/:mediaPid", { pid: string, mediaPid: string }>( - "/:pid/media/:mediaPid", requireAuthentication, unlinkMedia +roleSchemaRouter.delete<"/:pid/media/:mediaPid", { pid: string; mediaPid: string }>( + "/:pid/media/:mediaPid", + requireAuthentication, + unlinkMedia ); export default router; diff --git a/src/Routes/role.routes.ts b/src/Routes/role.routes.ts index 81ee739..f5df428 100644 --- a/src/Routes/role.routes.ts +++ b/src/Routes/role.routes.ts @@ -17,4 +17,4 @@ teamRouter.get<"/:pid/roles", { pid: string }>( getRolesForTeam ); -export default router; \ No newline at end of file +export default router;