UNPKG

@dwp/govuk-casa

Version:

A framework for building GOVUK Collect-And-Submit-Applications

107 lines 4.04 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_crypto_1 = require("node:crypto"); const helmet_1 = __importDefault(require("helmet")); /** * @typedef {import("../casa").HelmetConfigurator} HelmetConfigurator * @access private */ const GA_DOMAIN = "*.google-analytics.com"; const GA_ANALYTICS_DOMAIN = "*.analytics.google.com"; const GTM_DOMAIN = "*.googletagmanager.com"; const GTM_PREVIEW_DOMAIN = "https://tagmanager.google.com"; /** * Extracts the CSP nonce used in every template, and makes it available as a * nonce value in the CSP header. * * IMPORTANT: Do not rename this function as it _might_ be used in consumer code * to identify this function specifically, most likely to remove it from CSP * headers for custom purposes. * * @param {import("express").Request} req Request * @param {import("express").Response} res Response * @returns {string} Nonce value suitable for use in CSP header */ function casaCspNonce(req, res) { return `'nonce-${res.locals.cspNonce}'`; } /** * Pre middleware. * * @param {object} opts Options * @param {HelmetConfigurator} opts.helmetConfigurator Function to customise * Helmet configuration * @returns {Function[]} List of middleware */ exports.default = ({ helmetConfigurator = (config) => config } = {}) => [ // Only allow certain request methods (req, res, next) => { if (req.method !== "GET" && req.method !== "POST") { const err = new Error(`Unaccepted request method, "${String(req.method).substr(0, 7)}"`); err.code = "unaccepted_request_method"; next(err); } else { next(); } }, // Prevent caching response in any intermediaries by default, in case it // contains sensitive data. // The `no-store` setting is to specifically disable the bfcache and prevent // possible leakage of information. (req, res, next) => { res.set("cache-control", "no-store"); res.set("expires", 0); res.set("x-robots-tag", "noindex, nofollow"); next(); }, // Generate nonces ready for use in Content-Security-Policy header and // govuk-frontend template. This same none can be used wherever required. (req, res, next) => { res.locals.cspNonce = (0, node_crypto_1.randomBytes)(16).toString("hex"); next(); }, // Helmet suite of headers (0, helmet_1.default)(helmetConfigurator({ // Allows GA which is typically used, and a known inline script nonce contentSecurityPolicy: { useDefaults: true, directives: { "default-src": ["'none'"], "script-src": [ "'self'", GA_DOMAIN, GTM_DOMAIN, GTM_PREVIEW_DOMAIN, casaCspNonce, ], "img-src": [ "'self'", GA_DOMAIN, GA_ANALYTICS_DOMAIN, GTM_DOMAIN, "https://ssl.gstatic.com", "https://www.gstatic.com", ], "connect-src": ["'self'", GA_DOMAIN, GA_ANALYTICS_DOMAIN, GTM_DOMAIN], "frame-src": ["'self'", GTM_DOMAIN], "frame-ancestors": ["'self'"], "form-action": ["'self'"], "style-src": [ "'self'", "https://fonts.googleapis.com", GTM_PREVIEW_DOMAIN, casaCspNonce, ], "font-src": ["'self'", "data:", "https://fonts.gstatic.com"], "manifest-src": ["'self'"], }, }, // // Require referrer to aid navigation // referrerPolicy: 'no-referrer, same-origin', })), ]; //# sourceMappingURL=pre.js.map