@commercetools-frontend/mc-html-template 22.30.3 → 22.32.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 +19 -23
- package/dist/commercetools-frontend-mc-html-template.cjs.prod.js +19 -23
- package/dist/commercetools-frontend-mc-html-template.esm.js +19 -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
|
@@ -55,7 +55,7 @@ function createAssetHash(content) {
|
|
|
55
55
|
* CSP headers sent.
|
|
56
56
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
57
57
|
*/
|
|
58
|
-
return
|
|
58
|
+
return `sha256-${sha256Hash}`;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
@@ -63,7 +63,7 @@ const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
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; }
|
|
66
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
66
|
+
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; }
|
|
67
67
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
68
68
|
const htmlScripts$1 = {
|
|
69
69
|
"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);",
|
|
@@ -85,31 +85,29 @@ const toHeaderString = function () {
|
|
|
85
85
|
var _context2;
|
|
86
86
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
87
87
|
return _mapInstanceProperty__default["default"](_context2 = _Object$entries__default["default"](directives)).call(_context2, _ref => {
|
|
88
|
-
var _context3;
|
|
89
88
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
90
89
|
directive = _ref2[0],
|
|
91
90
|
value = _ref2[1];
|
|
92
|
-
return
|
|
91
|
+
return `${directive} ${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
93
92
|
}).join('; ');
|
|
94
93
|
};
|
|
95
94
|
const toStructuredHeaderString = function () {
|
|
96
|
-
var
|
|
95
|
+
var _context3;
|
|
97
96
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
98
|
-
return _mapInstanceProperty__default["default"](
|
|
99
|
-
var _context5;
|
|
97
|
+
return _mapInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](directives)).call(_context3, _ref3 => {
|
|
100
98
|
let _ref4 = _slicedToArray(_ref3, 2),
|
|
101
99
|
directive = _ref4[0],
|
|
102
100
|
value = _ref4[1];
|
|
103
|
-
return
|
|
101
|
+
return `${directive}=${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
104
102
|
}).join(', ');
|
|
105
103
|
};
|
|
106
104
|
const processHeaders = applicationConfig => {
|
|
107
|
-
var
|
|
105
|
+
var _context4, _context5, _context6;
|
|
108
106
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
109
107
|
|
|
110
108
|
// List hashes for injected inline scripts.
|
|
111
109
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
112
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
110
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
113
111
|
|
|
114
112
|
// // List hashes for injected inline styles.
|
|
115
113
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -121,15 +119,15 @@ const processHeaders = applicationConfig => {
|
|
|
121
119
|
*/
|
|
122
120
|
const cspDirectives = _Object$assign__default["default"]({
|
|
123
121
|
'default-src': "'none'",
|
|
124
|
-
'script-src': _concatInstanceProperty__default["default"](
|
|
122
|
+
'script-src': _concatInstanceProperty__default["default"](_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
125
123
|
// Allow webpack to load source maps on runtime when errors occur
|
|
126
124
|
// using script tags
|
|
127
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
128
|
-
'connect-src': _concatInstanceProperty__default["default"](
|
|
125
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
126
|
+
'connect-src': _concatInstanceProperty__default["default"](_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
129
127
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
130
|
-
'*.sentry.io']).call(
|
|
128
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
131
129
|
'img-src': ['*', 'data:'],
|
|
132
|
-
'style-src': _concatInstanceProperty__default["default"](
|
|
130
|
+
'style-src': _concatInstanceProperty__default["default"](_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
133
131
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
134
132
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
135
133
|
["'unsafe-inline'"]
|
|
@@ -155,14 +153,14 @@ const processHeaders = applicationConfig => {
|
|
|
155
153
|
);
|
|
156
154
|
|
|
157
155
|
// Recursively merge the directives
|
|
158
|
-
const mergedCsp = mergeCspDirectives(cspDirectives,
|
|
156
|
+
const mergedCsp = mergeCspDirectives(cspDirectives, applicationConfig.headers?.csp ?? {});
|
|
159
157
|
return _objectSpread(_objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
160
158
|
// The `Content-Security-Policy` header is always generated
|
|
161
159
|
// based on the Merchant Center customization config.
|
|
162
160
|
'Content-Security-Policy': toHeaderString(mergedCsp)
|
|
163
|
-
},
|
|
161
|
+
}, applicationConfig.headers?.strictTransportSecurity && {
|
|
164
162
|
'Strict-Transport-Security': [constants.HTTP_SECURITY_HEADERS['Strict-Transport-Security'], ...applicationConfig.headers.strictTransportSecurity].join('; ')
|
|
165
|
-
}),
|
|
163
|
+
}), applicationConfig.headers?.permissionsPolicies && {
|
|
166
164
|
'Permissions-Policy': toStructuredHeaderString(applicationConfig.headers.permissionsPolicies)
|
|
167
165
|
});
|
|
168
166
|
};
|
|
@@ -176,11 +174,9 @@ const htmlStyles = {
|
|
|
176
174
|
"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}"
|
|
177
175
|
};
|
|
178
176
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
179
|
-
const replaceHtmlPlaceholders = (indexHtmlContent, options) =>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"".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>"));
|
|
183
|
-
};
|
|
177
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
178
|
+
// Ensure there is a trailing slash
|
|
179
|
+
`${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>`);
|
|
184
180
|
|
|
185
181
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
186
182
|
const applicationConfig$1 = applicationConfig.processConfig();
|
|
@@ -55,7 +55,7 @@ function createAssetHash(content) {
|
|
|
55
55
|
* CSP headers sent.
|
|
56
56
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
57
57
|
*/
|
|
58
|
-
return
|
|
58
|
+
return `sha256-${sha256Hash}`;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
@@ -63,7 +63,7 @@ const sanitizeAppEnvironment = env => serialize__default["default"](env, {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
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; }
|
|
66
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
66
|
+
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; }
|
|
67
67
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
68
68
|
const htmlScripts$1 = {
|
|
69
69
|
"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);",
|
|
@@ -85,31 +85,29 @@ const toHeaderString = function () {
|
|
|
85
85
|
var _context2;
|
|
86
86
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
87
87
|
return _mapInstanceProperty__default["default"](_context2 = _Object$entries__default["default"](directives)).call(_context2, _ref => {
|
|
88
|
-
var _context3;
|
|
89
88
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
90
89
|
directive = _ref2[0],
|
|
91
90
|
value = _ref2[1];
|
|
92
|
-
return
|
|
91
|
+
return `${directive} ${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
93
92
|
}).join('; ');
|
|
94
93
|
};
|
|
95
94
|
const toStructuredHeaderString = function () {
|
|
96
|
-
var
|
|
95
|
+
var _context3;
|
|
97
96
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
98
|
-
return _mapInstanceProperty__default["default"](
|
|
99
|
-
var _context5;
|
|
97
|
+
return _mapInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](directives)).call(_context3, _ref3 => {
|
|
100
98
|
let _ref4 = _slicedToArray(_ref3, 2),
|
|
101
99
|
directive = _ref4[0],
|
|
102
100
|
value = _ref4[1];
|
|
103
|
-
return
|
|
101
|
+
return `${directive}=${_Array$isArray__default["default"](value) ? value.join(' ') : value}`;
|
|
104
102
|
}).join(', ');
|
|
105
103
|
};
|
|
106
104
|
const processHeaders = applicationConfig => {
|
|
107
|
-
var
|
|
105
|
+
var _context4, _context5, _context6;
|
|
108
106
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
109
107
|
|
|
110
108
|
// List hashes for injected inline scripts.
|
|
111
109
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
112
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
110
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
113
111
|
|
|
114
112
|
// // List hashes for injected inline styles.
|
|
115
113
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -121,15 +119,15 @@ const processHeaders = applicationConfig => {
|
|
|
121
119
|
*/
|
|
122
120
|
const cspDirectives = _Object$assign__default["default"]({
|
|
123
121
|
'default-src': "'none'",
|
|
124
|
-
'script-src': _concatInstanceProperty__default["default"](
|
|
122
|
+
'script-src': _concatInstanceProperty__default["default"](_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
125
123
|
// Allow webpack to load source maps on runtime when errors occur
|
|
126
124
|
// using script tags
|
|
127
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
128
|
-
'connect-src': _concatInstanceProperty__default["default"](
|
|
125
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
126
|
+
'connect-src': _concatInstanceProperty__default["default"](_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
129
127
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
130
|
-
'*.sentry.io']).call(
|
|
128
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
131
129
|
'img-src': ['*', 'data:'],
|
|
132
|
-
'style-src': _concatInstanceProperty__default["default"](
|
|
130
|
+
'style-src': _concatInstanceProperty__default["default"](_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
133
131
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
134
132
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
135
133
|
["'unsafe-inline'"]
|
|
@@ -155,14 +153,14 @@ const processHeaders = applicationConfig => {
|
|
|
155
153
|
);
|
|
156
154
|
|
|
157
155
|
// Recursively merge the directives
|
|
158
|
-
const mergedCsp = mergeCspDirectives(cspDirectives,
|
|
156
|
+
const mergedCsp = mergeCspDirectives(cspDirectives, applicationConfig.headers?.csp ?? {});
|
|
159
157
|
return _objectSpread(_objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
160
158
|
// The `Content-Security-Policy` header is always generated
|
|
161
159
|
// based on the Merchant Center customization config.
|
|
162
160
|
'Content-Security-Policy': toHeaderString(mergedCsp)
|
|
163
|
-
},
|
|
161
|
+
}, applicationConfig.headers?.strictTransportSecurity && {
|
|
164
162
|
'Strict-Transport-Security': [constants.HTTP_SECURITY_HEADERS['Strict-Transport-Security'], ...applicationConfig.headers.strictTransportSecurity].join('; ')
|
|
165
|
-
}),
|
|
163
|
+
}), applicationConfig.headers?.permissionsPolicies && {
|
|
166
164
|
'Permissions-Policy': toStructuredHeaderString(applicationConfig.headers.permissionsPolicies)
|
|
167
165
|
});
|
|
168
166
|
};
|
|
@@ -176,11 +174,9 @@ const htmlStyles = {
|
|
|
176
174
|
"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}"
|
|
177
175
|
};
|
|
178
176
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
179
|
-
const replaceHtmlPlaceholders = (indexHtmlContent, options) =>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"".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>"));
|
|
183
|
-
};
|
|
177
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
178
|
+
// Ensure there is a trailing slash
|
|
179
|
+
`${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>`);
|
|
184
180
|
|
|
185
181
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
186
182
|
const applicationConfig$1 = applicationConfig.processConfig();
|
|
@@ -31,7 +31,7 @@ function createAssetHash(content) {
|
|
|
31
31
|
* CSP headers sent.
|
|
32
32
|
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
33
33
|
*/
|
|
34
|
-
return
|
|
34
|
+
return `sha256-${sha256Hash}`;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const sanitizeAppEnvironment = env => serialize(env, {
|
|
@@ -39,7 +39,7 @@ const sanitizeAppEnvironment = env => serialize(env, {
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
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; }
|
|
42
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
42
|
+
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; }
|
|
43
43
|
// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
44
44
|
const htmlScripts$1 = {
|
|
45
45
|
"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);",
|
|
@@ -61,31 +61,29 @@ const toHeaderString = function () {
|
|
|
61
61
|
var _context2;
|
|
62
62
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
63
63
|
return _mapInstanceProperty(_context2 = _Object$entries(directives)).call(_context2, _ref => {
|
|
64
|
-
var _context3;
|
|
65
64
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
66
65
|
directive = _ref2[0],
|
|
67
66
|
value = _ref2[1];
|
|
68
|
-
return
|
|
67
|
+
return `${directive} ${_Array$isArray(value) ? value.join(' ') : value}`;
|
|
69
68
|
}).join('; ');
|
|
70
69
|
};
|
|
71
70
|
const toStructuredHeaderString = function () {
|
|
72
|
-
var
|
|
71
|
+
var _context3;
|
|
73
72
|
let directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
74
|
-
return _mapInstanceProperty(
|
|
75
|
-
var _context5;
|
|
73
|
+
return _mapInstanceProperty(_context3 = _Object$entries(directives)).call(_context3, _ref3 => {
|
|
76
74
|
let _ref4 = _slicedToArray(_ref3, 2),
|
|
77
75
|
directive = _ref4[0],
|
|
78
76
|
value = _ref4[1];
|
|
79
|
-
return
|
|
77
|
+
return `${directive}=${_Array$isArray(value) ? value.join(' ') : value}`;
|
|
80
78
|
}).join(', ');
|
|
81
79
|
};
|
|
82
80
|
const processHeaders = applicationConfig => {
|
|
83
|
-
var
|
|
81
|
+
var _context4, _context5, _context6;
|
|
84
82
|
const isMcDevEnv = applicationConfig.env.env === 'development';
|
|
85
83
|
|
|
86
84
|
// List hashes for injected inline scripts.
|
|
87
85
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
88
|
-
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(
|
|
86
|
+
const htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash(`window.app = ${sanitizeAppEnvironment(applicationConfig.env)};`), createAssetHash(htmlScripts$1.publicPath)];
|
|
89
87
|
|
|
90
88
|
// // List hashes for injected inline styles.
|
|
91
89
|
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
@@ -97,15 +95,15 @@ const processHeaders = applicationConfig => {
|
|
|
97
95
|
*/
|
|
98
96
|
const cspDirectives = _Object$assign({
|
|
99
97
|
'default-src': "'none'",
|
|
100
|
-
'script-src': _concatInstanceProperty(
|
|
98
|
+
'script-src': _concatInstanceProperty(_context4 = ["'self'"]).call(_context4, isMcDevEnv ?
|
|
101
99
|
// Allow webpack to load source maps on runtime when errors occur
|
|
102
100
|
// using script tags
|
|
103
|
-
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty(htmlScriptsHashes).call(htmlScriptsHashes, assetHash =>
|
|
104
|
-
'connect-src': _concatInstanceProperty(
|
|
101
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty(htmlScriptsHashes).call(htmlScriptsHashes, assetHash => `'${assetHash}'`)),
|
|
102
|
+
'connect-src': _concatInstanceProperty(_context5 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com',
|
|
105
103
|
// Match all attempts to load from any subdomain of `sentry.io`
|
|
106
|
-
'*.sentry.io']).call(
|
|
104
|
+
'*.sentry.io']).call(_context5, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
107
105
|
'img-src': ['*', 'data:'],
|
|
108
|
-
'style-src': _concatInstanceProperty(
|
|
106
|
+
'style-src': _concatInstanceProperty(_context6 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context6,
|
|
109
107
|
// TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
110
108
|
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
111
109
|
["'unsafe-inline'"]
|
|
@@ -131,14 +129,14 @@ const processHeaders = applicationConfig => {
|
|
|
131
129
|
);
|
|
132
130
|
|
|
133
131
|
// Recursively merge the directives
|
|
134
|
-
const mergedCsp = mergeCspDirectives(cspDirectives,
|
|
132
|
+
const mergedCsp = mergeCspDirectives(cspDirectives, applicationConfig.headers?.csp ?? {});
|
|
135
133
|
return _objectSpread(_objectSpread(_objectSpread({}, HTTP_SECURITY_HEADERS), {}, {
|
|
136
134
|
// The `Content-Security-Policy` header is always generated
|
|
137
135
|
// based on the Merchant Center customization config.
|
|
138
136
|
'Content-Security-Policy': toHeaderString(mergedCsp)
|
|
139
|
-
},
|
|
137
|
+
}, applicationConfig.headers?.strictTransportSecurity && {
|
|
140
138
|
'Strict-Transport-Security': [HTTP_SECURITY_HEADERS['Strict-Transport-Security'], ...applicationConfig.headers.strictTransportSecurity].join('; ')
|
|
141
|
-
}),
|
|
139
|
+
}), applicationConfig.headers?.permissionsPolicies && {
|
|
142
140
|
'Permissions-Policy': toStructuredHeaderString(applicationConfig.headers.permissionsPolicies)
|
|
143
141
|
});
|
|
144
142
|
};
|
|
@@ -152,11 +150,9 @@ const htmlStyles = {
|
|
|
152
150
|
"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
151
|
};
|
|
154
152
|
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
|
-
};
|
|
153
|
+
const replaceHtmlPlaceholders = (indexHtmlContent, options) => indexHtmlContent.replace(new RegExp('__CSP__', 'g'), options.headers?.['Content-Security-Policy'] ?? '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ?
|
|
154
|
+
// Ensure there is a trailing slash
|
|
155
|
+
`${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
156
|
|
|
161
157
|
async function compileHtml(indexHtmlTemplatePath) {
|
|
162
158
|
const applicationConfig = processConfig();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-frontend/mc-html-template",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.32.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": "22.
|
|
42
|
-
"@commercetools-frontend/constants": "22.
|
|
41
|
+
"@commercetools-frontend/application-config": "22.32.0",
|
|
42
|
+
"@commercetools-frontend/constants": "22.32.0",
|
|
43
43
|
"serialize-javascript": "6.0.2",
|
|
44
44
|
"uglify-js": "3.18.0",
|
|
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}"></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}"></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}"></script>`);
|
|
25
25
|
return generateTemplate({
|
|
26
26
|
cssImports,
|
|
27
27
|
scriptImports
|