mirror of
https://github.com/detleph/server.git
synced 2026-09-04 08:36:06 +02:00
@@ -35,3 +35,9 @@ services:
|
|||||||
- DATABASE_URL=postgresql://server:${DATABASE_PASSWORD}@postgres:5432/management?schema=public
|
- DATABASE_URL=postgresql://server:${DATABASE_PASSWORD}@postgres:5432/management?schema=public
|
||||||
- DATABASE_USER=server
|
- DATABASE_USER=server
|
||||||
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
|
- 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
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ model Discipline {
|
|||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||||
name String
|
name String
|
||||||
briefDescription String
|
briefDescription String @default("description")
|
||||||
fullDescription String?
|
fullDescription String?
|
||||||
minTeamSize Int
|
minTeamSize Int
|
||||||
maxTeamSize Int
|
maxTeamSize Int
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import prisma from "../lib/prisma";
|
import prisma from "../lib/prisma";
|
||||||
import { string, z } from "zod";
|
import { string, z } from "zod";
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import { DataType, generateError, generateInvalidBodyError } from "./common";
|
import { DataType, generateError, generateInvalidBodyError, createInsufficientPermissionsError } from "./common";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
|
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
|
||||||
import NotFoundError from "../Middleware/error/NotFoundError";
|
import NotFoundError from "../Middleware/error/NotFoundError";
|
||||||
import { requireLeaderOfTeam, requireResponsibleForParticipant } from "../Middleware/auth/teamleaderAuth";
|
import { requireLeaderOfTeam, requireResponsibleForParticipant } from "../Middleware/auth/teamleaderAuth";
|
||||||
import { requireResponsibleForGroups } from "../Middleware/auth/auth";
|
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";
|
||||||
|
import { getGroupsByTeamPid } from "./team.controller";
|
||||||
|
|
||||||
require("express-async-errors");
|
require("express-async-errors");
|
||||||
|
|
||||||
@@ -16,17 +21,11 @@ const InitialParticipant = z.object({
|
|||||||
groupPid: z.string().min(1).uuid(),
|
groupPid: z.string().min(1).uuid(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const returnedParticipant = {
|
const basicParticipant = {
|
||||||
pid: true,
|
pid: true,
|
||||||
firstName: true,
|
firstName: true,
|
||||||
lastName: true,
|
lastName: true,
|
||||||
relevance: true,
|
relevance: true,
|
||||||
team: {
|
|
||||||
select: {
|
|
||||||
pid: true,
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
group: {
|
group: {
|
||||||
select: {
|
select: {
|
||||||
pid: true,
|
pid: true,
|
||||||
@@ -35,7 +34,76 @@ const returnedParticipant = {
|
|||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// at: POST api/participants/
|
const returnedParticipant = {
|
||||||
|
...basicParticipant,
|
||||||
|
team: {
|
||||||
|
select: {
|
||||||
|
pid: true,
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
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") {
|
||||||
|
if (!teamPid) {
|
||||||
|
throw new AuthError("A STANDARD Admin is not allowed to fetch all Participants!");
|
||||||
|
} else {
|
||||||
|
requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(teamPid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) => {
|
||||||
|
return _getAllParticipants(res, req, req.query.teamPid);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllParticipantsParams = async (req: Request<{ teamPid: string }>, res: Response) => {
|
||||||
|
return _getAllParticipants(res, req, req.params.teamPid);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getParticipantForRole = async (req: Request<{ rolePid: string }>, res: Response) => {
|
||||||
|
const participant = await prisma.participant.findFirst({
|
||||||
|
where: { roles: { some: { pid: req.params.rolePid } } },
|
||||||
|
select: returnedParticipant,
|
||||||
|
});
|
||||||
|
|
||||||
|
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}'`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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 },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// at: POST api/teams/:teamPid/participant/
|
||||||
export const createParticipant = async (req: Request<{ teamPid: string }>, res: Response) => {
|
export const createParticipant = async (req: Request<{ teamPid: string }>, res: Response) => {
|
||||||
const { teamPid } = req.params;
|
const { teamPid } = req.params;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ import { getGroupsByTeamPid } from "./team.controller";
|
|||||||
|
|
||||||
require("express-async-errors");
|
require("express-async-errors");
|
||||||
|
|
||||||
|
const basicRole = {
|
||||||
|
pid: true,
|
||||||
|
score: true,
|
||||||
|
schema: { select: { pid: true } },
|
||||||
|
participant: { select: { pid: true, firstName: true, lastName: true } },
|
||||||
|
};
|
||||||
|
|
||||||
const detailedRole = {
|
const detailedRole = {
|
||||||
pid: true,
|
pid: true,
|
||||||
score: true,
|
score: true,
|
||||||
@@ -61,18 +68,13 @@ export async function getRolesForTeam(req: Request<{ pid: string }>, res: Respon
|
|||||||
|
|
||||||
if (req.teamleader?.isAuthenticated) {
|
if (req.teamleader?.isAuthenticated) {
|
||||||
await requireLeaderOfTeam(req.teamleader, pid);
|
await requireLeaderOfTeam(req.teamleader, pid);
|
||||||
} else {
|
} else if (req.auth?.permission_level == "STANDARD") {
|
||||||
requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(pid));
|
requireResponsibleForGroups(req.auth, await getGroupsByTeamPid(pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
const roles = await prisma.role.findMany({
|
const roles = await prisma.role.findMany({
|
||||||
where: { team: { pid } },
|
where: { team: { pid } },
|
||||||
select: {
|
select: basicRole,
|
||||||
pid: true,
|
|
||||||
score: true,
|
|
||||||
schema: { select: { pid: true } },
|
|
||||||
participant: { select: { pid: true, firstName: true, lastName: true } },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
@@ -83,6 +85,29 @@ 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: 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: {
|
||||||
|
role,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const AssignParticipantToRoleBody = z.object({
|
const AssignParticipantToRoleBody = z.object({
|
||||||
participantPid: z.string().uuid(),
|
participantPid: z.string().uuid(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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") {
|
if (req.auth?.permission_level !== "ELEVATED") {
|
||||||
return res.status(403).json(createInsufficientPermissionsError());
|
return res.status(403).json(createInsufficientPermissionsError());
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,27 @@ export const UpdateRoleSchema = async (req: Request<{ pid: string }>, res: Respo
|
|||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
|
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;
|
throw e;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import prisma from "../lib/prisma";
|
import prisma from "../lib/prisma";
|
||||||
import { DataType, generateInvalidBodyError } from "./common";
|
import { createInsufficientPermissionsError, DataType, generateInvalidBodyError } from "./common";
|
||||||
import { requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth";
|
import { requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth";
|
||||||
import { TeamBody } from "./user_auth.controller";
|
import { TeamBody } from "./user_auth.controller";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export const register = async (req: Request<{}, {}, CreateTeamBody>, res: Respon
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const requestToken = async (req: Request, res: Response) => {
|
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) {
|
if (data.success == false) {
|
||||||
return res.status(400).json(generateInvalidBodyError({ teamId: DataType.STRING }, data.error));
|
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) => {
|
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) {
|
if (data.success == false) {
|
||||||
return res.status(400).json(generateInvalidBodyError({ email: DataType.STRING }, data.error));
|
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) {
|
if (teams.length <= 0) {
|
||||||
return res.status(404).json(generateError("Team does not exist!"));
|
// 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
|
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();
|
const usid = nanoid();
|
||||||
|
|
||||||
(await mailClient).set(usid, team.pid);
|
(await mailClient).set(usid, team.pid);
|
||||||
|
|
||||||
verificationMail(team.leaderEmail, team.discipline.name, usid);
|
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) => {
|
export const verifyEmail = async (req: Request, res: Response) => {
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ export interface TeamleaderJWTPayload {
|
|||||||
team: string;
|
team: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isTeamleaderJWTPayload(payload: any): payload is TeamleaderJWTPayload {
|
||||||
|
return typeof payload.team === "string";
|
||||||
|
}
|
||||||
|
|
||||||
const JWT_SECRET = process.env.JWT_SECRET;
|
const JWT_SECRET = process.env.JWT_SECRET;
|
||||||
|
|
||||||
export function generateTeamleaderJWT(teamleader: Team) {
|
export function generateTeamleaderJWT(teamleader: Team) {
|
||||||
@@ -86,8 +90,13 @@ export const _requireTeamleaderAuthentication =
|
|||||||
|
|
||||||
export const requireTeamleaderAuthentication = _requireTeamleaderAuthentication({ optional: false, controlled: false });
|
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);
|
await checkTeamExistence(teamPid);
|
||||||
|
|
||||||
if (auth?.team !== teamPid) {
|
if (auth?.team !== teamPid) {
|
||||||
throw new AuthError("The provided authorization is not valid for the requested team");
|
throw new AuthError("The provided authorization is not valid for the requested team");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,40 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { createParticipant, deleteParticipant, updateParticipant } from "../Controllers/participant.controller";
|
|
||||||
import { requireConfiguredAuthentication } from "../Middleware/auth/auth";
|
|
||||||
import teamRouter from "./team.routes";
|
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";
|
||||||
|
|
||||||
|
require("express-async-errors");
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
teamRouter.post<"/:teamPid/participants", { teamPid: string }>(
|
router.get(
|
||||||
"/:teamPid/participants",
|
"/",
|
||||||
|
requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }),
|
||||||
|
getAllParticipants
|
||||||
|
);
|
||||||
|
|
||||||
|
teamRouter.get(
|
||||||
|
"/:teamPid/particpants",
|
||||||
|
requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }),
|
||||||
|
getAllParticipantsParams
|
||||||
|
);
|
||||||
|
|
||||||
|
roleRouter.get(
|
||||||
|
"/:rolePid/participant",
|
||||||
|
requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }),
|
||||||
|
getParticipantForRole
|
||||||
|
);
|
||||||
|
|
||||||
|
teamRouter.post<"/:teamPid/participants/", { teamPid: string }>(
|
||||||
|
"/:teamPid/participants/",
|
||||||
requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }),
|
requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }),
|
||||||
createParticipant
|
createParticipant
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import Express from "express";
|
import Express from "express";
|
||||||
import { assignParticipantToRole, getRolesForTeam } from "../Controllers/role.controller";
|
import { assignParticipantToRole, getRole, getRolesForTeam } from "../Controllers/role.controller";
|
||||||
import { requireConfiguredAuthentication } from "../Middleware/auth/auth";
|
import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth";
|
||||||
|
import { requireTeamleaderAuthentication } from "../Middleware/auth/teamleaderAuth";
|
||||||
import teamRouter from "./team.routes";
|
import teamRouter from "./team.routes";
|
||||||
|
|
||||||
const router = Express.Router();
|
const router = Express.Router();
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
"/:rolePid",
|
||||||
|
requireConfiguredAuthentication({ type: { admin: true, teamleader: true }, optional: false }),
|
||||||
|
getRole
|
||||||
|
);
|
||||||
|
|
||||||
router.put<"/:pid/participant", { pid: string }>(
|
router.put<"/:pid/participant", { pid: string }>(
|
||||||
"/:pid/participant",
|
"/:pid/participant",
|
||||||
requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }),
|
requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }),
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import express from "express";
|
|||||||
import disciplineRouter from "./discipline.routes";
|
import disciplineRouter from "./discipline.routes";
|
||||||
import {
|
import {
|
||||||
createRoleSchema,
|
createRoleSchema,
|
||||||
|
deleteRoleSchema,
|
||||||
getAllRoleSchemas,
|
getAllRoleSchemas,
|
||||||
getAllRoleSchemasWithParam,
|
getAllRoleSchemasWithParam,
|
||||||
getRoleSchema,
|
getRoleSchema,
|
||||||
|
updateRoleSchema,
|
||||||
} from "../Controllers/role_schema.controller";
|
} from "../Controllers/role_schema.controller";
|
||||||
import { requireAuthentication } from "../Middleware/auth/auth";
|
import { requireAuthentication, requireConfiguredAuthentication } from "../Middleware/auth/auth";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@@ -14,6 +16,10 @@ router.get("/", getAllRoleSchemas);
|
|||||||
|
|
||||||
router.get("/:pid", getRoleSchema);
|
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.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam);
|
||||||
|
|
||||||
disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema);
|
disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import express from "express";
|
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();
|
const router = express.Router();
|
||||||
|
|
||||||
router.post("/", register);
|
router.post("/", register);
|
||||||
router.get("/verify/:code", verifyEmail);
|
router.get("/verify/:code", verifyEmail);
|
||||||
router.get("/token", requestToken);
|
router.post("/token", requestToken);
|
||||||
|
router.post("/email-token", requestTokenEmail);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -81,4 +81,4 @@ describe("events", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ describe("mail", () => {
|
|||||||
info.accepted.length.should.eq(1);
|
info.accepted.length.should.eq(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user