Aktueller Stand
This commit is contained in:
190
backend/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js
generated
vendored
Normal file
190
backend/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var secure_headers_exports = {};
|
||||
__export(secure_headers_exports, {
|
||||
NONCE: () => NONCE,
|
||||
secureHeaders: () => secureHeaders
|
||||
});
|
||||
module.exports = __toCommonJS(secure_headers_exports);
|
||||
var import_encode = require("../../utils/encode");
|
||||
const HEADERS_MAP = {
|
||||
crossOriginEmbedderPolicy: ["Cross-Origin-Embedder-Policy", "require-corp"],
|
||||
crossOriginResourcePolicy: ["Cross-Origin-Resource-Policy", "same-origin"],
|
||||
crossOriginOpenerPolicy: ["Cross-Origin-Opener-Policy", "same-origin"],
|
||||
originAgentCluster: ["Origin-Agent-Cluster", "?1"],
|
||||
referrerPolicy: ["Referrer-Policy", "no-referrer"],
|
||||
strictTransportSecurity: ["Strict-Transport-Security", "max-age=15552000; includeSubDomains"],
|
||||
xContentTypeOptions: ["X-Content-Type-Options", "nosniff"],
|
||||
xDnsPrefetchControl: ["X-DNS-Prefetch-Control", "off"],
|
||||
xDownloadOptions: ["X-Download-Options", "noopen"],
|
||||
xFrameOptions: ["X-Frame-Options", "SAMEORIGIN"],
|
||||
xPermittedCrossDomainPolicies: ["X-Permitted-Cross-Domain-Policies", "none"],
|
||||
xXssProtection: ["X-XSS-Protection", "0"]
|
||||
};
|
||||
const DEFAULT_OPTIONS = {
|
||||
crossOriginEmbedderPolicy: false,
|
||||
crossOriginResourcePolicy: true,
|
||||
crossOriginOpenerPolicy: true,
|
||||
originAgentCluster: true,
|
||||
referrerPolicy: true,
|
||||
strictTransportSecurity: true,
|
||||
xContentTypeOptions: true,
|
||||
xDnsPrefetchControl: true,
|
||||
xDownloadOptions: true,
|
||||
xFrameOptions: true,
|
||||
xPermittedCrossDomainPolicies: true,
|
||||
xXssProtection: true,
|
||||
removePoweredBy: true,
|
||||
permissionsPolicy: {}
|
||||
};
|
||||
const generateNonce = () => {
|
||||
const arrayBuffer = new Uint8Array(16);
|
||||
crypto.getRandomValues(arrayBuffer);
|
||||
return (0, import_encode.encodeBase64)(arrayBuffer.buffer);
|
||||
};
|
||||
const NONCE = (ctx) => {
|
||||
const key = "secureHeadersNonce";
|
||||
const init = ctx.get(key);
|
||||
const nonce = init || generateNonce();
|
||||
if (init == null) {
|
||||
ctx.set(key, nonce);
|
||||
}
|
||||
return `'nonce-${nonce}'`;
|
||||
};
|
||||
const secureHeaders = (customOptions) => {
|
||||
const options = { ...DEFAULT_OPTIONS, ...customOptions };
|
||||
const headersToSet = getFilteredHeaders(options);
|
||||
const callbacks = [];
|
||||
if (options.contentSecurityPolicy) {
|
||||
const [callback, value] = getCSPDirectives(options.contentSecurityPolicy);
|
||||
if (callback) {
|
||||
callbacks.push(callback);
|
||||
}
|
||||
headersToSet.push(["Content-Security-Policy", value]);
|
||||
}
|
||||
if (options.contentSecurityPolicyReportOnly) {
|
||||
const [callback, value] = getCSPDirectives(options.contentSecurityPolicyReportOnly);
|
||||
if (callback) {
|
||||
callbacks.push(callback);
|
||||
}
|
||||
headersToSet.push(["Content-Security-Policy-Report-Only", value]);
|
||||
}
|
||||
if (options.permissionsPolicy && Object.keys(options.permissionsPolicy).length > 0) {
|
||||
headersToSet.push([
|
||||
"Permissions-Policy",
|
||||
getPermissionsPolicyDirectives(options.permissionsPolicy)
|
||||
]);
|
||||
}
|
||||
if (options.reportingEndpoints) {
|
||||
headersToSet.push(["Reporting-Endpoints", getReportingEndpoints(options.reportingEndpoints)]);
|
||||
}
|
||||
if (options.reportTo) {
|
||||
headersToSet.push(["Report-To", getReportToOptions(options.reportTo)]);
|
||||
}
|
||||
return async function secureHeaders2(ctx, next) {
|
||||
const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
|
||||
await next();
|
||||
setHeaders(ctx, headersToSetForReq);
|
||||
if (options?.removePoweredBy) {
|
||||
ctx.res.headers.delete("X-Powered-By");
|
||||
}
|
||||
};
|
||||
};
|
||||
function getFilteredHeaders(options) {
|
||||
return Object.entries(HEADERS_MAP).filter(([key]) => options[key]).map(([key, defaultValue]) => {
|
||||
const overrideValue = options[key];
|
||||
return typeof overrideValue === "string" ? [defaultValue[0], overrideValue] : defaultValue;
|
||||
});
|
||||
}
|
||||
function getCSPDirectives(contentSecurityPolicy) {
|
||||
const callbacks = [];
|
||||
const resultValues = [];
|
||||
for (const [directive, value] of Object.entries(contentSecurityPolicy)) {
|
||||
const valueArray = Array.isArray(value) ? value : [value];
|
||||
valueArray.forEach((value2, i) => {
|
||||
if (typeof value2 === "function") {
|
||||
const index = i * 2 + 2 + resultValues.length;
|
||||
callbacks.push((ctx, values) => {
|
||||
values[index] = value2(ctx, directive);
|
||||
});
|
||||
}
|
||||
});
|
||||
resultValues.push(
|
||||
directive.replace(
|
||||
/[A-Z]+(?![a-z])|[A-Z]/g,
|
||||
(match, offset) => offset ? "-" + match.toLowerCase() : match.toLowerCase()
|
||||
),
|
||||
...valueArray.flatMap((value2) => [" ", value2]),
|
||||
"; "
|
||||
);
|
||||
}
|
||||
resultValues.pop();
|
||||
return callbacks.length === 0 ? [void 0, resultValues.join("")] : [
|
||||
(ctx, headersToSet) => headersToSet.map((values) => {
|
||||
if (values[0] === "Content-Security-Policy" || values[0] === "Content-Security-Policy-Report-Only") {
|
||||
const clone = values[1].slice();
|
||||
callbacks.forEach((cb) => {
|
||||
cb(ctx, clone);
|
||||
});
|
||||
return [values[0], clone.join("")];
|
||||
} else {
|
||||
return values;
|
||||
}
|
||||
}),
|
||||
resultValues
|
||||
];
|
||||
}
|
||||
function getPermissionsPolicyDirectives(policy) {
|
||||
return Object.entries(policy).map(([directive, value]) => {
|
||||
const kebabDirective = camelToKebab(directive);
|
||||
if (typeof value === "boolean") {
|
||||
return `${kebabDirective}=${value ? "*" : "none"}`;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
if (value.length === 0) {
|
||||
return `${kebabDirective}=()`;
|
||||
}
|
||||
if (value.length === 1 && (value[0] === "*" || value[0] === "none")) {
|
||||
return `${kebabDirective}=${value[0]}`;
|
||||
}
|
||||
const allowlist = value.map((item) => ["self", "src"].includes(item) ? item : `"${item}"`);
|
||||
return `${kebabDirective}=(${allowlist.join(" ")})`;
|
||||
}
|
||||
return "";
|
||||
}).filter(Boolean).join(", ");
|
||||
}
|
||||
function camelToKebab(str) {
|
||||
return str.replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
|
||||
}
|
||||
function getReportingEndpoints(reportingEndpoints = []) {
|
||||
return reportingEndpoints.map((endpoint) => `${endpoint.name}="${endpoint.url}"`).join(", ");
|
||||
}
|
||||
function getReportToOptions(reportTo = []) {
|
||||
return reportTo.map((option) => JSON.stringify(option)).join(", ");
|
||||
}
|
||||
function setHeaders(ctx, headersToSet) {
|
||||
headersToSet.forEach(([header, value]) => {
|
||||
ctx.res.headers.set(header, value);
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
NONCE,
|
||||
secureHeaders
|
||||
});
|
||||
Reference in New Issue
Block a user