forked from papyrs/papyrs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild-csp.mjs
53 lines (41 loc) · 1.39 KB
/
build-csp.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env node
import {createHash} from 'crypto';
import {lstatSync, readdirSync} from 'fs';
import {readFile, writeFile} from 'fs/promises';
import {extname, join} from 'path';
export const findEntryPoints = (dir, files) => {
readdirSync(dir).forEach((file) => {
const fullPath = join(dir, file);
if (lstatSync(fullPath).isDirectory()) {
findEntryPoints(fullPath, files);
} else {
files.push(fullPath);
}
});
};
const entryPoints = [];
findEntryPoints('build', entryPoints);
const htmlEntryPoints = entryPoints.filter((entry) => ['.html'].includes(extname(entry)));
const computeHashes = (indexHtml) => {
const sw = /<script[\s\S]*?>([\s\S]*?)<\/script>/gm;
const scriptHashes = [];
let m;
while ((m = sw.exec(indexHtml))) {
const content = m[1];
scriptHashes.push(`'sha256-${createHash('sha256').update(content).digest('base64')}'`);
}
return scriptHashes;
};
const writeCSP = async ({scriptHashes, indexHtml, entry}) =>
writeFile(
entry,
indexHtml.replace('{{EXTRA_SHAS}}', scriptHashes.map((sha256) => sha256).join(' ')),
'utf-8'
);
const updateCSP = async (entry) => {
const indexHtml = await readFile(join(process.cwd(), entry), 'utf-8');
const scriptHashes = await computeHashes(indexHtml);
await writeCSP({scriptHashes, indexHtml, entry});
};
const promises = htmlEntryPoints.map(updateCSP);
await Promise.all(promises);