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 ?? '')); } 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*]/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'"; }