import { ErrorRequestHandler, Request, RequestHandler } from 'express'; import { randomUUID } from 'crypto'; import { validationResult } from 'express-validator'; import { UserInfo, UserRoles } from '@core'; declare module 'express-session' { interface SessionData { user: UserInfo | null; } } export function getRequestId(req: Request): string { return req.header('request-id') || 'unknown'; } export function RequestId(): RequestHandler { return (req, res, next) => { req.headers['request-id'] = randomUUID(); next(); }; } export function CheckPermissions(): RequestHandler { function getResourceId(req: Request): string | null { if (req.method === 'GET' && req.params.uuid) return req.params.uuid; if ((req.method === 'POST' || req.method === 'PUT') && req.body.uuid) return req.body.uuid; return null; } function canAccessRessource(user: UserInfo, uuid: string): boolean { if (user.uuid === uuid) return true; return false; } return (req, res, next) => { if (!req.session.user) { return next({ status: 401, messsage: 'Unauthorized' }); } if (req.session.user.role === UserRoles.ADMIN) { return next(); } const ressourceId = getResourceId(req); if (!ressourceId) { return next({ status: 403, messsage: 'Forbidden' }); } if (canAccessRessource(req.session.user, ressourceId)) { return next(); } next({ status: 403, messsage: 'Forbidden' }); }; } export function SchemaValidator(keys: number = 0): RequestHandler { return (req, res, next) => { if (Object.keys(req.body).length > keys) return next({ status: 400, message: `Found ${Object.keys(req.body).length} keys expected ${keys}`, }); const error = validationResult(req); error.isEmpty() ? next() : next({ status: 400, ...error, }); }; } export function ErrorHandler(): ErrorRequestHandler { return (error, req, res, next) => { error.status ? res.status(error.status).send(error) : res.status(500).send({ status: 500, message: error.message }); }; }