mirror of
https://github.com/detleph/server.git
synced 2026-09-04 08:36:06 +02:00
Merge branch 'dev' into feature-email-verification
This commit is contained in:
@@ -2,7 +2,7 @@ import prisma from "../lib/prisma";
|
||||
import { Request, Response } from "express";
|
||||
import { AdminLevel } from "@prisma/client";
|
||||
import argon2 from "argon2";
|
||||
import { DataType, generateInvalidBodyError } from "./common";
|
||||
import { AUTH_ERROR, createInsufficientPermissionsError, DataType, generateInvalidBodyError } from "./common";
|
||||
import { authClient } from "../lib/redis";
|
||||
|
||||
export const regenerateRevision = async (pid: string) => {
|
||||
@@ -16,28 +16,6 @@ export const regenerateRevision = async (pid: string) => {
|
||||
await authClient.set(pid, revision.toISOString());
|
||||
};
|
||||
|
||||
const AUTH_ERROR = {
|
||||
type: "failure",
|
||||
payload: {
|
||||
message: "The server was not able to validate your credentials; Please try again later",
|
||||
},
|
||||
};
|
||||
|
||||
const createInsufficientPermissionsError = (required: AdminLevel = "ELEVATED") => ({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "You do not have sufficient permissions to use this feature",
|
||||
required_level: required,
|
||||
},
|
||||
_links: [
|
||||
{
|
||||
rel: "authentication",
|
||||
href: "/api/authentication",
|
||||
type: "POST",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// requires: auth(elevated)
|
||||
export const getAllAdmins = async (req: Request, res: Response) => {
|
||||
if (!req.auth?.isAuthenticated) {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import { AdminLevel, Prisma } from "@prisma/client";
|
||||
import { PrismaClientKnownRequestError, PrismaClientUnknownRequestError } from "@prisma/client/runtime";
|
||||
import { Request, Response } from "express";
|
||||
import prisma from "../lib/prisma";
|
||||
|
||||
export enum DataType {
|
||||
STRING = "string",
|
||||
NUMBER = "number",
|
||||
@@ -20,3 +25,126 @@ export function generateInvalidBodyError(body: Body) {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const AUTH_ERROR = {
|
||||
type: "failure",
|
||||
payload: {
|
||||
message: "The server was not able to validate your credentials; Please try again later",
|
||||
},
|
||||
};
|
||||
|
||||
export const createInsufficientPermissionsError = (required: AdminLevel = "ELEVATED") => ({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "You do not have sufficient permissions to use this feature",
|
||||
required_level: required,
|
||||
},
|
||||
_links: [
|
||||
{
|
||||
rel: "authentication",
|
||||
href: "/api/authentication",
|
||||
type: "POST",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const generateError = (message: string) => {
|
||||
return {
|
||||
type: "error",
|
||||
payload: {
|
||||
message,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const genericError = {
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "There was an error processing your request, please try again later",
|
||||
},
|
||||
};
|
||||
|
||||
export function validateName(name: string) {
|
||||
return name.length > 0;
|
||||
}
|
||||
|
||||
type Organisation = Partial<Prisma.OrganisationCreateArgs["data"]>;
|
||||
type Group = Partial<Prisma.GroupCreateArgs["data"]>;
|
||||
|
||||
export async function handleCreateByName(
|
||||
create: { type: "organisation"; data: Organisation },
|
||||
link: { type: "event"; id: string },
|
||||
req: Request<any>,
|
||||
res: Response
|
||||
): Promise<unknown>;
|
||||
export async function handleCreateByName(
|
||||
create: { type: "group"; data: Group },
|
||||
link: { type: "organisation"; id: string },
|
||||
req: Request<any>,
|
||||
res: Response
|
||||
): Promise<unknown>;
|
||||
export async function handleCreateByName(
|
||||
create: { type: "organisation" | "group"; data: Organisation | Group },
|
||||
link: { type: "event" | "organisation"; id: string },
|
||||
req: Request<any>,
|
||||
res: Response
|
||||
) {
|
||||
if (!req.auth?.isAuthenticated) {
|
||||
return res.status(500).json(AUTH_ERROR);
|
||||
}
|
||||
|
||||
if (req.auth.permission_level !== "ELEVATED") {
|
||||
return res.status(403).json(createInsufficientPermissionsError());
|
||||
}
|
||||
|
||||
const { name } = create.data;
|
||||
|
||||
if (typeof name !== "string") {
|
||||
return res
|
||||
.status(400)
|
||||
.json(generateInvalidBodyError({ name: DataType.STRING, [link.type + "Pid"]: DataType.STRING }));
|
||||
}
|
||||
|
||||
if (!validateName(name)) {
|
||||
return res.status(400).json({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "The name has to be at least 1 character long",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Check if link object exsits
|
||||
|
||||
try {
|
||||
// @ts-ignore
|
||||
const linked = await prisma[link.type].findUnique({ where: { pid: link.id }, select: { id: true } });
|
||||
|
||||
if (!linked) {
|
||||
return res.status(404).json({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: `Could not link to ${link.type} with ID '${link.id}'`,
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// REVIEW: Check for valid UUID
|
||||
if (e instanceof PrismaClientUnknownRequestError) {
|
||||
return res.status(400).json({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "Unknown error occured. This could be due to malformed IDs",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const object = await prisma[create.type].create({
|
||||
data: { ...create.data, [link.type]: { connect: { pid: link.id } } },
|
||||
select: { pid: true, name: true },
|
||||
});
|
||||
|
||||
res.status(201).json({ type: "success", payload: { [create.type]: object } });
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Prisma } from "@prisma/client"
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
|
||||
import { Request, Response } from "express";
|
||||
import prisma from "../lib/prisma";
|
||||
import { DataType, generateInvalidBodyError } from "./common";
|
||||
import { createInsufficientPermissionsError, DataType, generateError, generateInvalidBodyError } from "./common";
|
||||
|
||||
export const getAllEvents = async (req: Request, res: Response) => {
|
||||
const events = await prisma.event.findMany({
|
||||
@@ -13,8 +14,13 @@ export const getAllEvents = async (req: Request, res: Response) => {
|
||||
id: false,
|
||||
},
|
||||
});
|
||||
if (events.length > 0) res.status(200).json(events);
|
||||
else res.status(200).json([]);
|
||||
if (events.length > 0)
|
||||
res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
events,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const getEvent = async (req: Request, res: Response) => {
|
||||
@@ -42,7 +48,12 @@ export const getEvent = async (req: Request, res: Response) => {
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json(event);
|
||||
res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
event,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
res.status(500).json({
|
||||
@@ -68,20 +79,23 @@ export const getEvent = async (req: Request, res: Response) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// requires: auth(ELEVATED)
|
||||
export const addEvent = async (req: Request, res: Response) => {
|
||||
if (req.auth?.permission_level !== "ELEVATED") {
|
||||
res.status(403).json(createInsufficientPermissionsError());
|
||||
}
|
||||
if (
|
||||
typeof req.body.name !== "string" ||
|
||||
typeof req.body.date !== "string" ||
|
||||
typeof req.body.description !== "string"
|
||||
) {
|
||||
res.status(400).json(
|
||||
generateInvalidBodyError({
|
||||
name: DataType.STRING,
|
||||
date: DataType.DATETIME,
|
||||
description: DataType.STRING,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: Check if date is valid
|
||||
@@ -102,9 +116,34 @@ export const addEvent = async (req: Request, res: Response) => {
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
type: "succes",
|
||||
type: "success",
|
||||
payload: {
|
||||
event,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
interface DeleteEventQueryParams {
|
||||
pid: string;
|
||||
}
|
||||
|
||||
// requires: auth(ELEVATED)
|
||||
export const deleteEvent = (req: Request<DeleteEventQueryParams>, res: Response) => {
|
||||
if (req.auth?.permission_level !== "ELEVATED") {
|
||||
res.status(403).json(createInsufficientPermissionsError());
|
||||
}
|
||||
|
||||
const { pid } = req.params;
|
||||
|
||||
try {
|
||||
prisma.event.delete({ where: { pid } });
|
||||
|
||||
return res.status(204).end();
|
||||
} catch (e) {
|
||||
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
|
||||
return res.status(404).json(generateError(`The organisation with the ID ${pid} could not be found`));
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Admin } from "@prisma/client";
|
||||
import { PrismaClientUnknownRequestError } from "@prisma/client/runtime";
|
||||
import { Request, Response } from "express";
|
||||
import prisma from "../lib/prisma";
|
||||
import { generateError, genericError, handleCreateByName } from "./common";
|
||||
|
||||
const basicGroup = {
|
||||
pid: true,
|
||||
name: true,
|
||||
organisation: { select: { pid: true, name: true } },
|
||||
} as const;
|
||||
|
||||
export const _getAllGroups = async (res: Response, organisationId: string | undefined) => {
|
||||
const groups = await prisma.group.findMany({
|
||||
where: { organisation: { pid: organisationId } },
|
||||
select: basicGroup,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
groups,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
interface GetAllGroupsSearchParams {
|
||||
organisationPid?: string;
|
||||
}
|
||||
|
||||
export const getAllGroups = async (req: Request<{}, {}, {}, GetAllGroupsSearchParams>, res: Response) => {
|
||||
return _getAllGroups(res, req.query.organisationPid);
|
||||
};
|
||||
|
||||
interface getAllGroupsWithParamQueryParams {
|
||||
organisationPid: string;
|
||||
}
|
||||
|
||||
export const getAllGroupsWithParam = async (req: Request<getAllGroupsWithParamQueryParams>, res: Response) => {
|
||||
return _getAllGroups(res, req.params.organisationPid);
|
||||
};
|
||||
|
||||
interface GetGroupQueryParams {
|
||||
pid: string;
|
||||
}
|
||||
|
||||
export const getGroup = async (req: Request<GetGroupQueryParams>, res: Response) => {
|
||||
const { pid } = req.params;
|
||||
|
||||
try {
|
||||
const group: {
|
||||
pid: string;
|
||||
name: string;
|
||||
organisation: { pid: string; name: string };
|
||||
admins?: { pid: string; name: string }[];
|
||||
participants?: { pid: string }[];
|
||||
} | null = await prisma.group.findUnique({
|
||||
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 } },
|
||||
}
|
||||
: basicGroup,
|
||||
});
|
||||
|
||||
if (!group) {
|
||||
return res.status(404).json(generateError(`The group with ID '${pid}' could not be found`));
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
group: {
|
||||
...group,
|
||||
organisation: {
|
||||
...group.organisation,
|
||||
_links: [{ rel: "self", type: "GET", href: `/api/organisation/${group.organisation.pid}` }],
|
||||
},
|
||||
...(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}` }],
|
||||
})),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof PrismaClientUnknownRequestError) {
|
||||
return res.status(400).json(generateError("Unknown error occured. This could be due to malformed IDs"));
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(500).json(genericError);
|
||||
};
|
||||
|
||||
// at: POST /api/organisations/:eventPid/groups
|
||||
// requires: auth(ELEVATED)
|
||||
export const createGroup = async (req: Request<{ organisationPid: string }, {}, { name?: string }>, res: Response) => {
|
||||
return handleCreateByName(
|
||||
{ type: "group", data: { name: req.body.name, level: 1 } },
|
||||
{ type: "organisation", id: req.params.organisationPid },
|
||||
req,
|
||||
res
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,233 @@
|
||||
import { PrismaClientUnknownRequestError } from "@prisma/client/runtime";
|
||||
import { Request, Response } from "express";
|
||||
import prisma from "../lib/prisma";
|
||||
import {
|
||||
AUTH_ERROR,
|
||||
createInsufficientPermissionsError,
|
||||
DataType,
|
||||
generateError,
|
||||
generateInvalidBodyError,
|
||||
genericError,
|
||||
handleCreateByName,
|
||||
} from "./common";
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
function validateOranisationName(name: string) {
|
||||
return name.length > 0;
|
||||
}
|
||||
|
||||
const detailedOrganisation = {
|
||||
pid: true,
|
||||
name: true,
|
||||
event: {
|
||||
select: {
|
||||
pid: true,
|
||||
name: true,
|
||||
date: true,
|
||||
description: true,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
const basicOrganisation = {
|
||||
pid: true,
|
||||
name: true,
|
||||
event: {
|
||||
select: {
|
||||
pid: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const _getAllOrganisations = async (res: Response, eventId: string | undefined = undefined) => {
|
||||
const organisations = await prisma.organisation.findMany({
|
||||
where: { event: { pid: eventId } },
|
||||
select: basicOrganisation,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
organisations,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
interface GetAllOrganisationsSearchParams {
|
||||
eventId?: string;
|
||||
}
|
||||
|
||||
export const getAllOrganisations = async (req: Request<{}, {}, {}, GetAllOrganisationsSearchParams>, res: Response) => {
|
||||
// TODO: Maybe rename to eventPid
|
||||
return _getAllOrganisations(res, req.query.eventId);
|
||||
};
|
||||
|
||||
interface GetAllOrganisationsWithParamQueryParams {
|
||||
eventPid: string;
|
||||
}
|
||||
|
||||
export const getAllOrganisationsWithParam = async (
|
||||
req: Request<GetAllOrganisationsWithParamQueryParams>,
|
||||
res: Response
|
||||
) => {
|
||||
return _getAllOrganisations(res, req.params.eventPid);
|
||||
};
|
||||
|
||||
interface GetOrganisationQueryParams {
|
||||
pid: string;
|
||||
}
|
||||
|
||||
export const getOrganisation = async (req: Request<GetOrganisationQueryParams>, res: Response) => {
|
||||
const { pid } = req.params;
|
||||
|
||||
const organisation = await prisma.organisation.findUnique({
|
||||
where: { pid },
|
||||
select: detailedOrganisation,
|
||||
});
|
||||
|
||||
if (!organisation) {
|
||||
return res.status(404).json({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: `The organisation with ID '${pid} could not be found'`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
organisation: {
|
||||
...organisation,
|
||||
event: {
|
||||
...organisation.event,
|
||||
_links: [{ rel: "self", type: "GET", href: `/api/event/${organisation.event.pid}` }],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
interface CreateOrganisationQueryParams {
|
||||
eventPid: string;
|
||||
}
|
||||
|
||||
interface CreateOrganisationBody {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
// at: POST /api/events/:eventPid/organisations
|
||||
// requires: auth(ELEVATED)
|
||||
export const createOrganisation = async (
|
||||
req: Request<CreateOrganisationQueryParams, {}, CreateOrganisationBody>,
|
||||
res: Response
|
||||
) => {
|
||||
return handleCreateByName(
|
||||
{ type: "organisation", data: { name: req.body.name } },
|
||||
{ type: "event", id: req.params.eventPid },
|
||||
req,
|
||||
res
|
||||
);
|
||||
};
|
||||
|
||||
interface UpdateOrganisationQueryParams {
|
||||
pid: string;
|
||||
}
|
||||
|
||||
interface UpdateOrganisationBody {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
// requires: auth(ELEVATED)
|
||||
export const updateOrganisation = async (
|
||||
req: Request<UpdateOrganisationQueryParams, {}, UpdateOrganisationBody>,
|
||||
res: Response
|
||||
) => {
|
||||
if (!req.auth?.isAuthenticated) {
|
||||
return res.status(500).json(AUTH_ERROR);
|
||||
}
|
||||
|
||||
if (req.auth.permission_level !== "ELEVATED") {
|
||||
return res.status(403).json(createInsufficientPermissionsError());
|
||||
}
|
||||
|
||||
const { pid } = req.params;
|
||||
const { name } = req.body;
|
||||
|
||||
if (name !== undefined && typeof name !== "string") {
|
||||
return res.status(400).json(
|
||||
generateInvalidBodyError({
|
||||
name: DataType.STRING,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (name !== undefined && !validateOranisationName(name)) {
|
||||
return res.status(400).json({
|
||||
type: "error",
|
||||
payload: {
|
||||
message: "The name has to be at least 1 character long",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const organisation = await prisma.organisation.update({
|
||||
where: { pid },
|
||||
data: { name },
|
||||
select: detailedOrganisation,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
type: "success",
|
||||
payload: {
|
||||
organisation,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof PrismaClientKnownRequestError) {
|
||||
if (e.code === "P2025") {
|
||||
return res.status(404).json(generateError(`The organisation with the ID ${pid} could not be found`));
|
||||
}
|
||||
} else if (e instanceof PrismaClientUnknownRequestError) {
|
||||
return res.status(400).send(generateError("Unkonwn error occured. This could be due to malformed IDs"));
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(500).json(genericError);
|
||||
};
|
||||
|
||||
interface DeleteOrganisationQueryParams {
|
||||
pid: string;
|
||||
}
|
||||
|
||||
// requires: auth(ELEVATED)
|
||||
export const deleteOrganisation = async (req: Request<DeleteOrganisationQueryParams>, res: Response) => {
|
||||
if (!req.auth?.isAuthenticated) {
|
||||
return res.status(500).json(AUTH_ERROR);
|
||||
}
|
||||
|
||||
if (req.auth.permission_level !== "ELEVATED") {
|
||||
return res.status(403).json(createInsufficientPermissionsError());
|
||||
}
|
||||
|
||||
const { pid } = req.params;
|
||||
|
||||
try {
|
||||
prisma.organisation.delete({ where: { pid } });
|
||||
|
||||
res.status(204).end();
|
||||
} catch (e) {
|
||||
if (e instanceof PrismaClientKnownRequestError) {
|
||||
if ((e.code = "P2025")) {
|
||||
return res.status(404).json(generateError(`The organisation with the ID ${pid} could not be found`));
|
||||
}
|
||||
} else if (e instanceof PrismaClientUnknownRequestError) {
|
||||
return res.status(400).send(generateError("Unkonwn error occured. This could be due to malformed IDs"));
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(500).json(genericError);
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
import express from "express";
|
||||
import { createGroup, getAllGroups, getAllGroupsWithParam, getGroup } from "../Controllers/group.controllers";
|
||||
import { requireAuthentication } from "../Middleware/auth/auth";
|
||||
import organisationRouter from "./organisation.routes";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/", getAllGroups);
|
||||
router.get("/:pid", getGroup);
|
||||
|
||||
organisationRouter.get("/:organisationPid/groups", getAllGroupsWithParam);
|
||||
organisationRouter.post("/:organisationPid/groups", requireAuthentication, createGroup);
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,25 @@
|
||||
import express from "express";
|
||||
import eventRouter from "./event.routes";
|
||||
import {
|
||||
createOrganisation,
|
||||
getAllOrganisations,
|
||||
getAllOrganisationsWithParam,
|
||||
getOrganisation,
|
||||
updateOrganisation,
|
||||
} from "../Controllers/organisation.controller";
|
||||
import { requireAuthentication } from "../Middleware/auth/auth";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/", getAllOrganisations);
|
||||
router.get("/:pid", getOrganisation);
|
||||
router.put<"/:pid", { pid: string }>("/:pid", requireAuthentication, updateOrganisation);
|
||||
|
||||
eventRouter.get("/:eventPid/organisations", getAllOrganisationsWithParam);
|
||||
eventRouter.post<"/:eventPid/organisations", { eventPid: string }>(
|
||||
"/:eventPid/organisations",
|
||||
requireAuthentication,
|
||||
createOrganisation
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -4,6 +4,9 @@ import eventRouter from "./Routes/event.routes";
|
||||
import adminAuthRouter from "./Routes/admin_auth.routes";
|
||||
import argon2 from "argon2";
|
||||
import adminRouter from "./Routes/admin.routes";
|
||||
import organisationRouter from "./Routes/organisation.routes";
|
||||
import groupRouter from "./Routes/group.routes";
|
||||
|
||||
|
||||
require("dotenv").config(); // Load dotenv config
|
||||
|
||||
@@ -46,6 +49,9 @@ async function main() {
|
||||
|
||||
app.use("/api/admins", adminRouter);
|
||||
|
||||
app.use("/api/organisations", organisationRouter);
|
||||
|
||||
app.use("/api/groups", groupRouter);
|
||||
app.listen(process.env.PORT, () => {
|
||||
console.log(`Listening on Port: ${process.env.PORT}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user