Files
rate/api/src/framework/express/middleware.ts

86 lines
2.1 KiB
TypeScript

import { ErrorRequestHandler, Request, RequestHandler } from 'express';
import { randomUUID } from 'crypto';
import { validationResult, matchedData } 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('x-request-id') || 'unknown';
}
export function RequestId(): RequestHandler {
return (req, res, next) => {
req.headers['x-request-id'] = randomUUID();
next();
};
}
export function CheckPermissions(): RequestHandler {
function getResourceId(req: Request): string | undefined {
if (req.params.uuid) return req.params.uuid;
if (req.body.uuid) return req.body.uuid;
return undefined;
}
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 ValidateSchema(): RequestHandler {
return (req, res, next) => {
const error = validationResult(req);
const oldBody = req.body;
req.body = matchedData(req, { locations: ['body'] });
if (JSON.stringify(oldBody) !== JSON.stringify(req.body))
return next({
status: 422,
message: 'Unprocessable Entity',
});
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 });
};
}