UNPKG

nestjs-security-module

Version:

A plug-and-play NestJS security module with CORS, Helmet, rate limiting, audit logging, CSP, XSS sanitization, and more.

163 lines 6.87 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 __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var SecurityModule_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.SecurityModule = exports.SECURITY_MODULE_OPTIONS = void 0; const common_1 = require("@nestjs/common"); const helmet_1 = require("helmet"); const config_1 = require("@nestjs/config"); const audit_log_middleware_1 = require("./middlewares/audit-log.middleware"); const rate_limit_middleware_1 = require("./middlewares/rate-limit.middleware"); exports.SECURITY_MODULE_OPTIONS = 'SECURITY_MODULE_OPTIONS'; let SecurityModule = SecurityModule_1 = class SecurityModule { options; static register(securityConfig) { throw new Error('Method not implemented.'); } constructor(options) { this.options = options; } static forRoot(options) { const optsProvider = { provide: exports.SECURITY_MODULE_OPTIONS, useValue: options, }; return { module: SecurityModule_1, providers: [optsProvider], exports: [optsProvider], }; } static forRootAsync(asyncOptions) { const asyncOptsProvider = { provide: exports.SECURITY_MODULE_OPTIONS, useFactory: asyncOptions.useFactory, inject: asyncOptions.inject || [], }; return { module: SecurityModule_1, imports: [...(asyncOptions.imports || []), config_1.ConfigModule], providers: [asyncOptsProvider], exports: [asyncOptsProvider], }; } configure(consumer) { const options = this.options; if (!options) { throw new Error('[SecurityModule] SecurityModuleOptions not provided. Use forRoot or forRootAsync to configure.'); } if (options.helmet !== false) { consumer.apply((0, helmet_1.default)()).forRoutes('*'); } if (options.cors) { const corsOpts = typeof options.cors === 'object' ? options.cors : {}; consumer .apply((_req, res, next) => { if (corsOpts.origin) { res.setHeader('Access-Control-Allow-Origin', corsOpts.origin); } if (corsOpts.methods) { res.setHeader('Access-Control-Allow-Methods', corsOpts.methods); } next(); }) .forRoutes('*'); } if (options.rateLimit) { consumer .apply((0, rate_limit_middleware_1.createRateLimitMiddleware)(options.rateLimit)) .forRoutes('*'); } if (options.auditLog) { consumer.apply((0, audit_log_middleware_1.createAuditLogMiddleware)()).forRoutes('*'); } if (options.csp) { const cspConfig = typeof options.csp === 'object' ? options.csp : { useDefaults: true, directives: { "default-src": ["'self'"], "script-src": ["'self'"], "style-src": ["'self'", "'unsafe-inline'"], "img-src": ["'self'", 'data:'], }, }; consumer .apply(helmet_1.default.contentSecurityPolicy(cspConfig)) .forRoutes('*'); } if (options.xFrameOptions) { const action = typeof options.xFrameOptions === 'string' ? options.xFrameOptions.toLowerCase() : 'sameorigin'; consumer .apply(helmet_1.default.frameguard({ action: action })) .forRoutes('*'); } if (options.referrerPolicy) { const policy = typeof options.referrerPolicy === 'object' ? options.referrerPolicy : { policy: 'no-referrer' }; consumer.apply(helmet_1.default.referrerPolicy(policy)).forRoutes('*'); } if (options.hsts) { const hstsConfig = typeof options.hsts === 'object' ? options.hsts : { maxAge: 60 * 60 * 24 * 180 }; consumer.apply(helmet_1.default.hsts(hstsConfig)).forRoutes('*'); } if (options.xContentTypeOptions !== false) { consumer.apply(helmet_1.default.noSniff()).forRoutes('*'); } if (options.expectCt) { const expectCtConfig = typeof options.expectCt === 'object' ? options.expectCt : { maxAge: 86400, enforce: true }; consumer .apply((_, res, next) => { res.setHeader('Expect-CT', `max-age=${expectCtConfig.maxAge}${expectCtConfig.enforce ? ', enforce' : ''}`); next(); }) .forRoutes('*'); } if (options.permissionsPolicy) { const policy = Object.entries(options.permissionsPolicy) .map(([key, val]) => `${key}=(${val.join(' ')})`) .join(', '); consumer .apply((_, res, next) => { res.setHeader('Permissions-Policy', policy); next(); }) .forRoutes('*'); } if (options.crossOriginEmbedderPolicy !== false) { const coepConfig = typeof options.crossOriginEmbedderPolicy === 'object' ? options.crossOriginEmbedderPolicy : {}; consumer .apply(helmet_1.default.crossOriginEmbedderPolicy(coepConfig)) .forRoutes('*'); } } }; exports.SecurityModule = SecurityModule; exports.SecurityModule = SecurityModule = SecurityModule_1 = __decorate([ (0, common_1.Global)(), (0, common_1.Module)({}), __param(0, (0, common_1.Inject)(exports.SECURITY_MODULE_OPTIONS)), __metadata("design:paramtypes", [Object]) ], SecurityModule); //# sourceMappingURL=security.module.js.map