From 5b9823298e04b36c954bd207d2e6e0d19b80c5c7 Mon Sep 17 00:00:00 2001 From: Jon Bake Date: Wed, 29 Jun 2022 20:15:52 -0500 Subject: [PATCH 1/2] fix #783: Add sub-resource integrity (SRI) hash to all CDN resources Also update update-monaco script to update SRI integrity hash when performing a monaco upgrade. --- .github/workflows/update-monaco-editor.yml | 5 +++- bin/update-monaco | 12 -------- bin/update-monaco.js | 32 ++++++++++++++++++++++ src/app.html | 13 +++++---- 4 files changed, 43 insertions(+), 19 deletions(-) delete mode 100755 bin/update-monaco create mode 100755 bin/update-monaco.js diff --git a/.github/workflows/update-monaco-editor.yml b/.github/workflows/update-monaco-editor.yml index 646aa98f..6d36aa63 100644 --- a/.github/workflows/update-monaco-editor.yml +++ b/.github/workflows/update-monaco-editor.yml @@ -10,7 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - run: ./bin/update-monaco + - uses: actions/setup-node@v2 + with: + node-version: 18 + - run: node ./bin/update-monaco.js - name: Commit changes uses: EndBug/add-and-commit@v9 with: diff --git a/bin/update-monaco b/bin/update-monaco deleted file mode 100755 index dbddd571..00000000 --- a/bin/update-monaco +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -monacoVersion="$(jq -r '.dependencies."monaco-editor"' package.json)" -monacoVersion="${monacoVersion:1}" - -if [[ $(uname) == "Darwin" ]]; -then - sed -i '' -E "s/monaco-editor\/[^/]*/monaco-editor\/$monacoVersion/g" ./src/app.html -else - sed -i'' -E "s/monaco-editor\/[^/]*/monaco-editor\/$monacoVersion/g" ./src/app.html -fi - diff --git a/bin/update-monaco.js b/bin/update-monaco.js new file mode 100755 index 00000000..867bcf75 --- /dev/null +++ b/bin/update-monaco.js @@ -0,0 +1,32 @@ +import fs from 'fs'; +import path from 'path'; + +// parse monaco version out of package.json +const packageJson = JSON.parse(fs.readFileSync('package.json')); +const monacoVersion = packageJson.dependencies['monaco-editor'].substring(1); + +// fetch monaco sri info from cdnjs api +const cdnjsAPIResp = await fetch( + `https://api.cdnjs.com/libraries/monaco-editor/${monacoVersion}?fields=sri` +); +if (cdnjsAPIResp.ok) { + const respJson = await cdnjsAPIResp.json(); + + let appHtml = fs.readFileSync(path.join('src', 'app.html'), 'utf8'); + // update monaco version of every asset in app.html + appHtml = appHtml.replaceAll(/[0-9.]+\/min\/vs/g, `${monacoVersion}/min/vs`); + // update sri integrity value for each asset + for (let monacoAssetMatch of appHtml.matchAll(/min\/vs\/[^"]+/g)) { + let monacoAsset = monacoAssetMatch[0]; + appHtml = appHtml.replace( + new RegExp( + monacoAsset.replaceAll('/', '\\/').replaceAll('.', '\\.') + '" integrity=".+"', + 'g' + ), + `${monacoAsset}" integrity="${respJson.sri[monacoAsset]}"` + ); + } + fs.writeFileSync(path.join('src', 'app.html'), appHtml); +} else { + throw Error('Unable to fetch monaco sri data from cdnjs api.'); +} diff --git a/src/app.html b/src/app.html index e6054088..60805ef4 100644 --- a/src/app.html +++ b/src/app.html @@ -15,10 +15,12 @@ + href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" + crossorigin="anonymous" + referrerpolicy="no-referrer" /> - %sveltekit.head% From d7388b0ccb6bae91e3bc2f5e264802fde799aad1 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Fri, 8 Jul 2022 13:44:16 +0530 Subject: [PATCH 2/2] Use 'node-html-parser' --- bin/update-monaco.js | 45 ++++++++++++++++++++++++++++---------------- package.json | 2 +- src/app.html | 19 +++++++++++++------ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/bin/update-monaco.js b/bin/update-monaco.js index 867bcf75..3d81bdfc 100755 --- a/bin/update-monaco.js +++ b/bin/update-monaco.js @@ -1,9 +1,11 @@ import fs from 'fs'; import path from 'path'; +import { parse } from 'node-html-parser'; +import prettier from 'prettier'; // parse monaco version out of package.json const packageJson = JSON.parse(fs.readFileSync('package.json')); -const monacoVersion = packageJson.dependencies['monaco-editor'].substring(1); +const monacoVersion = packageJson.dependencies['monaco-editor'].replace('^', ''); // fetch monaco sri info from cdnjs api const cdnjsAPIResp = await fetch( @@ -11,22 +13,33 @@ const cdnjsAPIResp = await fetch( ); if (cdnjsAPIResp.ok) { const respJson = await cdnjsAPIResp.json(); + const htmlPath = path.join('src', 'app.html'); + const appHtml = fs + .readFileSync(htmlPath, 'utf8') + // update monaco version of every asset in app.html + .replaceAll(/[0-9.]+\/min\/vs/g, `${monacoVersion}/min/vs`); + const root = parse(appHtml); + const updateIntegrity = (tag, attr) => { + for (const node of root + .getElementsByTagName(tag) + .filter((node) => node.getAttribute(attr)?.includes('monaco-editor'))) { + const file = node.getAttribute(attr).split(`${monacoVersion}/`)[1]; + node.setAttribute('integrity', respJson.sri[file]); + } + }; - let appHtml = fs.readFileSync(path.join('src', 'app.html'), 'utf8'); - // update monaco version of every asset in app.html - appHtml = appHtml.replaceAll(/[0-9.]+\/min\/vs/g, `${monacoVersion}/min/vs`); - // update sri integrity value for each asset - for (let monacoAssetMatch of appHtml.matchAll(/min\/vs\/[^"]+/g)) { - let monacoAsset = monacoAssetMatch[0]; - appHtml = appHtml.replace( - new RegExp( - monacoAsset.replaceAll('/', '\\/').replaceAll('.', '\\.') + '" integrity=".+"', - 'g' - ), - `${monacoAsset}" integrity="${respJson.sri[monacoAsset]}"` - ); - } - fs.writeFileSync(path.join('src', 'app.html'), appHtml); + updateIntegrity('script', 'src'); + updateIntegrity('link', 'href'); + + fs.writeFileSync( + htmlPath, + prettier.format(root.toString(), { + singleQuote: false, + parser: 'html', + bracketSameLine: true, + useTabs: true + }) + ); } else { throw Error('Unable to fetch monaco sri data from cdnjs api.'); } diff --git a/package.json b/package.json index 3ff87837..86147fc4 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ ] }, "volta": { - "node": "16.15.0", + "node": "18.5.0", "yarn": "1.22.10" }, "engines": { diff --git a/src/app.html b/src/app.html index 60805ef4..38b8fb45 100644 --- a/src/app.html +++ b/src/app.html @@ -15,29 +15,36 @@ %sveltekit.head%