diff --git a/__tests__/config/webpack.js b/__tests__/config/webpack.js new file mode 100644 index 000000000..262e850ff --- /dev/null +++ b/__tests__/config/webpack.js @@ -0,0 +1,37 @@ +/* eslint-env jest */ + +const crypto = require('crypto'); +const fs = require('fs'); +const forge = require('node-forge'); + +jest.unmock('webpack'); + +const createWebpackConfig = require('../../config/webpack/create'); + +describe('webpack build information', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('generates a raw 32-byte key accepted by the renderer cipher', () => { + const bytes = [ + 0, 10, 13, 34, 92, 255, + ...Array.from({ length: 26 }, (_, index) => index + 128), + ]; + jest.spyOn(crypto, 'randomBytes').mockReturnValue(Buffer.from(bytes)); + const writeFile = jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {}); + + const webpackConfig = createWebpackConfig('production'); + + const buildInfo = JSON.parse(writeFile.mock.calls[0][1]); + const definePlugin = webpackConfig.plugins.find(plugin => ( + plugin.definitions && plugin.definitions.BUILD_INFO + )); + const clientBuildInfo = JSON.parse(definePlugin.definitions.BUILD_INFO); + expect(buildInfo.key).toHaveLength(32); + expect([...buildInfo.key].map(character => character.charCodeAt(0))).toEqual(bytes); + expect(clientBuildInfo.key).toBe(buildInfo.key); + expect(() => forge.cipher.createCipher('AES-CBC', buildInfo.key)).not.toThrow(); + expect(() => forge.cipher.createDecipher('AES-CBC', clientBuildInfo.key)).not.toThrow(); + }); +}); diff --git a/config/webpack/create.js b/config/webpack/create.js index 2798b2b42..a5b8c2e02 100644 --- a/config/webpack/create.js +++ b/config/webpack/create.js @@ -44,7 +44,7 @@ function getBuildInfo(publicPath, keepExisting) { } const info = { - key: crypto.randomBytes(32).toString('base64url'), + key: crypto.randomBytes(32).toString('latin1'), publicPath, timestamp: new Date().toISOString(), crossOriginLoading: 'anonymous',