From 43f3975c20d77d6473b00e646194f72e9124ce75 Mon Sep 17 00:00:00 2001 From: naugtur Date: Wed, 13 Mar 2024 11:43:41 +0100 Subject: [PATCH 1/5] feat(webpack): ability to inline lockdown --- packages/webpack/src/buildtime/emitSes.js | 79 ++++++++++++++----- packages/webpack/src/plugin.js | 66 ++++++++++------ packages/webpack/src/types.js | 2 + .../webpack/test/e2e-lockdown-inline.spec.js | 29 +++++++ 4 files changed, 133 insertions(+), 43 deletions(-) create mode 100644 packages/webpack/test/e2e-lockdown-inline.spec.js diff --git a/packages/webpack/src/buildtime/emitSes.js b/packages/webpack/src/buildtime/emitSes.js index 43e0190798..f99f8d658e 100644 --- a/packages/webpack/src/buildtime/emitSes.js +++ b/packages/webpack/src/buildtime/emitSes.js @@ -1,40 +1,79 @@ const { readFileSync } = require('node:fs') +const path = require('node:path') const { - sources: { RawSource }, + sources: { RawSource, ConcatSource }, } = require('webpack') +const lockdownSource = readFileSync( + path.join(require.resolve('ses'), '../lockdown.umd.min.js'), + 'utf-8' +) +const lockdownSourcePrefix = `;(function(){\n${lockdownSource}\n})();\n` + module.exports = { + /** + * @param {object} options + * @param {import('webpack').Compilation} options.compilation + * @param {string[]} options.inlineLockdown + * @returns {() => void} + */ + sesPrefixFiles: + ({ compilation, inlineLockdown: files }) => + () => { + files.forEach((file) => { + const asset = compilation.assets[file] + if (!asset) { + throw new Error( + `LavaMoatPlugin: file specified in inlineLockdown not found in compilation: ${file}` + ) + } + compilation.assets[file] = new ConcatSource(lockdownSourcePrefix, asset) + }) + }, + /** + * @param {object} options + * @param {import('webpack').Compilation} options.compilation + * @param {import('webpack').WebpackPluginInstance} [options.HtmlWebpackPluginInUse] + * @param {boolean} [options.HtmlWebpackPluginInterop] + * @returns {() => void} + */ sesEmitHook: ({ compilation, HtmlWebpackPluginInUse, HtmlWebpackPluginInterop }) => () => { - const sesFile = readFileSync(require.resolve('ses'), 'utf-8') // TODO: to consider: instead manually copy to compiler.options.output.path - const asset = new RawSource(sesFile) + const asset = new RawSource(lockdownSource) compilation.emitAsset('lockdown', asset) if (HtmlWebpackPluginInUse && HtmlWebpackPluginInterop) { HtmlWebpackPluginInUse.constructor + // @ts-expect-error - incomplete types .getHooks(compilation) - .beforeEmit.tapAsync('LavaMoatWebpackPlugin-lockdown', (data, cb) => { - const scriptTag = '' - const headTagRegex = /]*>/iu - const scriptTagRegex = /' + const headTagRegex = /]*>/iu + const scriptTagRegex = /