import { createHash } from 'node:crypto'; import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const BUILD_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'build'); const scriptRe = /]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/gi; function* walk(dir) { for (const entry of readdirSync(dir)) { const path = join(dir, entry); if (statSync(path).isDirectory()) yield* walk(path); else if (entry.endsWith('.html')) yield path; } } let pages = 0; for (const file of walk(BUILD_DIR)) { const html = readFileSync(file, 'utf8'); const hashes = new Set(); for (const match of html.matchAll(scriptRe)) { const content = match[1]; if (!content.trim()) continue; hashes.add(`'sha256-${createHash('sha256').update(content).digest('base64')}'`); } if (hashes.size === 0) continue; const csp = `default-src 'self'; script-src 'self' ${[...hashes].join(' ')}`; const meta = ``; const anchor = html.match(//); if (!anchor) { console.warn(`[csp] pas d'ancre charset dans ${file}, page ignorée`); continue; } writeFileSync(file, html.replace(anchor[0], `${anchor[0]}\n\t\t${meta}`)); pages++; } console.log(`[csp] meta CSP injectée dans ${pages} page(s)`);