import { createHash } from "node:crypto";
//#region src/gateway/security/csp.ts
/**
* Compute SHA-256 CSP hashes for inline `<script>` blocks in an HTML string.
* Only scripts without a `src` attribute are considered inline.
*/
function computeInlineScriptHashes(html) {
	const hashes = [];
	const scriptRegex = /<script(?:\s[^>]*)?>([^]*?)<\/script>/gi;
	let match;
	while ((match = scriptRegex.exec(html)) !== null) {
		if (hasSrcAttribute(match[0].slice(0, match[0].indexOf(">") + 1))) continue;
		const content = match[1];
		if (!content) continue;
		const hash = createHash("sha256").update(content, "utf8").digest("base64");
		hashes.push(`sha256-${hash}`);
	}
	return hashes;
}
const ATTRIBUTE_NAME_REGEX = /\s([^\s=/>]+)(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?/g;
function hasSrcAttribute(openTag) {
	return Array.from(openTag.matchAll(ATTRIBUTE_NAME_REGEX)).some((attrMatch) => attrMatch[1]?.toLowerCase() === "src");
}
/**
* Build a Content-Security-Policy header string.
*
* For the gateway console, we use:
* - `script-src 'self'` + optional SHA-256 hashes for inline scripts (no unsafe-inline)
* - `style-src 'self' 'unsafe-inline'` (Tailwind + runtime style injection)
* - `media-src 'self' blob:` (chat voice previews / recorded clips use blob URLs)
* - `frame-ancestors 'none'` (prevent clickjacking)
* - `base-uri 'none'` (prevent base tag hijacking)
* - `object-src 'none'` (prevent plugin execution)
*/
function buildGatewayConsoleCspHeader(options) {
	const hashes = options?.inlineScriptHashes;
	return [
		"default-src 'self'",
		"base-uri 'none'",
		"object-src 'none'",
		"frame-ancestors 'none'",
		hashes?.length ? `script-src 'self' ${hashes.map((hash) => `'${hash}'`).join(" ")}` : "script-src 'self'",
		"style-src 'self' 'unsafe-inline'",
		"img-src 'self' data: blob: https:",
		"media-src 'self' blob: data:",
		"font-src 'self'",
		`connect-src ${options?.connectSrc ?? "'self' ws: wss:"}`,
		"worker-src 'self'"
	].join("; ");
}
//#endregion
export { buildGatewayConsoleCspHeader, computeInlineScriptHashes };

//# sourceMappingURL=csp.js.map