From 87f5fa2e9189b8f750f02f459c49c627e8148fca Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Fri, 3 Jun 2022 22:19:09 +0200 Subject: [PATCH 01/10] Add various participant and role controllers + Fix issues --- src/Controllers/participant.controller.ts | 114 ++++++++++++++++++++-- src/Middleware/auth/teamleaderAuth.ts | 11 ++- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 08bf4db..84ecef0 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -1,12 +1,16 @@ import prisma from "../lib/prisma"; import { string, z } from "zod"; import { Request, Response } from "express"; -import { DataType, generateError, generateInvalidBodyError } from "./common"; +import { DataType, generateError, generateInvalidBodyError, createInsufficientPermissionsError } from "./common"; import { Prisma } from "@prisma/client"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; import NotFoundError from "../Middleware/error/NotFoundError"; import { requireLeaderOfTeam, requireResponsibleForParticipant } from "../Middleware/auth/teamleaderAuth"; import { requireResponsibleForGroups } from "../Middleware/auth/auth"; +import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; +import { isTeamleaderJWTPayload, TeamleaderJWTPayload } from "../Middleware/auth/teamleaderAuth"; +import { AuthJWTPayload } from "./admin_auth.controller"; +import AuthError from "../Middleware/error/AuthError"; require("express-async-errors"); @@ -16,17 +20,13 @@ const InitialParticipant = z.object({ groupPid: z.string().min(1).uuid(), }); -const returnedParticipant = { +const ParticipantBody = InitialParticipant.extend({ teamPid: z.string().uuid() }); + +const basicParticipant = { pid: true, firstName: true, lastName: true, relevance: true, - team: { - select: { - pid: true, - name: true, - }, - }, group: { select: { pid: true, @@ -35,11 +35,105 @@ const returnedParticipant = { }, } as const; -// at: POST api/participants/ +const returnedParticipant = { + ...basicParticipant, + team: { + select: { + pid: true, + name: true, + }, + }, +} as const; + +const _getAllParticipants = async ( + res: Response, + authentication: TeamleaderJWTPayload | AuthJWTPayload, + teamPid?: string +) => { + if (isTeamleaderJWTPayload(authentication)) { + teamPid = authentication.team; + } else { + if (authentication.permission_level !== "ELEVATED") { + throw new AuthError(); + } + } + + const participants = await prisma.participant.findMany({ + where: { team: { pid: teamPid } }, + select: basicParticipant, + }); + + return res.status(200).json({ + type: "success", + payload: { + participants, + }, + }); +}; + +export const getAllParticipants = async (req: Request<{}, {}, {}, { teamPid?: string }>, res: Response) => { + const auth = req.auth || req.teamleader; + + if (!auth) { + throw new AuthError("No authentication provided"); + } + + return _getAllParticipants(res, auth, req.query.teamPid); +}; + +export const getAllDisciplinesParams = async (req: Request<{ teamPid: string }>, res: Response) => { + const auth = req.auth || req.teamleader; + + if (!auth) { + throw new AuthError("Not authentication provided"); + } + + return _getAllParticipants(res, auth, req.params.teamPid); +}; + +export const getParticipantForRole = async (req: Request<{ rolePid: string }>, res: Response) => { + let authenticated = false; + + if (req.auth && req.auth.permission_level !== "ELEVATED") { + return res.status(403).json(createInsufficientPermissionsError()); + } else if (req.auth) { + authenticated = true; + } + + const participant = await prisma.participant.findFirst({ + where: { roles: { some: { pid: req.params.rolePid } } }, + select: returnedParticipant, + }); + + if (!authenticated) { + requireLeaderOfTeam(req.teamleader, participant?.team.pid); + authenticated = true; + } + + if (!authenticated) { + throw new AuthError(); // REVIEW: Is this check neccesary? + } + + if (!participant) { + return res.status(404).json({ + type: "error", + payload: { + message: `Could not find a participant for the role with the ID '${req.params.rolePid}'`, + }, + }); + } + + return res.status(200).json({ + type: "success", + payload: { participant }, + }); +}; + +// at: POST api/teams/:teamPid/participant/ export const createParticipant = async (req: Request<{ teamPid: string }>, res: Response) => { const { teamPid } = req.params; - const result = InitialParticipant.safeParse(req.body); + const result = ParticipantBody.safeParse(req.body); if (result.success === false) { return res.status(400).json( diff --git a/src/Middleware/auth/teamleaderAuth.ts b/src/Middleware/auth/teamleaderAuth.ts index 0af4e3a..9b5c745 100644 --- a/src/Middleware/auth/teamleaderAuth.ts +++ b/src/Middleware/auth/teamleaderAuth.ts @@ -10,6 +10,10 @@ export interface TeamleaderJWTPayload { team: string; } +export function isTeamleaderJWTPayload(payload: any): payload is TeamleaderJWTPayload { + return typeof payload.team === "string"; +} + const JWT_SECRET = process.env.JWT_SECRET; export function generateTeamleaderJWT(teamleader: Team) { @@ -86,8 +90,13 @@ export const _requireTeamleaderAuthentication = export const requireTeamleaderAuthentication = _requireTeamleaderAuthentication({ optional: false, controlled: false }); -export async function requireLeaderOfTeam(auth: TeamleaderJWTPayload | undefined, teamPid: string) { +export async function requireLeaderOfTeam(auth: TeamleaderJWTPayload | undefined, teamPid?: string) { + if (!teamPid) { + throw new AuthError("Could not match IDs"); + } + await checkTeamExistence(teamPid); + if (auth?.team !== teamPid) { throw new AuthError("The provided authorization is not valid for the requested team"); } From 718c040517aef813908cb391f935386d04f0a96d Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Sat, 4 Jun 2022 22:28:59 +0200 Subject: [PATCH 02/10] Fix routes, add getRole controller --- src/Controllers/participant.controller.ts | 2 +- src/Controllers/role.controller.ts | 31 ++++++++++++++++++----- src/Controllers/team.controller.ts | 9 ++++++- src/Routes/participant.routes.ts | 30 ++++++++++++++++++---- src/Routes/role.routes.ts | 11 ++++++-- 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 84ecef0..94021ff 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -81,7 +81,7 @@ export const getAllParticipants = async (req: Request<{}, {}, {}, { teamPid?: st return _getAllParticipants(res, auth, req.query.teamPid); }; -export const getAllDisciplinesParams = async (req: Request<{ teamPid: string }>, res: Response) => { +export const getAllParticipantsParams = async (req: Request<{ teamPid: string }>, res: Response) => { const auth = req.auth || req.teamleader; if (!auth) { diff --git a/src/Controllers/role.controller.ts b/src/Controllers/role.controller.ts index 8860f52..7b4f671 100644 --- a/src/Controllers/role.controller.ts +++ b/src/Controllers/role.controller.ts @@ -11,6 +11,13 @@ import { getGroupsByTeamPid } from "./team.controller"; require("express-async-errors"); +const basicRole = { + pid: true, + score: true, + schema: { select: { pid: true } }, + participant: { select: { pid: true, firstName: true, lastName: true } }, +}; + const detailedRole = { pid: true, score: true, @@ -67,12 +74,7 @@ export async function getRolesForTeam(req: Request<{ pid: string }>, res: Respon const roles = await prisma.role.findMany({ where: { team: { pid } }, - select: { - pid: true, - score: true, - schema: { select: { pid: true } }, - participant: { select: { pid: true, firstName: true, lastName: true } }, - }, + select: basicRole, }); return res.status(200).json({ @@ -83,6 +85,23 @@ export async function getRolesForTeam(req: Request<{ pid: string }>, res: Respon }); } +export async function getRole(req: Request<{ rolePid: string }>, res: Response) { + const rolePid = req.params.rolePid; + + const role = await prisma.role.findUnique({ where: { pid: rolePid }, select: basicRole }); + + if (!role) { + throw new NotFoundError("role", rolePid); + } + + return res.status(200).json({ + type: "success", + payload: { + role, + }, + }); +} + const AssignParticipantToRoleBody = z.object({ participantPid: z.string().uuid(), }); diff --git a/src/Controllers/team.controller.ts b/src/Controllers/team.controller.ts index 7b685a0..9d1f0f2 100644 --- a/src/Controllers/team.controller.ts +++ b/src/Controllers/team.controller.ts @@ -1,6 +1,6 @@ import { Request, Response } from "express"; import prisma from "../lib/prisma"; -import { DataType, generateInvalidBodyError } from "./common"; +import { createInsufficientPermissionsError, DataType, generateInvalidBodyError } from "./common"; import { requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth"; import { TeamBody } from "./user_auth.controller"; import { Prisma } from "@prisma/client"; @@ -88,6 +88,13 @@ export const updateTeam = async (req: Request, res: Response) => { const body = result.data; + try { + requireLeaderOfTeam(req.teamleader, pid); + } catch { + // TODO: DO NOT CATCH THESE ERRORS + return res.status(401).json(createInsufficientPermissionsError("STANDARD")); + } + try { const team = await prisma.team.update({ where: { diff --git a/src/Routes/participant.routes.ts b/src/Routes/participant.routes.ts index 2e76a2e..aa8f69d 100644 --- a/src/Routes/participant.routes.ts +++ b/src/Routes/participant.routes.ts @@ -1,13 +1,33 @@ import express from "express"; -import { createParticipant, deleteParticipant, updateParticipant } from "../Controllers/participant.controller"; -import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; import teamRouter from "./team.routes"; +import { + createParticipant, + deleteParticipant, + getAllParticipants, + getAllParticipantsParams, + updateParticipant, +} from "../Controllers/participant.controller"; +import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth"; + +require("express-async-errors"); const router = express.Router(); -teamRouter.post<"/:teamPid/participants", { teamPid: string }>( - "/:teamPid/participants", - requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), +router.get( + "/", + requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), + getAllParticipants +); + +teamRouter.get( + "/:pid/particpants", + requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), + getAllParticipantsParams +); + +teamRouter.post<"/:teamPid/participants/", { teamPid: string }>( + "/:teamPid/participants/", + requireConfiguredAuthentication({ optional: true, type: { admin: true, teamleader: true } }), createParticipant ); diff --git a/src/Routes/role.routes.ts b/src/Routes/role.routes.ts index f5df428..f070e32 100644 --- a/src/Routes/role.routes.ts +++ b/src/Routes/role.routes.ts @@ -1,10 +1,17 @@ import Express from "express"; -import { assignParticipantToRole, getRolesForTeam } from "../Controllers/role.controller"; -import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; +import { assignParticipantToRole, getRole, getRolesForTeam } from "../Controllers/role.controller"; +import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth"; +import { requireTeamleaderAuthentication } from "../Middleware/auth/teamleaderAuth"; import teamRouter from "./team.routes"; const router = Express.Router(); +router.get( + "/:rolePid", + requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), + getRole +); + router.put<"/:pid/participant", { pid: string }>( "/:pid/participant", requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), From 3a995c6b03a9fd74db2dbc450c6d0e058e9cc89e Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Sat, 4 Jun 2022 22:47:25 +0200 Subject: [PATCH 03/10] Add route to get participant for role --- src/Routes/participant.routes.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Routes/participant.routes.ts b/src/Routes/participant.routes.ts index aa8f69d..3fc9a8f 100644 --- a/src/Routes/participant.routes.ts +++ b/src/Routes/participant.routes.ts @@ -1,10 +1,12 @@ import express from "express"; import teamRouter from "./team.routes"; +import roleRouter from "./role.routes"; import { createParticipant, deleteParticipant, getAllParticipants, getAllParticipantsParams, + getParticipantForRole, updateParticipant, } from "../Controllers/participant.controller"; import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth"; @@ -25,6 +27,12 @@ teamRouter.get( getAllParticipantsParams ); +roleRouter.get( + "/:rolePid/participant", + requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), + getParticipantForRole +); + teamRouter.post<"/:teamPid/participants/", { teamPid: string }>( "/:teamPid/participants/", requireConfiguredAuthentication({ optional: true, type: { admin: true, teamleader: true } }), From 68cf5bf573c408337de88bedea4ad834fc516367 Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Thu, 9 Jun 2022 11:55:44 +0200 Subject: [PATCH 04/10] Address some comments and fix issues --- src/Controllers/participant.controller.ts | 4 +--- src/Routes/participant.routes.ts | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 94021ff..2b7e75e 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -20,8 +20,6 @@ const InitialParticipant = z.object({ groupPid: z.string().min(1).uuid(), }); -const ParticipantBody = InitialParticipant.extend({ teamPid: z.string().uuid() }); - const basicParticipant = { pid: true, firstName: true, @@ -133,7 +131,7 @@ export const getParticipantForRole = async (req: Request<{ rolePid: string }>, r export const createParticipant = async (req: Request<{ teamPid: string }>, res: Response) => { const { teamPid } = req.params; - const result = ParticipantBody.safeParse(req.body); + const result = InitialParticipant.safeParse(req.body); if (result.success === false) { return res.status(400).json( diff --git a/src/Routes/participant.routes.ts b/src/Routes/participant.routes.ts index 3fc9a8f..391e3e6 100644 --- a/src/Routes/participant.routes.ts +++ b/src/Routes/participant.routes.ts @@ -22,7 +22,7 @@ router.get( ); teamRouter.get( - "/:pid/particpants", + "/:teamPid/particpants", requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), getAllParticipantsParams ); @@ -35,7 +35,7 @@ roleRouter.get( teamRouter.post<"/:teamPid/participants/", { teamPid: string }>( "/:teamPid/participants/", - requireConfiguredAuthentication({ optional: true, type: { admin: true, teamleader: true } }), + requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), createParticipant ); From 474b3f81857ff27717cf97c63e16d0e075f16e3c Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Thu, 9 Jun 2022 13:50:26 +0200 Subject: [PATCH 05/10] Rewrite parts of the requestTokenEmailController --- src/Controllers/user_auth.controller.ts | 19 ++++++++++--------- src/Routes/user_auth.routes.ts | 3 ++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Controllers/user_auth.controller.ts b/src/Controllers/user_auth.controller.ts index c2f02ef..268e1cc 100644 --- a/src/Controllers/user_auth.controller.ts +++ b/src/Controllers/user_auth.controller.ts @@ -97,7 +97,7 @@ export const register = async (req: Request<{}, {}, CreateTeamBody>, res: Respon }; export const requestToken = async (req: Request, res: Response) => { - const data = z.object({ teamId: z.string().min(1) }).safeParse(req); + const data = z.object({ teamId: z.string().min(1) }).safeParse(req.body); if (data.success == false) { return res.status(400).json(generateInvalidBodyError({ teamId: DataType.STRING }, data.error)); @@ -130,7 +130,7 @@ export const requestToken = async (req: Request, res: Response) => { }; export const requestTokenEmail = async (req: Request, res: Response) => { - const data = z.object({ email: z.string().min(1) }).safeParse(req); + const data = z.object({ email: z.string().email() }).safeParse(req.body); if (data.success == false) { return res.status(400).json(generateInvalidBodyError({ email: DataType.STRING }, data.error)); @@ -149,23 +149,24 @@ export const requestTokenEmail = async (req: Request, res: Response) => { }, }); - if (!teams) { - return res.status(404).json(generateError("Team does not exist!")); + if (teams.length <= 0) { + // REVIEW: Potential for time-based attacks + return res + .status(200) + .json({ type: "sucess", payload: { message: "If a team with the provided email exist, the token was sent!" } }); } const team = teams[0]; //REVIEW: maybe a email should be only able to be responsible for one team - if (!team) { - return res.status(404).json(generateError("Team does not exist!")); - } - const usid = nanoid(); (await mailClient).set(usid, team.pid); verificationMail(team.leaderEmail, team.discipline.name, usid); - res.status(200).json({ type: "sucess", payload: { message: "Email sent!" } }); + res + .status(200) + .json({ type: "sucess", payload: { message: "If a team with the provided email exist, the token was sent!" } }); }; export const verifyEmail = async (req: Request, res: Response) => { diff --git a/src/Routes/user_auth.routes.ts b/src/Routes/user_auth.routes.ts index 568b764..a673928 100644 --- a/src/Routes/user_auth.routes.ts +++ b/src/Routes/user_auth.routes.ts @@ -1,10 +1,11 @@ import express from "express"; -import { register, requestToken, verifyEmail } from "../Controllers/user_auth.controller"; +import { register, requestToken, requestTokenEmail, verifyEmail } from "../Controllers/user_auth.controller"; const router = express.Router(); router.post("/", register); router.get("/verify/:code", verifyEmail); router.get("/token", requestToken); +router.post("/email-token", requestTokenEmail); export default router; From 0fea7edb25ebed7a800f334f66e1104d49492005 Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Thu, 9 Jun 2022 14:16:08 +0200 Subject: [PATCH 06/10] fixed review suggestions --- src/Controllers/participant.controller.ts | 54 +++++++---------------- src/Controllers/role.controller.ts | 10 ++++- src/Controllers/team.controller.ts | 7 --- src/Routes/participant.routes.ts | 5 +-- 4 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 2b7e75e..c0df55d 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -11,6 +11,7 @@ import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; import { isTeamleaderJWTPayload, TeamleaderJWTPayload } from "../Middleware/auth/teamleaderAuth"; import { AuthJWTPayload } from "./admin_auth.controller"; import AuthError from "../Middleware/error/AuthError"; +import { getGroupsByTeamPid } from "./team.controller"; require("express-async-errors"); @@ -45,14 +46,16 @@ const returnedParticipant = { const _getAllParticipants = async ( res: Response, - authentication: TeamleaderJWTPayload | AuthJWTPayload, + req: Request, teamPid?: string ) => { - if (isTeamleaderJWTPayload(authentication)) { - teamPid = authentication.team; - } else { - if (authentication.permission_level !== "ELEVATED") { - throw new AuthError(); + if (req.teamleader?.isAuthenticated) { + await requireLeaderOfTeam(req.teamleader, teamPid); + } else if (req.auth?.permission_level == "STANDARD") { + if (!teamPid) { + throw new AuthError("A STANDARD Admin is not allowed to fetch all Participants!"); + } else { + requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(teamPid)); } } @@ -70,48 +73,19 @@ const _getAllParticipants = async ( }; export const getAllParticipants = async (req: Request<{}, {}, {}, { teamPid?: string }>, res: Response) => { - const auth = req.auth || req.teamleader; - - if (!auth) { - throw new AuthError("No authentication provided"); - } - - return _getAllParticipants(res, auth, req.query.teamPid); + return _getAllParticipants(res, req, req.query.teamPid); }; export const getAllParticipantsParams = async (req: Request<{ teamPid: string }>, res: Response) => { - const auth = req.auth || req.teamleader; - - if (!auth) { - throw new AuthError("Not authentication provided"); - } - - return _getAllParticipants(res, auth, req.params.teamPid); + return _getAllParticipants(res, req, req.params.teamPid); }; export const getParticipantForRole = async (req: Request<{ rolePid: string }>, res: Response) => { - let authenticated = false; - - if (req.auth && req.auth.permission_level !== "ELEVATED") { - return res.status(403).json(createInsufficientPermissionsError()); - } else if (req.auth) { - authenticated = true; - } - const participant = await prisma.participant.findFirst({ where: { roles: { some: { pid: req.params.rolePid } } }, select: returnedParticipant, }); - if (!authenticated) { - requireLeaderOfTeam(req.teamleader, participant?.team.pid); - authenticated = true; - } - - if (!authenticated) { - throw new AuthError(); // REVIEW: Is this check neccesary? - } - if (!participant) { return res.status(404).json({ type: "error", @@ -121,6 +95,12 @@ export const getParticipantForRole = async (req: Request<{ rolePid: string }>, r }); } + if (req.teamleader?.isAuthenticated) { + await requireLeaderOfTeam(req.teamleader, participant?.team.pid); + } else if (req.auth?.permission_level == "STANDARD") { + requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(participant?.team.pid)); + } + return res.status(200).json({ type: "success", payload: { participant }, diff --git a/src/Controllers/role.controller.ts b/src/Controllers/role.controller.ts index 7b4f671..7fe04fb 100644 --- a/src/Controllers/role.controller.ts +++ b/src/Controllers/role.controller.ts @@ -68,7 +68,7 @@ export async function getRolesForTeam(req: Request<{ pid: string }>, res: Respon if (req.teamleader?.isAuthenticated) { await requireLeaderOfTeam(req.teamleader, pid); - } else { + } else if (req.auth?.permission_level == "STANDARD") { requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(pid)); } @@ -88,12 +88,18 @@ export async function getRolesForTeam(req: Request<{ pid: string }>, res: Respon export async function getRole(req: Request<{ rolePid: string }>, res: Response) { const rolePid = req.params.rolePid; - const role = await prisma.role.findUnique({ where: { pid: rolePid }, select: basicRole }); + const role = await prisma.role.findUnique({ where: { pid: rolePid }, select: detailedRole }); if (!role) { throw new NotFoundError("role", rolePid); } + if (req.teamleader?.isAuthenticated) { + await requireLeaderOfTeam(req.teamleader, role.team.pid); + } else if (req.auth?.permission_level == "STANDARD" && role.participant?.pid !== undefined) { + requireResponsibleForGroups(req.auth, await getGroupByParticipantPid(role.participant?.pid)); + } + return res.status(200).json({ type: "success", payload: { diff --git a/src/Controllers/team.controller.ts b/src/Controllers/team.controller.ts index 9d1f0f2..be0a66e 100644 --- a/src/Controllers/team.controller.ts +++ b/src/Controllers/team.controller.ts @@ -88,13 +88,6 @@ export const updateTeam = async (req: Request, res: Response) => { const body = result.data; - try { - requireLeaderOfTeam(req.teamleader, pid); - } catch { - // TODO: DO NOT CATCH THESE ERRORS - return res.status(401).json(createInsufficientPermissionsError("STANDARD")); - } - try { const team = await prisma.team.update({ where: { diff --git a/src/Routes/participant.routes.ts b/src/Routes/participant.routes.ts index 391e3e6..4ecab8e 100644 --- a/src/Routes/participant.routes.ts +++ b/src/Routes/participant.routes.ts @@ -16,10 +16,7 @@ require("express-async-errors"); const router = express.Router(); router.get( - "/", - requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }), - getAllParticipants -); + "/", requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), getAllParticipants); teamRouter.get( "/:teamPid/particpants", From 418a26b3dd3c7ce2ff30075c7c8eab677957093a Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Thu, 9 Jun 2022 16:20:34 +0200 Subject: [PATCH 07/10] Adding RoleSchema Update/Delete --- src/Controllers/role_schema.controller.ts | 24 +++++++++++++++++++++-- src/Routes/role_schema.routes.ts | 8 +++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index 99c5369..f9a9445 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -136,7 +136,7 @@ export const createRoleSchema = async ( } }; -export const UpdateRoleSchema = async (req: Request<{ pid: string }>, res: Response) => { +export const updateRoleSchema = async (req: Request<{ pid: string }>, res: Response) => { if (req.auth?.permission_level !== "ELEVATED") { return res.status(403).json(createInsufficientPermissionsError()); } @@ -177,7 +177,27 @@ export const UpdateRoleSchema = async (req: Request<{ pid: string }>, res: Respo }); } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") { - throw new NotFoundError("discipline", pid); + throw new NotFoundError("role-schema", pid); + } + + throw e; + } +}; + +export const deleteRoleSchema = async (req: Request<{ pid: string }>, res: Response) => { + if (req.auth?.permission_level !== "ELEVATED") { + return res.status(403).json(createInsufficientPermissionsError()); + } + + const { pid } = req.params; + + try { + await prisma.roleSchema.delete({ where: { pid } }); + + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError("role-schema", pid); } throw e; diff --git a/src/Routes/role_schema.routes.ts b/src/Routes/role_schema.routes.ts index 688dafc..79d4c83 100644 --- a/src/Routes/role_schema.routes.ts +++ b/src/Routes/role_schema.routes.ts @@ -2,11 +2,13 @@ import express from "express"; import disciplineRouter from "./discipline.routes"; import { createRoleSchema, + deleteRoleSchema, getAllRoleSchemas, getAllRoleSchemasWithParam, getRoleSchema, + updateRoleSchema, } from "../Controllers/role_schema.controller"; -import { requireAuthentication } from "../Middleware/auth/auth"; +import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth"; const router = express.Router(); @@ -14,6 +16,10 @@ router.get("/", getAllRoleSchemas); router.get("/:pid", getRoleSchema); +router.patch("/:pid", requireConfiguredAuthentication({ optional: false, type: "admin" }), updateRoleSchema); + +router.delete("/:pid", requireConfiguredAuthentication({ optional: false, type: "admin" }), deleteRoleSchema) + disciplineRouter.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam); disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema); From 44a98a8312b44a86ba8a7d0b60bd1cb51657b584 Mon Sep 17 00:00:00 2001 From: Flexla54 Date: Thu, 9 Jun 2022 14:22:46 +0000 Subject: [PATCH 08/10] [create-pull-request] push formatted files --- src/Controllers/participant.controller.ts | 6 +----- src/Routes/participant.routes.ts | 5 ++++- src/Routes/role_schema.routes.ts | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index c0df55d..b1960c7 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -44,11 +44,7 @@ const returnedParticipant = { }, } as const; -const _getAllParticipants = async ( - res: Response, - req: Request, - teamPid?: string -) => { +const _getAllParticipants = async (res: Response, req: Request, teamPid?: string) => { if (req.teamleader?.isAuthenticated) { await requireLeaderOfTeam(req.teamleader, teamPid); } else if (req.auth?.permission_level == "STANDARD") { diff --git a/src/Routes/participant.routes.ts b/src/Routes/participant.routes.ts index 4ecab8e..7e113db 100644 --- a/src/Routes/participant.routes.ts +++ b/src/Routes/participant.routes.ts @@ -16,7 +16,10 @@ require("express-async-errors"); const router = express.Router(); router.get( - "/", requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), getAllParticipants); + "/", + requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), + getAllParticipants +); teamRouter.get( "/:teamPid/particpants", diff --git a/src/Routes/role_schema.routes.ts b/src/Routes/role_schema.routes.ts index 79d4c83..e2f4b5c 100644 --- a/src/Routes/role_schema.routes.ts +++ b/src/Routes/role_schema.routes.ts @@ -18,7 +18,7 @@ router.get("/:pid", getRoleSchema); router.patch("/:pid", requireConfiguredAuthentication({ optional: false, type: "admin" }), updateRoleSchema); -router.delete("/:pid", requireConfiguredAuthentication({ optional: false, type: "admin" }), deleteRoleSchema) +router.delete("/:pid", requireConfiguredAuthentication({ optional: false, type: "admin" }), deleteRoleSchema); disciplineRouter.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam); From f92b004fbe5a478d05744b7a0d89d8dc9f88a695 Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Fri, 10 Jun 2022 00:34:58 +0200 Subject: [PATCH 09/10] patches for update --- docker-compose.yml | 6 ++++++ prisma/schema.prisma | 2 +- src/Routes/user_auth.routes.ts | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b706db3..54a831b 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,3 +35,9 @@ services: - DATABASE_URL=postgresql://server:${DATABASE_PASSWORD}@postgres:5432/management?schema=public - DATABASE_USER=server - DATABASE_PASSWORD=${DATABASE_PASSWORD} + - JWT_SECRET=${JWT_SECRET} + - DOMAIN=${DOMAIN} + - MAILUSER=${MAILUSER} + - MAILPASSWORD=${MAILPASSWORD} + - FRONTEND_MAIL_ENDPOINT=https://josport.at/authteamleader/ + - ALLOW_ORIGIN=https://josport.at diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 79ea5f2..cef0fb2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -37,7 +37,7 @@ model Discipline { id Int @id @default(autoincrement()) pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid name String - briefDescription String + briefDescription String @default("description") fullDescription String? minTeamSize Int maxTeamSize Int diff --git a/src/Routes/user_auth.routes.ts b/src/Routes/user_auth.routes.ts index a673928..12028f0 100644 --- a/src/Routes/user_auth.routes.ts +++ b/src/Routes/user_auth.routes.ts @@ -5,7 +5,7 @@ const router = express.Router(); router.post("/", register); router.get("/verify/:code", verifyEmail); -router.get("/token", requestToken); +router.post("/token", requestToken); router.post("/email-token", requestTokenEmail); export default router; From c711f3b899429f93823b70e0023e91393a7c5b6b Mon Sep 17 00:00:00 2001 From: Flexla54 Date: Fri, 10 Jun 2022 05:31:53 +0000 Subject: [PATCH 10/10] [create-pull-request] push formatted files --- src/Tests/events.test.ts | 2 +- src/Tests/mail.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/events.test.ts b/src/Tests/events.test.ts index ef4dae5..08c8985 100644 --- a/src/Tests/events.test.ts +++ b/src/Tests/events.test.ts @@ -81,4 +81,4 @@ describe("events", () => { }); }); }); -*/ \ No newline at end of file +*/ diff --git a/src/Tests/mail.test.ts b/src/Tests/mail.test.ts index 3102622..fccddc0 100644 --- a/src/Tests/mail.test.ts +++ b/src/Tests/mail.test.ts @@ -15,4 +15,4 @@ describe("mail", () => { info.accepted.length.should.eq(1); }); }); -*/ \ No newline at end of file +*/