UNPKG

@brandazm/dynamic-permissions

Version:

A flexible and powerful permissions management system for NestJS applications with built-in security features

139 lines 6.31 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SecurityMiddleware = void 0; const common_1 = require("@nestjs/common"); const helmet_1 = __importDefault(require("helmet")); const express_rate_limit_1 = __importDefault(require("express-rate-limit")); const config_service_1 = require("../services/config.service"); let SecurityMiddleware = class SecurityMiddleware { constructor(configService) { this.configService = configService; this.config = this.configService.getSecurityConfig(); if (this.config.helmet.enabled) { this.helmetMiddleware = (0, helmet_1.default)({ contentSecurityPolicy: this.config.helmet.contentSecurityPolicy, crossOriginEmbedderPolicy: this.config.helmet.crossOriginEmbedderPolicy, crossOriginOpenerPolicy: this.config.helmet.crossOriginOpenerPolicy, crossOriginResourcePolicy: this.config.helmet.crossOriginResourcePolicy ? { policy: 'same-site' } : false, dnsPrefetchControl: this.config.helmet.dnsPrefetchControl, frameguard: this.config.helmet.frameguard ? { action: 'deny' } : false, hidePoweredBy: this.config.helmet.hidePoweredBy, hsts: this.config.helmet.hsts ? { maxAge: 31536000, includeSubDomains: true, preload: true, } : false, ieNoOpen: this.config.helmet.ieNoOpen, noSniff: this.config.helmet.noSniff, referrerPolicy: this.config.helmet.referrerPolicy ? { policy: 'strict-origin-when-cross-origin' } : false, xssFilter: this.config.helmet.xssFilter, }); } if (this.config.rateLimit.enabled) { this.rateLimiter = (0, express_rate_limit_1.default)({ windowMs: this.config.rateLimit.windowMs, max: this.config.rateLimit.max, message: 'Too many requests from this IP, please try again later', standardHeaders: true, legacyHeaders: false, }); } } use(req, res, next) { const chain = []; if (this.config.helmet.enabled) { chain.push((req, res, next) => { this.helmetMiddleware(req, res, next); }); } if (this.config.rateLimit.enabled) { chain.push((req, res, next) => { this.rateLimiter(req, res, next); }); } if (this.config.cors.enabled) { chain.push((req, res, next) => { const origin = req.headers.origin; if (origin && this.isAllowedOrigin(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Methods', this.config.cors.allowedMethods.join(',')); res.setHeader('Access-Control-Allow-Headers', this.config.cors.allowedHeaders.join(',')); res.setHeader('Access-Control-Expose-Headers', this.config.cors.exposedHeaders.join(',')); if (this.config.cors.credentials) { res.setHeader('Access-Control-Allow-Credentials', 'true'); } } next(); }); } if (this.config.requestValidation.validateContentType) { chain.push((req, res, next) => { try { this.validateRequest(req); next(); } catch (error) { next(error); } }); } const executeChain = (index) => { if (index < chain.length) { chain[index](req, res, (error) => { if (error) { next(error); } else { executeChain(index + 1); } }); } else { next(); } }; executeChain(0); } validateRequest(req) { if (this.config.requestValidation.requireJsonContent) { if (['POST', 'PUT', 'PATCH'].includes(req.method)) { const contentType = req.headers['content-type']; if (!contentType || !contentType.includes('application/json')) { throw new Error('Invalid Content-Type. Expected application/json'); } } } const contentLength = parseInt(req.headers['content-length'] || '0', 10); if (contentLength > this.config.requestValidation.maxBodySize) { throw new Error('Request body too large'); } } isAllowedOrigin(origin) { return (this.config.cors.allowedOrigins.includes(origin) || this.config.cors.allowedOrigins.includes('*')); } }; exports.SecurityMiddleware = SecurityMiddleware; exports.SecurityMiddleware = SecurityMiddleware = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [config_service_1.ConfigService]) ], SecurityMiddleware); //# sourceMappingURL=security.middleware.js.map