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 /]*\bsrc\s*=/i.test(String(html ?? '')); } export function publishedPageCsp( html, { embed = false, raw = false, wechatShare = false, scriptHashes = [] } = {}, ) { const isFullHtml = /^\s*]/i.test(html); if (embed && isFullHtml) { return publishedPageCspForEmbed(true); } if (wechatShare && isFullHtml) { 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 'unsafe-inline' https://res.wx.qq.com"; } if (raw && isFullHtml) { const scriptSrc = scriptSrcDirective({ inline: true, urls: htmlUsesExternalScriptSrc(html) ? ["'self'"] : [], }); 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'; ${scriptSrc}`; } if (isFullHtml) { 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'; ${scriptSrcDirective({ hashes: scriptHashes, urls: htmlUsesExternalScriptSrc(html) ? ["'self'"] : [], })}`; } 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'"; }