module.exports = function(options = {}) { let security = {} security.options = options security.setHeaders = function(req, res, next) { if(!security.options) options = {} else options = security.options if (typeof options.CacheControl === 'undefined') { options.CacheControl = 'no-cache, no-store, must-revalidate' } if (options.CacheControl !== false) { res.set('Cache-Control', options.CacheControl) } if (typeof options.Pragma === 'undefined') { options.Pragma = 'no-cache' } if (options.Pragma !== false) { res.set('Pragma', options.Pragma) } if (typeof options.Expires === 'undefined') { options.Expires = '0' } if (options.Expires !== false) { res.set('Expires', options.Expires) } if (typeof options.ContentSecurityPolicy === 'undefined') { options.ContentSecurityPolicy = 'default-src \'self\'; frame-ancestors \'none\'' } if (options.ContentSecurityPolicy !== false) { res.set('Content-Security-Policy', options.ContentSecurityPolicy ) } if (typeof options.XXSSProtection === 'undefined') { options.XXSSProtection = '1; mode=block' } if (options.XXSSProtection !== false) { res.set('X-XSS-Protection', options.XXSSProtection) } if (typeof options.XDNSPrefetchControl === 'undefined') { options.XDNSPrefetchControl = 'off' } if (options.XDNSPrefetchControl !== false) { res.set('X-DNS-Prefetch-Control', options.XDNSPrefetchControl) } if (typeof options.ExpectCT === 'undefined') { options.ExpectCT = 'enforce; max-age=30; report-uri="/_report"' } if (options.ExpectCT !== false) { res.set('Expect-CT', options.ExpectCT) } if (typeof options.XFrameOptions === 'undefined') { options.XFrameOptions = 'deny' } if (options.XFrameOptions !== false) { res.set('X-Frame-Options', options.XFrameOptions) } if (typeof options.XPoweredBy === 'undefined') { options.XPoweredBy = true } if (options.XPoweredBy !== false) { res.removeHeader('X-Powered-By') } if (typeof options.StrictTransportSecurity === 'undefined') { options.StrictTransportSecurity = 'max-age=30' } if (options.StrictTransportSecurity !== false) { res.set('Strict-Transport-Security', options.StrictTransportSecurity) } if (typeof options.XDownloadOptions === 'undefined') { options.XDownloadOptions = 'noopen' } if (options.XDownloadOptions !== false) { res.set('X-Download-Options', options.XDownloadOptions) } if (typeof options.XContentTypeOptions === 'undefined') { options.XContentTypeOptions = 'nosniff' } if (options.XContentTypeOptions !== false) { res.set('X-Content-Type-Options', options.XContentTypeOptions ) } if (typeof options.XPermittedCrossDomainPolicies === 'undefined') { options.XPermittedCrossDomainPolicies = 'none' } if (options.XPermittedCrossDomainPolicies !== false) { res.set('X-Permitted-Cross-Domain-Policies', options.XPermittedCrossDomainPolicies) } if (typeof options.ReferrerPolicy === 'undefined') { options.ReferrerPolicy = 'no-referrer' } if (options.ReferrerPolicy !== false) { res.set('Referrer-Policy', options.ReferrerPolicy) } if (typeof options.allowedMethods === 'undefined') { options.allowedMethods = ['GET', 'POST', 'PUT', 'DELETE'] } if (!options.allowedMethods.includes(req.method)) { res.status(405).end() } if (typeof options.onlyDefinedRoutes === 'undefined') { options.onlyDefinedRoutes = false } if (options.onlyDefinedRoutes) { if (!options.definedRoutes) { options.definedRoutes = [] } let isAllowed = false; for (const allowedRoute of options.definedRoutes) { if (allowedRoute.startsWith('REGEX:')) { let regexString = allowedRoute.split('REGEX:')[1]; let regexp = new RegExp(regexString); if (regexp.test(req.originalUrl)) { isAllowed= true; } } else { if (req.originalUrl === allowedRoute) { isAllowed = true; } } } if (!isAllowed) { res.status(405).end() } } next() } return security; }