ae9090948a
Switch default MindSpace HTML delivery to a hybrid inline CSP so onclick handlers and addEventListener pages both run under real HTTP headers, and add Playwright interaction verify beyond HTTP 200 checks. Co-authored-by: Cursor <cursoragent@cursor.com>
53 lines
1.7 KiB
JavaScript
53 lines
1.7 KiB
JavaScript
import { publishedPageCspForEmbed } from './plaza-embed.mjs';
|
|
|
|
export function scriptSrcDirective({ inline = false, urls = [], hashes = [] } = {}) {
|
|
const parts = [];
|
|
if (inline) parts.push("'unsafe-inline'");
|
|
for (const hash of hashes) parts.push(`'sha256-${hash}'`);
|
|
for (const url of urls) parts.push(url);
|
|
return parts.length ? `script-src ${parts.join(' ')}` : "script-src 'none'";
|
|
}
|
|
|
|
export function htmlUsesExternalScriptSrc(html) {
|
|
return /<script\b[^>]*\bsrc\s*=/i.test(String(html ?? ''));
|
|
}
|
|
|
|
function buildHybridPublishedPageCsp(html, { extraScriptUrls = [] } = {}) {
|
|
const scriptSrc = scriptSrcDirective({
|
|
inline: true,
|
|
urls: [
|
|
...(htmlUsesExternalScriptSrc(html) ? ["'self'"] : []),
|
|
...extraScriptUrls,
|
|
],
|
|
});
|
|
return [
|
|
"default-src 'none'",
|
|
"style-src 'unsafe-inline' https:",
|
|
"img-src 'self' data: http: https:",
|
|
"font-src 'self' https: data:",
|
|
"connect-src 'self'",
|
|
"base-uri 'none'",
|
|
"form-action 'self'",
|
|
"frame-ancestors 'self'",
|
|
"script-src-attr 'unsafe-inline'",
|
|
scriptSrc,
|
|
].join('; ');
|
|
}
|
|
|
|
export function publishedPageCsp(
|
|
html,
|
|
{ embed = false, raw = false, wechatShare = false, scriptHashes = [] } = {},
|
|
) {
|
|
const isFullHtml = /^\s*<!doctype html/i.test(html) || /^\s*<html[\s>]/i.test(html);
|
|
if (embed && isFullHtml) {
|
|
return publishedPageCspForEmbed(true);
|
|
}
|
|
if (wechatShare && isFullHtml) {
|
|
return buildHybridPublishedPageCsp(html, { extraScriptUrls: ['https://res.wx.qq.com'] });
|
|
}
|
|
if ((raw || isFullHtml) && isFullHtml) {
|
|
return buildHybridPublishedPageCsp(html);
|
|
}
|
|
return "default-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src 'none'; connect-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'self'";
|
|
}
|