@hmcts/rpx-xui-node-lib
Version:
Common nodejs library components for XUI
40 lines • 2.45 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.csp = csp;
const helmet_1 = __importDefault(require("helmet"));
const node_crypto_1 = __importDefault(require("node:crypto"));
const deepmerge_1 = __importDefault(require("deepmerge"));
function csp(_a) {
var _b, _c, _d, _e, _f;
var { extraScript = ((_b = process.env.CSP_SCRIPT_EXTRA) !== null && _b !== void 0 ? _b : '').split(',').filter(Boolean), extraStyle = ((_c = process.env.CSP_STYLE_EXTRA) !== null && _c !== void 0 ? _c : '').split(',').filter(Boolean), extraConnect = ((_d = process.env.CSP_CONNECT_EXTRA) !== null && _d !== void 0 ? _d : '').split(',').filter(Boolean), extraFont = ((_e = process.env.CSP_FONT_EXTRA) !== null && _e !== void 0 ? _e : '').split(',').filter(Boolean), extraImg = ((_f = process.env.CSP_IMG_EXTRA) !== null && _f !== void 0 ? _f : '').split(',').filter(Boolean), defaultCsp = {} } = _a === void 0 ? {} : _a;
return (req, res, next) => {
const nonce = node_crypto_1.default.randomBytes(16).toString('base64');
res.locals.cspNonce = nonce;
const newCsp = {
useDefaults: true,
directives: {
// dashed form is fine too, but keep the SAME spelling everywhere
defaultSrc: ["'self'"],
scriptSrc: ["'self'", `'nonce-${nonce}'`, ...extraScript],
styleSrc: ["'self'", `'nonce-${nonce}'`, ...extraStyle],
// inline style attributes still allowed - should be phased out in future
styleSrcAttr: ["'unsafe-inline'"],
connectSrc: ["'self'", "blob:", "data:", ...extraConnect],
imgSrc: ["'self'", "data:", ...extraImg],
fontSrc: ["'self'", "data:", "https://fonts.gstatic.com", ...extraFont],
objectSrc: ["'none'"],
frameSrc: ["'self'"],
frameAncestors: ["'self'"],
formAction: ["'none'"]
},
reportOnly: process.env.CSP_REPORT_ONLY === 'true'
};
// deep‑merge so we don’t lose anything from SECURITY_POLICY
const finalCsp = (0, deepmerge_1.default)(defaultCsp, newCsp);
helmet_1.default.contentSecurityPolicy(finalCsp)(req, res, next);
};
}
//# sourceMappingURL=csp.js.map