env + perms + tools
This commit is contained in:
@ -25,7 +25,7 @@ const services: Services = {
|
||||
userModel: new UserModel(db),
|
||||
};
|
||||
|
||||
const server = new Server(config.server, services);
|
||||
const server = new Server(config.server, config.mongo, services);
|
||||
|
||||
server.start(() =>
|
||||
console.log(
|
||||
|
@ -2,7 +2,6 @@ import { ErrorRequestHandler, Request, RequestHandler } from 'express';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { validationResult } from 'express-validator';
|
||||
import { UserInfo, UserRoles } from '@core';
|
||||
import permissions from './permissions';
|
||||
|
||||
declare module 'express-session' {
|
||||
interface SessionData {
|
||||
@ -21,62 +20,42 @@ export function RequestId(): RequestHandler {
|
||||
};
|
||||
}
|
||||
|
||||
export function checkPermissions(): RequestHandler {
|
||||
const getRoute = (url: string): string => {
|
||||
for (const route in permissions) {
|
||||
if (url.startsWith(route)) return route;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const canAccess = (req: Request): boolean => {
|
||||
const user = req.session.user;
|
||||
if (!user) return false;
|
||||
|
||||
//Logout
|
||||
if (req.url === '/user/logout') {
|
||||
return true;
|
||||
}
|
||||
|
||||
//User Imself
|
||||
if (req.params.uuid === user.uuid) {
|
||||
return true;
|
||||
}
|
||||
export function CheckPermissions(): RequestHandler {
|
||||
function getResourceId(req: Request): string | null {
|
||||
console.log(req.url);
|
||||
if (req.params.uuid) return req.params.uuid;
|
||||
if (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) => {
|
||||
const route = getRoute(req.url);
|
||||
console.log(canAccess(req));
|
||||
console.log(route);
|
||||
|
||||
if (!req.session.user && req.url === '/user/login') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req.session.user) {
|
||||
next({ status: 401, messsage: 'Unauthorized' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!(route in permissions) ||
|
||||
(req.session.user.role !== permissions[route] &&
|
||||
req.session.user.role !== UserRoles.ADMIN) ||
|
||||
(!canAccess(req) && req.session.user.role !== UserRoles.ADMIN)
|
||||
) {
|
||||
next({ status: 401, messsage: 'Unauthorized' });
|
||||
if (req.session.user.role === UserRoles.ADMIN) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
req.session.user.role === UserRoles.ADMIN ||
|
||||
(req.session.user.role === permissions[route] && canAccess(req))
|
||||
) {
|
||||
const ressourceId = getResourceId(req);
|
||||
console.log(ressourceId);
|
||||
if (!ressourceId) {
|
||||
next({ status: 403, messsage: 'Forbidden' });
|
||||
return;
|
||||
}
|
||||
if (canAccessRessource(req.session.user, ressourceId)) {
|
||||
next();
|
||||
return;
|
||||
} else {
|
||||
next({ status: 403, messsage: 'Forbidden' });
|
||||
return;
|
||||
}
|
||||
|
||||
next({ status: 401, messsage: 'Unauthorized' });
|
||||
|
@ -1,10 +0,0 @@
|
||||
import { UserRoles } from '@core';
|
||||
|
||||
const permissions = {
|
||||
'/user/login': UserRoles.USER,
|
||||
'/user/logout': UserRoles.USER,
|
||||
'/user/read': UserRoles.USER,
|
||||
'/user/create': UserRoles.ADMIN,
|
||||
};
|
||||
|
||||
export default permissions;
|
@ -2,10 +2,10 @@ import { Router } from 'express';
|
||||
import { Services } from '../../app';
|
||||
import * as user from './user';
|
||||
|
||||
export function getRoutes(services: Services) {
|
||||
export function Routes(services: Services) {
|
||||
const router = Router();
|
||||
|
||||
router.use('/user', user.getRoutes(services));
|
||||
router.use('/user', user.Routes(services));
|
||||
|
||||
return router;
|
||||
}
|
||||
|
@ -1,17 +1,22 @@
|
||||
import express, { Express } from 'express';
|
||||
import cors from 'cors';
|
||||
import session from 'express-session';
|
||||
import { getRoutes } from './router';
|
||||
import { RequestId, ErrorHandler, checkPermissions } from './middleware';
|
||||
import { Routes } from './router';
|
||||
import { RequestId, ErrorHandler } from './middleware';
|
||||
import { Services } from '../../app';
|
||||
import { ServerConfig } from '../../config';
|
||||
import { MongoConfig, ServerConfig } from '../../config';
|
||||
import { randomUUID } from 'crypto';
|
||||
import MongoStore from 'connect-mongo';
|
||||
|
||||
class Server {
|
||||
private app: Express;
|
||||
private config: ServerConfig;
|
||||
|
||||
constructor(config: ServerConfig, services: Services) {
|
||||
constructor(
|
||||
config: ServerConfig,
|
||||
mongoConfig: MongoConfig,
|
||||
services: Services,
|
||||
) {
|
||||
this.config = config;
|
||||
|
||||
this.app = express();
|
||||
@ -26,14 +31,23 @@ class Server {
|
||||
this.app.use(RequestId());
|
||||
this.app.use(
|
||||
session({
|
||||
proxy: process.env.NODE_ENV === 'production',
|
||||
secret: randomUUID(),
|
||||
cookie: { maxAge: 1000 * 3600 * 24 },
|
||||
cookie: {
|
||||
maxAge: 1000 * 3600 * 24,
|
||||
sameSite: 'strict',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
},
|
||||
store: MongoStore.create({
|
||||
mongoUrl: mongoConfig.uri,
|
||||
dbName: mongoConfig.dbName,
|
||||
touchAfter: 3600,
|
||||
}),
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
}),
|
||||
);
|
||||
//this.app.use(checkPermissions());
|
||||
this.app.use(getRoutes(services));
|
||||
this.app.use(Routes(services));
|
||||
this.app.use(ErrorHandler());
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
ReadUserSchema,
|
||||
LogoutUserSchema,
|
||||
} from './schema/user';
|
||||
import { getId, SchemaValidator } from './middleware';
|
||||
import { CheckPermissions, getId, SchemaValidator } from './middleware';
|
||||
|
||||
function LoginHandler(services: Services): RequestHandler {
|
||||
const login = LoginUser(services);
|
||||
@ -52,16 +52,9 @@ function ReadHandler(services: Services): RequestHandler {
|
||||
};
|
||||
}
|
||||
|
||||
export function getRoutes(services: Services) {
|
||||
export function Routes(services: Services) {
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/read/:uuid',
|
||||
ReadUserSchema(),
|
||||
SchemaValidator(),
|
||||
ReadHandler(services),
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/login',
|
||||
LoginUserSchema(),
|
||||
@ -74,10 +67,19 @@ export function getRoutes(services: Services) {
|
||||
SchemaValidator(),
|
||||
LogoutHandler(services),
|
||||
);
|
||||
router.get(
|
||||
'/read/:uuid',
|
||||
ReadUserSchema(),
|
||||
SchemaValidator(),
|
||||
CheckPermissions(),
|
||||
ReadHandler(services),
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/create',
|
||||
CreateUserSchema(),
|
||||
SchemaValidator(),
|
||||
CheckPermissions(),
|
||||
CreateHandler(services),
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user