UNPKG

csp-header

Version:

Content-Security-Policy header generator

134 lines 4.46 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCSP = getCSP; exports.nonce = nonce; const directives_1 = require("./constants/directives"); const values_1 = require("./constants/values"); __exportStar(require("./types"), exports); __exportStar(require("./constants/directives"), exports); __exportStar(require("./constants/values"), exports); /** * Build CSP header value from params */ function getCSP(params = {}) { const { directives = {}, presets = {}, reportUri } = params; const presetsList = normalizePresetsList(presets); const mergedPolicies = applyPresets(directives, presetsList); return policyToString(mergedPolicies, reportUri); } /** * Build CSP nonce string */ function nonce(nonceKey) { return `'nonce-${nonceKey}'`; } /** * Build CSP header value from resolved policy */ function policyToString(directives, reportUri) { const cspStringParts = []; for (const directiveName in directives) { if (!directives.hasOwnProperty(directiveName)) { continue; } const directiveValue = directives[directiveName]; if (!directiveValue) { continue; } const directiveRulesString = getDirectiveString(directiveName, directiveValue); if (directiveRulesString) { cspStringParts.push(directiveRulesString); } } if (reportUri) { cspStringParts.push(getReportUriDirective(reportUri)); } return cspStringParts.join(' '); } /** * Build directive rules part of CSP header value */ function getDirectiveString(directiveName, directiveValue) { if (typeof directiveValue === 'boolean') { return `${directiveName};`; } if (typeof directiveValue === 'string') { return `${directiveName} ${directiveValue};`; } if (Array.isArray(directiveValue)) { const valueString = directiveValue.join(' '); return `${directiveName} ${valueString};`; } return ''; } /** * Build report-uri directive */ function getReportUriDirective(reportUri) { return `report-uri ${reportUri};`; } /** * Normalize different presets list formats to array format */ function normalizePresetsList(presets) { return Array.isArray(presets) ? presets : Object.values(presets); } /** * Merges presets to policy */ function applyPresets(directives, presets) { const mergedPolicies = {}; for (const preset of [directives, ...presets]) { for (const directiveName in preset) { if (!(directiveName in directives_1.ALLOWED_DIRECTIVES)) { continue; } const currentRules = mergedPolicies[directiveName]; const presetRules = preset[directiveName]; if (presetRules === undefined) { continue; } mergedPolicies[directiveName] = mergeDirectiveRules(currentRules, presetRules); } } return mergedPolicies; } function mergeDirectiveRules(directiveValue1 = '', directiveValue2 = '') { if (directiveValue1 === undefined) { return directiveValue2; } if (directiveValue2 === undefined) { return directiveValue1; } if (Array.isArray(directiveValue1) && Array.isArray(directiveValue2)) { const uniqRules = getUniqRules([ ...directiveValue1, ...directiveValue2 ]); const noneIndex = uniqRules.indexOf(values_1.NONE); // Remove "'none'" if there are other rules if (noneIndex >= 0 && uniqRules.length > 1) { uniqRules.splice(noneIndex, 1); } return uniqRules; } return directiveValue2; } function getUniqRules(rules) { return Array.from(new Set(rules)); } //# sourceMappingURL=index.js.map