Skip to content

Commit

Permalink
Clean the output when useJWT=true (#756)
Browse files Browse the repository at this point in the history
Remove the apiKey from the build output when useJWT=true

The apiKey needs to be removed in the templatedataformatter and in the JAMBO_INJECTED_DATA that weback puts in the bundles.

J=J=SLAP-1118
TEST=manual, auto

When useJWT is true, run a build and search for the apiKey and confirm that it does not appear anywhere in the build output. Test this with JAMBO_INJECTED_DATA which contains apiKeys. Smoke test the JWT integration and the standard integration. Add unit test.
  • Loading branch information
cea2aj authored May 7, 2021
1 parent abea750 commit 2cea8e5
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
26 changes: 26 additions & 0 deletions hooks/templatedataformatter.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const getCleanedJamboInjectedData = require('../static/webpack/getCleanedJamboInjectedData');

/**
* Formats the data sent to the handlebars templates during Jambo builds.
*
Expand Down Expand Up @@ -26,6 +28,9 @@ module.exports = function (pageMetadata, siteLevelAttributes, pageNameToConfig)
JAMBO_INJECTED_DATA: env.JAMBO_INJECTED_DATA
}
};
if (globalConfig.useJWT) {
return getCleanedTemplateData(templateData);
}
return templateData;
}

Expand All @@ -50,4 +55,25 @@ function getLocalizedGlobalConfig(globalConfig, currentLocaleConfig, locale) {
localizedGlobalConfig.locale = locale;
}
return localizedGlobalConfig;
}

/**
* Returns the provided template data without the API Key
*
* @param {Object} templateData
* @returns {Object}
*/
function getCleanedTemplateData(templateData) {
const jamboInjectedData = templateData.env.JAMBO_INJECTED_DATA;
const globalConfig = templateData.global_config;
return {
...templateData,
global_config: {
...globalConfig,
apiKey: undefined
},
env: {
JAMBO_INJECTED_DATA: getCleanedJamboInjectedData(jamboInjectedData)
}
}
}
23 changes: 21 additions & 2 deletions static/webpack-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlPlugin = require('html-webpack-plugin');
const RemovePlugin = require('remove-files-webpack-plugin');
const { merge } = require('webpack-merge');
const { parse } = require('comment-json');

module.exports = function () {
const jamboConfig = require('./jambo.json');
Expand All @@ -25,11 +26,29 @@ module.exports = function () {
});
}

const globalConfigPath = `./${jamboConfig.dirs.config}/global_config.json`;
let globalConfig = {};
if (fs.existsSync(globalConfigPath)) {
globalConfigRaw = fs.readFileSync(globalConfigPath, 'utf-8');
globalConfig = parse(globalConfigRaw);
}

const { useJWT } = globalConfig;

let jamboInjectedData = process.env.JAMBO_INJECTED_DATA || null;
if (useJWT && jamboInjectedData) {
const getCleanedJamboInjectedData =
require(`./${jamboConfig.dirs.output}/static/webpack/getCleanedJamboInjectedData.js`);
jamboInjectedData = JSON.parse(jamboInjectedData)
jamboInjectedData = getCleanedJamboInjectedData(jamboInjectedData)
jamboInjectedData = JSON.stringify(jamboInjectedData)
}

const plugins = [
new MiniCssExtractPlugin({ filename: '[name].css' }),
...htmlPlugins,
new webpack.EnvironmentPlugin({
JAMBO_INJECTED_DATA: null
new webpack.DefinePlugin({
'process.env.JAMBO_INJECTED_DATA': JSON.stringify(jamboInjectedData)
}),
new RemovePlugin({
after: {
Expand Down
31 changes: 31 additions & 0 deletions static/webpack/getCleanedJamboInjectedData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const _ = require('lodash');

/**
* Returns JAMBO_INJECTED_DATA with instances of the global config's apiKey removed
*
* @param {Object} data JAMBO_INJECTED_DATA
* @returns {Object}
*/
function getCleanedJamboInjectedData (data) {
if (!data || !data.answers || !data.answers.experiences) {
return;
}
const updatedData = _.cloneDeep(data);
const experiences = updatedData.answers.experiences;

const removeApiKeyFromConfig = config => {
if ('apiKey' in config) {
delete config['apiKey'];
}
}

Object.values(experiences).forEach(config => {
removeApiKeyFromConfig(config);
if ('configByLabel' in config) {
Object.values(config.configByLabel).forEach(removeApiKeyFromConfig);
}
});
return updatedData;
}

module.exports = getCleanedJamboInjectedData;
34 changes: 34 additions & 0 deletions tests/static/webpack/getCleanedJamboInjectedData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import getCleanedJamboInjectedData from '../../../static/webpack/getCleanedJamboInjectedData';

describe('secures the injected data', () => {
const sampleConfig = {
apiKey: 999,
verticals: {
KM: {
displayName: 'Locations',
source: 'KNOWLEDGE_MANAGER'
}
}
};

const mockInjectedData = {
businessId: 999,
answers: {
experiences: {
test_experience: {
...sampleConfig,
configByLabel: {
PRODUCTION: sampleConfig,
STAGING: sampleConfig
}
}
}
}
};

it('removes instances of the apiKey', () => {
const securedInjectedData = getCleanedJamboInjectedData(mockInjectedData);
expect(securedInjectedData).toEqual(expect.not.objectContaining({apiKey: 999}));
});
});

0 comments on commit 2cea8e5

Please sign in to comment.