@commercetools-frontend/mc-html-template 25.0.0 → 25.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commercetools-frontend-mc-html-template.cjs.dev.js +21 -24
- package/dist/commercetools-frontend-mc-html-template.cjs.prod.js +21 -24
- package/dist/commercetools-frontend-mc-html-template.esm.js +20 -23
- package/package.json +3 -3
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.dev.js +2 -2
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.prod.js +2 -2
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.esm.js +2 -2
|
@@ -12,8 +12,8 @@ var _Object$assign = require('@babel/runtime-corejs3/core-js-stable/object/assig
|
|
|
12
12
|
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
13
13
|
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
|
14
14
|
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
15
|
-
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
16
15
|
var _trimInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/trim');
|
|
16
|
+
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
17
17
|
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
|
|
18
18
|
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
|
19
19
|
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
|
|
@@ -35,8 +35,8 @@ var _Object$assign__default = /*#__PURE__*/_interopDefault(_Object$assign);
|
|
|
35
35
|
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
36
36
|
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
|
37
37
|
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
38
|
-
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
39
38
|
var _trimInstanceProperty__default = /*#__PURE__*/_interopDefault(_trimInstanceProperty);
|
|
39
|
+
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
40
40
|
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
|
|
41
41
|
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
|
42
42
|
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
|
|
@@ -57,7 +57,7 @@ function createAssetHash(content) {
|
|
|
57
57
|
* CSP headers sent.
|
|
58
58
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
59
59
|
*/
|
|
60
|
-
return
|
|
60
|
+
return `sha256-${sha256Hash}`;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
@@ -65,7 +65,7 @@ const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
68
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
68
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context7, _context8; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context7 = ownKeys(Object(t), !0)).call(_context7, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context8 = ownKeys(Object(t))).call(_context8, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
69
69
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
70
70
|
const htmlScripts$1 = {
|
|
71
71
|
"loadingScreen": "window.onAppLoaded=function(){var e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){var e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){var e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
@@ -82,21 +82,20 @@ const parseCSPDirectives = function () {
|
|
|
82
82
|
return _Object$assign__default["default"](mergedDirectives, _reduceInstanceProperty__default["default"](_context = _Object$keys__default["default"](directive)).call(_context, (mergedDirectiveValues, directiveKey) => {
|
|
83
83
|
const existingDirectiveValue = mergedDirectives[directiveKey];
|
|
84
84
|
return _Object$assign__default["default"](mergedDirectiveValues, {
|
|
85
|
-
[directiveKey]: [...toArray(existingDirectiveValue
|
|
85
|
+
[directiveKey]: [...toArray(existingDirectiveValue ?? []), ...toArray(directive[directiveKey])]
|
|
86
86
|
});
|
|
87
87
|
}, {}));
|
|
88
88
|
}, {});
|
|
89
89
|
return _mapInstanceProperty__default["default"](_context2 = _Object$entries__default["default"](mergedDirectives)).call(_context2, _ref => {
|
|
90
|
-
var _context3;
|
|
91
90
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
92
91
|
directive = _ref2[0],
|
|
93
92
|
value = _ref2[1];
|
|
94
|
-
return
|
|
93
|
+
return `${directive} ${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
95
94
|
}).join('; ');
|
|
96
95
|
};
|
|
97
96
|
const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
98
|
-
var
|
|
99
|
-
const mergedDirectives = _mapInstanceProperty__default["default"](
|
|
97
|
+
var _context3;
|
|
98
|
+
const mergedDirectives = _mapInstanceProperty__default["default"](_context3 = defaultValue.split(',')).call(_context3, directive => {
|
|
100
99
|
const _directive$trim$split = _trimInstanceProperty__default["default"](directive).call(directive).split('='),
|
|
101
100
|
_directive$trim$split2 = _slicedToArray(_directive$trim$split, 2),
|
|
102
101
|
directiveName = _directive$trim$split2[0],
|
|
@@ -110,12 +109,12 @@ const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
|
110
109
|
return mergedDirectives.join(', ');
|
|
111
110
|
};
|
|
112
111
|
const processHeaders = applicationConfig => {
|
|
113
|
-
var _context5, _context6
|
|
112
|
+
var _context4, _context5, _context6;
|
|
114
113
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
115
114
|
|
|
116
115
|
// List hashes for injected inline scripts.
|
|
117
116
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
118
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
117
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
119
118
|
|
|
120
119
|
// // List hashes for injected inline styles.
|
|
121
120
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -127,15 +126,15 @@ const processHeaders = applicationConfig => {
|
|
|
127
126
|
*/
|
|
128
127
|
const defaultCSPDirectives = _Object$assign__default["default"]({
|
|
129
128
|
'default-src': "'none'",
|
|
130
|
-
'script-src': _concatInstanceProperty__default["default"](
|
|
129
|
+
'script-src': _concatInstanceProperty__default["default"](_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
131
130
|
// Allow webpack to load source maps on runtime when errors occur
|
|
132
131
|
// using script tags
|
|
133
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
134
|
-
'connect-src': _concatInstanceProperty__default["default"](
|
|
132
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
133
|
+
'connect-src': _concatInstanceProperty__default["default"](_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
135
134
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
136
|
-
'*.sentry.io']).call(
|
|
135
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
137
136
|
'img-src': ['*', 'data:'],
|
|
138
|
-
'style-src': _concatInstanceProperty__default["default"](
|
|
137
|
+
'style-src': _concatInstanceProperty__default["default"](_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
139
138
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
140
139
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
141
140
|
["'unsafe-inline'"]
|
|
@@ -162,9 +161,9 @@ const processHeaders = applicationConfig => {
|
|
|
162
161
|
return _objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
163
162
|
// The `Content-Security-Policy` header is always generated
|
|
164
163
|
// based on the Merchant Center customization config.
|
|
165
|
-
[constants.HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives,
|
|
166
|
-
},
|
|
167
|
-
[constants.HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(constants.HTTP_SECURITY_HEADERS['Permissions-Policy'],
|
|
164
|
+
[constants.HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives, applicationConfig.headers?.csp ?? {})
|
|
165
|
+
}, applicationConfig.headers?.permissionsPolicies ? {
|
|
166
|
+
[constants.HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(constants.HTTP_SECURITY_HEADERS['Permissions-Policy'], applicationConfig.headers.permissionsPolicies ?? {})
|
|
168
167
|
} : {});
|
|
169
168
|
};
|
|
170
169
|
|
|
@@ -177,11 +176,9 @@ const htmlStyles = {
|
|
|
177
176
|
"loadingScreen": ".loading-screen{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;width:100vw}.loading-screen--hidden{display:none}.loading-screen>*+*{margin:24px 0 0}.loading-spinner{width:32px;height:32px}.long-loading-notice{color:#999;font-family:'Open Sans',sans-serif;font-size:12px}.long-loading-notice--hidden{visibility:hidden}.loading-spinner-circle{fill:#213c45;opacity:.2}@keyframes loading-spinner-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.loading-spinner-pointer{transform-origin:20px 20px 0;animation:loading-spinner-animation .5s infinite linear}"
|
|
178
177
|
};
|
|
179
178
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
180
|
-
const replaceHtmlPlaceholders = (indexHtmlContent, options) =>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
"".concat(trimTrailingSlash(options.env.cdnUrl), "/") : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), "<script>window.app = ".concat(sanitizeAppEnvironment(options.env), ";</script>")).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), "<script>".concat(htmlScripts.loadingScreen, "</script>")).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), "<style>".concat(htmlStyles.loadingScreen, "</style>"));
|
|
184
|
-
};
|
|
179
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
180
|
+
// Ensure there is a trailing slash
|
|
181
|
+
`${trimTrailingSlash(options.env.cdnUrl)}/` : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), `<script>window.app = ${sanitizeAppEnvironment(options.env)};</script>`).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), `<script>${htmlScripts.loadingScreen}</script>`).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), `<style>${htmlStyles.loadingScreen}</style>`);
|
|
185
182
|
|
|
186
183
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
187
184
|
const applicationConfig$1 = await applicationConfig.processConfig();
|
|
@@ -12,8 +12,8 @@ var _Object$assign = require('@babel/runtime-corejs3/core-js-stable/object/assig
|
|
|
12
12
|
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
13
13
|
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
|
14
14
|
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
15
|
-
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
16
15
|
var _trimInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/trim');
|
|
16
|
+
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
17
17
|
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
|
|
18
18
|
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
|
19
19
|
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
|
|
@@ -35,8 +35,8 @@ var _Object$assign__default = /*#__PURE__*/_interopDefault(_Object$assign);
|
|
|
35
35
|
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
36
36
|
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
|
37
37
|
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
38
|
-
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
39
38
|
var _trimInstanceProperty__default = /*#__PURE__*/_interopDefault(_trimInstanceProperty);
|
|
39
|
+
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
40
40
|
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
|
|
41
41
|
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
|
42
42
|
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
|
|
@@ -57,7 +57,7 @@ function createAssetHash(content) {
|
|
|
57
57
|
* CSP headers sent.
|
|
58
58
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
59
59
|
*/
|
|
60
|
-
return
|
|
60
|
+
return `sha256-${sha256Hash}`;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
@@ -65,7 +65,7 @@ const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
68
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
68
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context7, _context8; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context7 = ownKeys(Object(t), !0)).call(_context7, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context8 = ownKeys(Object(t))).call(_context8, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
69
69
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
70
70
|
const htmlScripts$1 = {
|
|
71
71
|
"loadingScreen": "window.onAppLoaded=function(){var e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){var e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){var e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
@@ -82,21 +82,20 @@ const parseCSPDirectives = function () {
|
|
|
82
82
|
return _Object$assign__default["default"](mergedDirectives, _reduceInstanceProperty__default["default"](_context = _Object$keys__default["default"](directive)).call(_context, (mergedDirectiveValues, directiveKey) => {
|
|
83
83
|
const existingDirectiveValue = mergedDirectives[directiveKey];
|
|
84
84
|
return _Object$assign__default["default"](mergedDirectiveValues, {
|
|
85
|
-
[directiveKey]: [...toArray(existingDirectiveValue
|
|
85
|
+
[directiveKey]: [...toArray(existingDirectiveValue ?? []), ...toArray(directive[directiveKey])]
|
|
86
86
|
});
|
|
87
87
|
}, {}));
|
|
88
88
|
}, {});
|
|
89
89
|
return _mapInstanceProperty__default["default"](_context2 = _Object$entries__default["default"](mergedDirectives)).call(_context2, _ref => {
|
|
90
|
-
var _context3;
|
|
91
90
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
92
91
|
directive = _ref2[0],
|
|
93
92
|
value = _ref2[1];
|
|
94
|
-
return
|
|
93
|
+
return `${directive} ${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
95
94
|
}).join('; ');
|
|
96
95
|
};
|
|
97
96
|
const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
98
|
-
var
|
|
99
|
-
const mergedDirectives = _mapInstanceProperty__default["default"](
|
|
97
|
+
var _context3;
|
|
98
|
+
const mergedDirectives = _mapInstanceProperty__default["default"](_context3 = defaultValue.split(',')).call(_context3, directive => {
|
|
100
99
|
const _directive$trim$split = _trimInstanceProperty__default["default"](directive).call(directive).split('='),
|
|
101
100
|
_directive$trim$split2 = _slicedToArray(_directive$trim$split, 2),
|
|
102
101
|
directiveName = _directive$trim$split2[0],
|
|
@@ -110,12 +109,12 @@ const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
|
110
109
|
return mergedDirectives.join(', ');
|
|
111
110
|
};
|
|
112
111
|
const processHeaders = applicationConfig => {
|
|
113
|
-
var _context5, _context6
|
|
112
|
+
var _context4, _context5, _context6;
|
|
114
113
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
115
114
|
|
|
116
115
|
// List hashes for injected inline scripts.
|
|
117
116
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
118
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
117
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
119
118
|
|
|
120
119
|
// // List hashes for injected inline styles.
|
|
121
120
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -127,15 +126,15 @@ const processHeaders = applicationConfig => {
|
|
|
127
126
|
*/
|
|
128
127
|
const defaultCSPDirectives = _Object$assign__default["default"]({
|
|
129
128
|
'default-src': "'none'",
|
|
130
|
-
'script-src': _concatInstanceProperty__default["default"](
|
|
129
|
+
'script-src': _concatInstanceProperty__default["default"](_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
131
130
|
// Allow webpack to load source maps on runtime when errors occur
|
|
132
131
|
// using script tags
|
|
133
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
134
|
-
'connect-src': _concatInstanceProperty__default["default"](
|
|
132
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
133
|
+
'connect-src': _concatInstanceProperty__default["default"](_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
135
134
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
136
|
-
'*.sentry.io']).call(
|
|
135
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
137
136
|
'img-src': ['*', 'data:'],
|
|
138
|
-
'style-src': _concatInstanceProperty__default["default"](
|
|
137
|
+
'style-src': _concatInstanceProperty__default["default"](_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
139
138
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
140
139
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
141
140
|
["'unsafe-inline'"]
|
|
@@ -162,9 +161,9 @@ const processHeaders = applicationConfig => {
|
|
|
162
161
|
return _objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
163
162
|
// The `Content-Security-Policy` header is always generated
|
|
164
163
|
// based on the Merchant Center customization config.
|
|
165
|
-
[constants.HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives,
|
|
166
|
-
},
|
|
167
|
-
[constants.HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(constants.HTTP_SECURITY_HEADERS['Permissions-Policy'],
|
|
164
|
+
[constants.HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives, applicationConfig.headers?.csp ?? {})
|
|
165
|
+
}, applicationConfig.headers?.permissionsPolicies ? {
|
|
166
|
+
[constants.HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(constants.HTTP_SECURITY_HEADERS['Permissions-Policy'], applicationConfig.headers.permissionsPolicies ?? {})
|
|
168
167
|
} : {});
|
|
169
168
|
};
|
|
170
169
|
|
|
@@ -177,11 +176,9 @@ const htmlStyles = {
|
|
|
177
176
|
"loadingScreen": ".loading-screen{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;width:100vw}.loading-screen--hidden{display:none}.loading-screen>*+*{margin:24px 0 0}.loading-spinner{width:32px;height:32px}.long-loading-notice{color:#999;font-family:'Open Sans',sans-serif;font-size:12px}.long-loading-notice--hidden{visibility:hidden}.loading-spinner-circle{fill:#213c45;opacity:.2}@keyframes loading-spinner-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.loading-spinner-pointer{transform-origin:20px 20px 0;animation:loading-spinner-animation .5s infinite linear}"
|
|
178
177
|
};
|
|
179
178
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
180
|
-
const replaceHtmlPlaceholders = (indexHtmlContent, options) =>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
"".concat(trimTrailingSlash(options.env.cdnUrl), "/") : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), "<script>window.app = ".concat(sanitizeAppEnvironment(options.env), ";</script>")).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), "<script>".concat(htmlScripts.loadingScreen, "</script>")).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), "<style>".concat(htmlStyles.loadingScreen, "</style>"));
|
|
184
|
-
};
|
|
179
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
180
|
+
// Ensure there is a trailing slash
|
|
181
|
+
`${trimTrailingSlash(options.env.cdnUrl)}/` : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), `<script>window.app = ${sanitizeAppEnvironment(options.env)};</script>`).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), `<script>${htmlScripts.loadingScreen}</script>`).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), `<style>${htmlStyles.loadingScreen}</style>`);
|
|
185
182
|
|
|
186
183
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
187
184
|
const applicationConfig$1 = await applicationConfig.processConfig();
|
|
@@ -8,8 +8,8 @@ import _Object$assign from '@babel/runtime-corejs3/core-js-stable/object/assign'
|
|
|
8
8
|
import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
|
|
9
9
|
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
|
|
10
10
|
import _Object$entries from '@babel/runtime-corejs3/core-js-stable/object/entries';
|
|
11
|
-
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
|
|
12
11
|
import _trimInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/trim';
|
|
12
|
+
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
|
|
13
13
|
import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
|
|
14
14
|
import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
|
|
15
15
|
import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
|
|
@@ -32,7 +32,7 @@ function createAssetHash(content) {
|
|
|
32
32
|
* CSP headers sent.
|
|
33
33
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
34
34
|
*/
|
|
35
|
-
return
|
|
35
|
+
return `sha256-${sha256Hash}`;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const sanitizeAppEnvironment = env => serialize(env, {
|
|
@@ -40,7 +40,7 @@ const sanitizeAppEnvironment = env => serialize(env, {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
43
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
43
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context7, _context8; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context7 = ownKeys(Object(t), !0)).call(_context7, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context8 = ownKeys(Object(t))).call(_context8, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
44
44
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
45
45
|
const htmlScripts$1 = {
|
|
46
46
|
"loadingScreen": "window.onAppLoaded=function(){var e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){var e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){var e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
@@ -57,21 +57,20 @@ const parseCSPDirectives = function () {
|
|
|
57
57
|
return _Object$assign(mergedDirectives, _reduceInstanceProperty(_context = _Object$keys(directive)).call(_context, (mergedDirectiveValues, directiveKey) => {
|
|
58
58
|
const existingDirectiveValue = mergedDirectives[directiveKey];
|
|
59
59
|
return _Object$assign(mergedDirectiveValues, {
|
|
60
|
-
[directiveKey]: [...toArray(existingDirectiveValue
|
|
60
|
+
[directiveKey]: [...toArray(existingDirectiveValue ?? []), ...toArray(directive[directiveKey])]
|
|
61
61
|
});
|
|
62
62
|
}, {}));
|
|
63
63
|
}, {});
|
|
64
64
|
return _mapInstanceProperty(_context2 = _Object$entries(mergedDirectives)).call(_context2, _ref => {
|
|
65
|
-
var _context3;
|
|
66
65
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
67
66
|
directive = _ref2[0],
|
|
68
67
|
value = _ref2[1];
|
|
69
|
-
return
|
|
68
|
+
return `${directive} ${_Array$isArray(value) ? value.join(' ') : value}`;
|
|
70
69
|
}).join('; ');
|
|
71
70
|
};
|
|
72
71
|
const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
73
|
-
var
|
|
74
|
-
const mergedDirectives = _mapInstanceProperty(
|
|
72
|
+
var _context3;
|
|
73
|
+
const mergedDirectives = _mapInstanceProperty(_context3 = defaultValue.split(',')).call(_context3, directive => {
|
|
75
74
|
const _directive$trim$split = _trimInstanceProperty(directive).call(directive).split('='),
|
|
76
75
|
_directive$trim$split2 = _slicedToArray(_directive$trim$split, 2),
|
|
77
76
|
directiveName = _directive$trim$split2[0],
|
|
@@ -85,12 +84,12 @@ const parsePermissionsPolicyDirectives = (defaultValue, customDirectives) => {
|
|
|
85
84
|
return mergedDirectives.join(', ');
|
|
86
85
|
};
|
|
87
86
|
const processHeaders = applicationConfig => {
|
|
88
|
-
var _context5, _context6
|
|
87
|
+
var _context4, _context5, _context6;
|
|
89
88
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
90
89
|
|
|
91
90
|
// List hashes for injected inline scripts.
|
|
92
91
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
93
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
92
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
94
93
|
|
|
95
94
|
// // List hashes for injected inline styles.
|
|
96
95
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -102,15 +101,15 @@ const processHeaders = applicationConfig => {
|
|
|
102
101
|
*/
|
|
103
102
|
const defaultCSPDirectives = _Object$assign({
|
|
104
103
|
'default-src': "'none'",
|
|
105
|
-
'script-src': _concatInstanceProperty(
|
|
104
|
+
'script-src': _concatInstanceProperty(_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
106
105
|
// Allow webpack to load source maps on runtime when errors occur
|
|
107
106
|
// using script tags
|
|
108
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty(htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
109
|
-
'connect-src': _concatInstanceProperty(
|
|
107
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty(htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
108
|
+
'connect-src': _concatInstanceProperty(_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
110
109
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
111
|
-
'*.sentry.io']).call(
|
|
110
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
112
111
|
'img-src': ['*', 'data:'],
|
|
113
|
-
'style-src': _concatInstanceProperty(
|
|
112
|
+
'style-src': _concatInstanceProperty(_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
114
113
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
115
114
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
116
115
|
["'unsafe-inline'"]
|
|
@@ -137,9 +136,9 @@ const processHeaders = applicationConfig => {
|
|
|
137
136
|
return _objectSpread(_objectSpread({}, HTTP_SECURITY_HEADERS), {}, {
|
|
138
137
|
// The `Content-Security-Policy` header is always generated
|
|
139
138
|
// based on the Merchant Center customization config.
|
|
140
|
-
[HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives,
|
|
141
|
-
},
|
|
142
|
-
[HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(HTTP_SECURITY_HEADERS['Permissions-Policy'],
|
|
139
|
+
[HTTP_SECURITY_HEADER_KEYS['Content-Security-Policy']]: parseCSPDirectives(defaultCSPDirectives, applicationConfig.headers?.csp ?? {})
|
|
140
|
+
}, applicationConfig.headers?.permissionsPolicies ? {
|
|
141
|
+
[HTTP_SECURITY_HEADER_KEYS['Permissions-Policy']]: parsePermissionsPolicyDirectives(HTTP_SECURITY_HEADERS['Permissions-Policy'], applicationConfig.headers.permissionsPolicies ?? {})
|
|
143
142
|
} : {});
|
|
144
143
|
};
|
|
145
144
|
|
|
@@ -152,11 +151,9 @@ const htmlStyles = {
|
|
|
152
151
|
"loadingScreen": ".loading-screen{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;width:100vw}.loading-screen--hidden{display:none}.loading-screen>*+*{margin:24px 0 0}.loading-spinner{width:32px;height:32px}.long-loading-notice{color:#999;font-family:'Open Sans',sans-serif;font-size:12px}.long-loading-notice--hidden{visibility:hidden}.loading-spinner-circle{fill:#213c45;opacity:.2}@keyframes loading-spinner-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.loading-spinner-pointer{transform-origin:20px 20px 0;animation:loading-spinner-animation .5s infinite linear}"
|
|
153
152
|
};
|
|
154
153
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
155
|
-
const replaceHtmlPlaceholders = (indexHtmlContent, options) =>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"".concat(trimTrailingSlash(options.env.cdnUrl), "/") : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), "<script>window.app = ".concat(sanitizeAppEnvironment(options.env), ";</script>")).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), "<script>".concat(htmlScripts.loadingScreen, "</script>")).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), "<style>".concat(htmlStyles.loadingScreen, "</style>"));
|
|
159
|
-
};
|
|
154
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
155
|
+
// Ensure there is a trailing slash
|
|
156
|
+
`${trimTrailingSlash(options.env.cdnUrl)}/` : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), `<script>window.app = ${sanitizeAppEnvironment(options.env)};</script>`).replace(new RegExp('__LOADING_SCREEN_JS__', 'g'), `<script>${htmlScripts.loadingScreen}</script>`).replace(new RegExp('__LOADING_SCREEN_CSS__', 'g'), `<style>${htmlStyles.loadingScreen}</style>`);
|
|
160
157
|
|
|
161
158
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
162
159
|
const applicationConfig = await processConfig();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-frontend/mc-html-template",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.2.0",
|
|
4
4
|
"description": "Everything related to render the index.html for a MC application",
|
|
5
5
|
"bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
|
|
6
6
|
"repository": {
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@babel/runtime": "^7.22.15",
|
|
40
40
|
"@babel/runtime-corejs3": "^7.22.15",
|
|
41
|
-
"@commercetools-frontend/application-config": "25.
|
|
42
|
-
"@commercetools-frontend/constants": "25.
|
|
41
|
+
"@commercetools-frontend/application-config": "25.2.0",
|
|
42
|
+
"@commercetools-frontend/constants": "25.2.0",
|
|
43
43
|
"serialize-javascript": "6.0.2",
|
|
44
44
|
"uglify-js": "3.19.3",
|
|
45
45
|
"uglifycss": "0.0.29"
|
|
@@ -31,8 +31,8 @@ function webpackHtmlTemplate(templateParams) {
|
|
|
31
31
|
// Trim leading slash, the CDN_URL will ensure to have a trailing slash
|
|
32
32
|
// (see `replaceHtmlPlaceholders`)
|
|
33
33
|
fileName.replace(/^\//, ''));
|
|
34
|
-
const cssImports = _mapInstanceProperty__default["default"](cssChunks).call(cssChunks, chunkPath =>
|
|
35
|
-
const scriptImports = _mapInstanceProperty__default["default"](scriptChunks).call(scriptChunks, chunkPath =>
|
|
34
|
+
const cssImports = _mapInstanceProperty__default["default"](cssChunks).call(cssChunks, chunkPath => `<link href="__CDN_URL__${chunkPath}" rel='stylesheet' type='text/css'>`);
|
|
35
|
+
const scriptImports = _mapInstanceProperty__default["default"](scriptChunks).call(scriptChunks, chunkPath => `<script src="__CDN_URL__${chunkPath}" defer></script>`);
|
|
36
36
|
return generateTemplate.generateTemplate({
|
|
37
37
|
cssImports,
|
|
38
38
|
scriptImports
|
|
@@ -31,8 +31,8 @@ function webpackHtmlTemplate(templateParams) {
|
|
|
31
31
|
// Trim leading slash, the CDN_URL will ensure to have a trailing slash
|
|
32
32
|
// (see `replaceHtmlPlaceholders`)
|
|
33
33
|
fileName.replace(/^\//, ''));
|
|
34
|
-
const cssImports = _mapInstanceProperty__default["default"](cssChunks).call(cssChunks, chunkPath =>
|
|
35
|
-
const scriptImports = _mapInstanceProperty__default["default"](scriptChunks).call(scriptChunks, chunkPath =>
|
|
34
|
+
const cssImports = _mapInstanceProperty__default["default"](cssChunks).call(cssChunks, chunkPath => `<link href="__CDN_URL__${chunkPath}" rel='stylesheet' type='text/css'>`);
|
|
35
|
+
const scriptImports = _mapInstanceProperty__default["default"](scriptChunks).call(scriptChunks, chunkPath => `<script src="__CDN_URL__${chunkPath}" defer></script>`);
|
|
36
36
|
return generateTemplate.generateTemplate({
|
|
37
37
|
cssImports,
|
|
38
38
|
scriptImports
|
|
@@ -20,8 +20,8 @@ function webpackHtmlTemplate(templateParams) {
|
|
|
20
20
|
// Trim leading slash, the CDN_URL will ensure to have a trailing slash
|
|
21
21
|
// (see `replaceHtmlPlaceholders`)
|
|
22
22
|
fileName.replace(/^\//, ''));
|
|
23
|
-
const cssImports = _mapInstanceProperty(cssChunks).call(cssChunks, chunkPath =>
|
|
24
|
-
const scriptImports = _mapInstanceProperty(scriptChunks).call(scriptChunks, chunkPath =>
|
|
23
|
+
const cssImports = _mapInstanceProperty(cssChunks).call(cssChunks, chunkPath => `<link href="__CDN_URL__${chunkPath}" rel='stylesheet' type='text/css'>`);
|
|
24
|
+
const scriptImports = _mapInstanceProperty(scriptChunks).call(scriptChunks, chunkPath => `<script src="__CDN_URL__${chunkPath}" defer></script>`);
|
|
25
25
|
return generateTemplate({
|
|
26
26
|
cssImports,
|
|
27
27
|
scriptImports
|