@commercetools-frontend/mc-html-template 21.4.0 → 21.7.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/README.md +51 -5
- package/dist/commercetools-frontend-mc-html-template.cjs.d.ts +1 -0
- package/dist/commercetools-frontend-mc-html-template.cjs.dev.js +255 -0
- package/dist/commercetools-frontend-mc-html-template.cjs.js +7 -0
- package/dist/commercetools-frontend-mc-html-template.cjs.prod.js +255 -0
- package/dist/commercetools-frontend-mc-html-template.esm.js +227 -0
- package/dist/declarations/src/compile-html.d.ts +8 -0
- package/dist/declarations/src/generate-template.d.ts +6 -0
- package/dist/declarations/src/index.d.ts +4 -0
- package/dist/declarations/src/load-html-docs.d.ts +3 -0
- package/dist/declarations/src/load-html-scripts.d.ts +7 -0
- package/dist/declarations/src/load-html-styles.d.ts +5 -0
- package/dist/declarations/src/process-headers.d.ts +3 -0
- package/dist/declarations/src/replace-html-placeholders.d.ts +7 -0
- package/dist/declarations/src/utils/create-asset-hash.d.ts +2 -0
- package/dist/declarations/src/utils/sanitize-app-environment.d.ts +3 -0
- package/dist/declarations/src/webpack-html-template.d.ts +3 -0
- package/dist/generate-template-211c0b41.cjs.dev.js +16 -0
- package/dist/generate-template-600664a1.cjs.prod.js +16 -0
- package/{build/load-html-docs.js → dist/generate-template-e252c441.esm.js} +13 -10
- package/package.json +17 -36
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.d.ts +2 -0
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.dev.js +57 -0
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.js +7 -0
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.cjs.prod.js +57 -0
- package/webpack-html-template/dist/commercetools-frontend-mc-html-template-webpack-html-template.esm.js +46 -0
- package/webpack-html-template/package.json +4 -0
- package/webpack.js +5 -35
- package/build/compile-html.js +0 -27
- package/build/generate-template.js +0 -10
- package/build/index.js +0 -6
- package/build/load-html-scripts.js +0 -13
- package/build/load-html-styles.js +0 -11
- package/build/process-headers.js +0 -116
- package/build/process-headers.spec.js +0 -98
- package/build/utils/create-asset-hash.js +0 -16
- package/build/utils/replace-html-placeholders.js +0 -22
- package/build/utils/sanitize-app-environment.js +0 -9
- package/build/utils/substitute-env-variable-placeholders.js +0 -74
- package/build/utils/substitute-env-variable-placeholders.spec.js +0 -42
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<a href="https://www.npmjs.com/package/@commercetools-frontend/mc-html-template"><img src="https://badgen.net/npm/v/@commercetools-frontend/mc-html-template" alt="Latest release (latest dist-tag)" /></a> <a href="https://www.npmjs.com/package/@commercetools-frontend/mc-html-template"><img src="https://badgen.net/npm/v/@commercetools-frontend/mc-html-template/next" alt="Latest release (next dist-tag)" /></a> <a href="https://bundlephobia.com/result?p=@commercetools-frontend/mc-html-template"><img src="https://badgen.net/bundlephobia/minzip/@commercetools-frontend/mc-html-template" alt="Minified + GZipped size" /></a> <a href="https://github.com/commercetools/merchant-center-application-kit/blob/main/LICENSE"><img src="https://badgen.net/github/license/commercetools/merchant-center-application-kit" alt="GitHub license" /></a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
This package contains utils and scripts related to the `index.html` for a
|
|
7
|
+
This package contains utils and scripts related to the `index.html` for a Custom Application.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -14,13 +14,25 @@ $ npm install --save @commercetools-frontend/mc-html-template
|
|
|
14
14
|
|
|
15
15
|
## API
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### `generateTemplate`
|
|
18
18
|
|
|
19
|
-
This method will return the
|
|
19
|
+
This method will return the template HTML document with the provided CSS/JS scripts injected.
|
|
20
20
|
|
|
21
21
|
> NOTE that the HTML document will still have the **placeholders** (see `replaceHtmlPlaceholders`)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
```ts
|
|
24
|
+
type TGenerateTemplateOptions = {
|
|
25
|
+
cssImports?: string[];
|
|
26
|
+
scriptImports?: string[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function generateTemplate({
|
|
30
|
+
cssImports = [],
|
|
31
|
+
scriptImports = [],
|
|
32
|
+
}: TGenerateTemplateOptions);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### `replaceHtmlPlaceholders`
|
|
24
36
|
|
|
25
37
|
This method will replace the **placeholders** defined in the HTML document based on the application config.
|
|
26
38
|
|
|
@@ -37,7 +49,35 @@ At the moment we define the following placeholders:
|
|
|
37
49
|
- `__GTM_SCRIPT__`: the actual GTM script, in case the `trackingGtm` is defined in the `additionalEnv` property of the application config
|
|
38
50
|
- `__CSP__`: the generated `Content-Security-Policy` directives, defined as an HTML meta tag
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
```ts
|
|
53
|
+
type TReplaceHtmlPlaceholdersOptions = {
|
|
54
|
+
env: ApplicationRuntimeConfig['env'];
|
|
55
|
+
headers: Record<string, string | undefined>;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function replaceHtmlPlaceholders(
|
|
59
|
+
indexHtmlContent: string,
|
|
60
|
+
options: TReplaceHtmlPlaceholdersOptions
|
|
61
|
+
): string;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `compileHtml`
|
|
65
|
+
|
|
66
|
+
This method will compile the template HTML document.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
type TCompileHtmlResult = {
|
|
70
|
+
env: ApplicationRuntimeConfig['env'];
|
|
71
|
+
headers: Record<string, string | undefined>;
|
|
72
|
+
indexHtmlContent: string;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
async function compileHtml(
|
|
76
|
+
indexHtmlTemplatePath: string
|
|
77
|
+
): Promise<TCompileHtmlResult>;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `processHeaders`
|
|
41
81
|
|
|
42
82
|
This method will return the security headers to be used on the server response, serving the `index.html`.
|
|
43
83
|
|
|
@@ -57,6 +97,12 @@ The return value of the `processHeaders` function contains the following ready-t
|
|
|
57
97
|
}
|
|
58
98
|
```
|
|
59
99
|
|
|
100
|
+
```ts
|
|
101
|
+
function processHeaders(
|
|
102
|
+
applicationConfig: ApplicationRuntimeConfig
|
|
103
|
+
): Record<string, string | undefined>;
|
|
104
|
+
```
|
|
105
|
+
|
|
60
106
|
## Bundler entry points
|
|
61
107
|
|
|
62
108
|
The package exposes some special entry points used by specific bundlers to use the HTML template.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./declarations/src/index";
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _asyncToGenerator = require('@babel/runtime-corejs3/helpers/asyncToGenerator');
|
|
6
|
+
var _regeneratorRuntime = require('@babel/runtime-corejs3/regenerator');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var applicationConfig = require('@commercetools-frontend/application-config');
|
|
9
|
+
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
|
|
10
|
+
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
|
|
11
|
+
var _toConsumableArray = require('@babel/runtime-corejs3/helpers/toConsumableArray');
|
|
12
|
+
var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
|
|
13
|
+
var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
|
|
14
|
+
var _Object$assign = require('@babel/runtime-corejs3/core-js-stable/object/assign');
|
|
15
|
+
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
16
|
+
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
17
|
+
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
|
18
|
+
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
19
|
+
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
|
|
20
|
+
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
|
21
|
+
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
|
|
22
|
+
var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
|
|
23
|
+
var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
|
|
24
|
+
var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
|
|
25
|
+
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
|
|
26
|
+
var constants = require('@commercetools-frontend/constants');
|
|
27
|
+
var crypto = require('crypto');
|
|
28
|
+
var serialize = require('serialize-javascript');
|
|
29
|
+
var generateTemplate = require('./generate-template-211c0b41.cjs.dev.js');
|
|
30
|
+
|
|
31
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
32
|
+
|
|
33
|
+
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
|
|
34
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
35
|
+
var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
|
|
36
|
+
var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
|
|
37
|
+
var _Object$assign__default = /*#__PURE__*/_interopDefault(_Object$assign);
|
|
38
|
+
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
39
|
+
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
40
|
+
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
|
41
|
+
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
42
|
+
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
|
|
43
|
+
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
|
44
|
+
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
|
|
45
|
+
var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
|
|
46
|
+
var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
|
|
47
|
+
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
|
|
48
|
+
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
|
|
49
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
50
|
+
var serialize__default = /*#__PURE__*/_interopDefault(serialize);
|
|
51
|
+
|
|
52
|
+
function createAssetHash(content) {
|
|
53
|
+
var sha256Hash = crypto__default["default"].createHash('sha256').update(content).digest('base64');
|
|
54
|
+
/**
|
|
55
|
+
* NOTE:
|
|
56
|
+
* We prefix the hash function type as the browser
|
|
57
|
+
* needs it when validating the contents of a script against
|
|
58
|
+
* CSP headers sent.
|
|
59
|
+
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
return "sha256-".concat(sha256Hash);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var sanitizeAppEnvironment = function sanitizeAppEnvironment(env) {
|
|
66
|
+
return serialize__default["default"](env, {
|
|
67
|
+
isJSON: true
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function ownKeys(object, enumerableOnly) { var keys = _Object$keys__default["default"](object); if (_Object$getOwnPropertySymbols__default["default"]) { var symbols = _Object$getOwnPropertySymbols__default["default"](object); enumerableOnly && (symbols = _filterInstanceProperty__default["default"](symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor__default["default"](object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
72
|
+
|
|
73
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context11, _context12; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty__default["default"](_context11 = ownKeys(Object(source), !0)).call(_context11, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](target, _Object$getOwnPropertyDescriptors__default["default"](source)) : _forEachInstanceProperty__default["default"](_context12 = ownKeys(Object(source))).call(_context12, function (key) { _Object$defineProperty__default["default"](target, key, _Object$getOwnPropertyDescriptor__default["default"](source, key)); }); } return target; }
|
|
74
|
+
|
|
75
|
+
var htmlScripts$1 = {
|
|
76
|
+
"dataLayer": "window.dataLayer=[{\"gtm.start\":(new Date).getTime(),event:\"gtm.js\"}];",
|
|
77
|
+
"loadingScreen": "window.onAppLoaded=function(){const e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){const e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){const e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
78
|
+
"publicPath": "window.__dynamicImportHandler__=function(n){return window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n.replace(/^(\\.\\/)?/,\"\")},window.__dynamicImportPreload__=function(n){return n.map(n=>window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n)};"
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
var toArray = function toArray(value) {
|
|
82
|
+
return _Array$isArray__default["default"](value) ? value : [value];
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
var mergeCspDirectives = function mergeCspDirectives() {
|
|
86
|
+
for (var _len = arguments.length, directives = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
87
|
+
directives[_key] = arguments[_key];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return _reduceInstanceProperty__default["default"](directives).call(directives, function (mergedCsp, csp) {
|
|
91
|
+
var _context;
|
|
92
|
+
|
|
93
|
+
return _Object$assign__default["default"](mergedCsp, _reduceInstanceProperty__default["default"](_context = _Object$keys__default["default"](csp)).call(_context, function (acc, directiveKey) {
|
|
94
|
+
var _context2;
|
|
95
|
+
|
|
96
|
+
return _Object$assign__default["default"](acc, _defineProperty({}, directiveKey, _concatInstanceProperty__default["default"](_context2 = []).call(_context2, _toConsumableArray(toArray(mergedCsp[directiveKey] ? mergedCsp[directiveKey] : [])), _toConsumableArray(toArray(csp[directiveKey])))));
|
|
97
|
+
}, {}));
|
|
98
|
+
}, {});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
var toHeaderString = function toHeaderString() {
|
|
102
|
+
var _context3;
|
|
103
|
+
|
|
104
|
+
var directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
105
|
+
return _mapInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](directives)).call(_context3, function (_ref) {
|
|
106
|
+
var _context4;
|
|
107
|
+
|
|
108
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
109
|
+
directive = _ref2[0],
|
|
110
|
+
value = _ref2[1];
|
|
111
|
+
|
|
112
|
+
return _concatInstanceProperty__default["default"](_context4 = "".concat(directive, " ")).call(_context4, _Array$isArray__default["default"](value) ? value.join(' ') : value);
|
|
113
|
+
}).join('; ');
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
var toStructuredHeaderString = function toStructuredHeaderString() {
|
|
117
|
+
var _context5;
|
|
118
|
+
|
|
119
|
+
var directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
120
|
+
return _mapInstanceProperty__default["default"](_context5 = _Object$entries__default["default"](directives)).call(_context5, function (_ref3) {
|
|
121
|
+
var _context6;
|
|
122
|
+
|
|
123
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
124
|
+
directive = _ref4[0],
|
|
125
|
+
value = _ref4[1];
|
|
126
|
+
|
|
127
|
+
return _concatInstanceProperty__default["default"](_context6 = "".concat(directive, "=")).call(_context6, _Array$isArray__default["default"](value) ? value.join(' ') : value);
|
|
128
|
+
}).join(', ');
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
var processHeaders = function processHeaders(applicationConfig) {
|
|
132
|
+
var _context7, _context8, _context9, _applicationConfig$he, _applicationConfig$he2, _applicationConfig$he3, _context10, _applicationConfig$he4, _applicationConfig$he5;
|
|
133
|
+
|
|
134
|
+
var isMcDevEnv = applicationConfig.env.env === 'development'; // List hashes for injected inline scripts.
|
|
135
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
136
|
+
|
|
137
|
+
var htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash("window.app = ".concat(sanitizeAppEnvironment(applicationConfig.env), ";")), createAssetHash(htmlScripts$1.publicPath), createAssetHash(htmlScripts$1.dataLayer)]; // // List hashes for injected inline styles.
|
|
138
|
+
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
139
|
+
// const htmlStylesHashes = [createAssetHash(htmlStyles.loadingScreen)];
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Content Security Policy (CSP)
|
|
143
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
var cspDirectives = _Object$assign__default["default"]({
|
|
147
|
+
'default-src': "'none'",
|
|
148
|
+
'script-src': _concatInstanceProperty__default["default"](_context7 = ["'self'", 'www.googletagmanager.com/gtm.js', 'www.google-analytics.com/analytics.js']).call(_context7, isMcDevEnv ? // Allow webpack to load source maps on runtime when errors occur
|
|
149
|
+
// using script tags
|
|
150
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, function (assetHash) {
|
|
151
|
+
return "'".concat(assetHash, "'");
|
|
152
|
+
})),
|
|
153
|
+
'connect-src': _concatInstanceProperty__default["default"](_context8 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com', // Match all attempts to load from any subdomain of `sentry.io`
|
|
154
|
+
'*.sentry.io', 'www.google-analytics.com']).call(_context8, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
155
|
+
'img-src': ['*', 'data:'],
|
|
156
|
+
'style-src': _concatInstanceProperty__default["default"](_context9 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context9, // TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
157
|
+
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
158
|
+
["'unsafe-inline'"] // TODO: enable this once we can avoid unsafe-inline
|
|
159
|
+
// htmlStylesHashes.map(assetHash => `'${assetHash}'`)
|
|
160
|
+
),
|
|
161
|
+
'font-src': ["'self'", 'fonts.gstatic.com', 'data:']
|
|
162
|
+
}, isMcDevEnv ? {
|
|
163
|
+
// NOTE: use this instead of `upgrade-insecure-requests` for local
|
|
164
|
+
// development to avoid `http://localhost` requests to be redirected
|
|
165
|
+
// to https.
|
|
166
|
+
'block-all-mixed-content': ''
|
|
167
|
+
} : {
|
|
168
|
+
// NOTE: prefer this over `block-all-mixed-content`.
|
|
169
|
+
// https://youtu.be/j-0Bj40juMI?t=11m47s
|
|
170
|
+
'upgrade-insecure-requests': ''
|
|
171
|
+
} // NOTE: we might want to define further policies in the future, for example
|
|
172
|
+
// - `require-sri-for style script` (at the moment not possible because
|
|
173
|
+
// GTM and Intercom scripts are apparently not meant for this)
|
|
174
|
+
); // Recursively merge the directives
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
var mergedCsp = mergeCspDirectives(cspDirectives, (_applicationConfig$he = (_applicationConfig$he2 = applicationConfig.headers) === null || _applicationConfig$he2 === void 0 ? void 0 : _applicationConfig$he2.csp) !== null && _applicationConfig$he !== void 0 ? _applicationConfig$he : {});
|
|
178
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
179
|
+
// The `Content-Security-Policy` header is always generated
|
|
180
|
+
// based on the Custom Application config.
|
|
181
|
+
'Content-Security-Policy': toHeaderString(mergedCsp)
|
|
182
|
+
}, ((_applicationConfig$he3 = applicationConfig.headers) === null || _applicationConfig$he3 === void 0 ? void 0 : _applicationConfig$he3.strictTransportSecurity) && {
|
|
183
|
+
'Strict-Transport-Security': _concatInstanceProperty__default["default"](_context10 = [constants.HTTP_SECURITY_HEADERS['Strict-Transport-Security']]).call(_context10, _toConsumableArray(applicationConfig.headers.strictTransportSecurity)).join('; ')
|
|
184
|
+
}), ((_applicationConfig$he4 = applicationConfig.headers) === null || _applicationConfig$he4 === void 0 ? void 0 : _applicationConfig$he4.featurePolicies) && {
|
|
185
|
+
'Feature-Policy': toHeaderString(applicationConfig.headers.featurePolicies)
|
|
186
|
+
}), ((_applicationConfig$he5 = applicationConfig.headers) === null || _applicationConfig$he5 === void 0 ? void 0 : _applicationConfig$he5.permissionsPolicies) && {
|
|
187
|
+
'Permissions-Policy': toStructuredHeaderString(applicationConfig.headers.permissionsPolicies)
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
var htmlScripts = {
|
|
192
|
+
"dataLayer": "window.dataLayer=[{\"gtm.start\":(new Date).getTime(),event:\"gtm.js\"}];",
|
|
193
|
+
"loadingScreen": "window.onAppLoaded=function(){const e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){const e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){const e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
194
|
+
"publicPath": "window.__dynamicImportHandler__=function(n){return window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n.replace(/^(\\.\\/)?/,\"\")},window.__dynamicImportPreload__=function(n){return n.map(n=>window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n)};"
|
|
195
|
+
}; // https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
196
|
+
|
|
197
|
+
var htmlStyles = {
|
|
198
|
+
"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}"
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
var trimTrailingSlash = function trimTrailingSlash(value) {
|
|
202
|
+
return value.replace(/\/$/, '');
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
var getGtmTrackingScript = function getGtmTrackingScript(gtmId) {
|
|
206
|
+
if (!gtmId) return '';
|
|
207
|
+
var url = "https://www.googletagmanager.com/gtm.js?id=".concat(gtmId);
|
|
208
|
+
return "\n<script async type=\"text/javascript\" src=\"".concat(url, "\" referrerpolicy=\"no-referrer\"></script>\n ");
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
var replaceHtmlPlaceholders = function replaceHtmlPlaceholders(indexHtmlContent, options) {
|
|
212
|
+
var _options$headers$Cont, _options$headers;
|
|
213
|
+
|
|
214
|
+
return indexHtmlContent.replace(new RegExp('__CSP__', 'g'), (_options$headers$Cont = (_options$headers = options.headers) === null || _options$headers === void 0 ? void 0 : _options$headers['Content-Security-Policy']) !== null && _options$headers$Cont !== void 0 ? _options$headers$Cont : '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ? // Ensure there is a trailing slash
|
|
215
|
+
"".concat(trimTrailingSlash(options.env.cdnUrl), "/") : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), sanitizeAppEnvironment(options.env)).replace(new RegExp('__GTM_SCRIPT__', 'g'), getGtmTrackingScript(options.env.trackingGtm)).replace(new RegExp('__DATALAYER_JS__', 'g'), "<script>".concat(htmlScripts.dataLayer, "</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>"));
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
function compileHtml(_x) {
|
|
219
|
+
return _compileHtml.apply(this, arguments);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function _compileHtml() {
|
|
223
|
+
_compileHtml = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee(indexHtmlTemplatePath) {
|
|
224
|
+
var applicationConfig$1, compiledHeaders, indexHtmlTemplateContent, indexHtmlContent;
|
|
225
|
+
return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
|
|
226
|
+
while (1) {
|
|
227
|
+
switch (_context.prev = _context.next) {
|
|
228
|
+
case 0:
|
|
229
|
+
applicationConfig$1 = applicationConfig.processConfig();
|
|
230
|
+
compiledHeaders = processHeaders(applicationConfig$1);
|
|
231
|
+
indexHtmlTemplateContent = fs__default["default"].readFileSync(indexHtmlTemplatePath, 'utf8');
|
|
232
|
+
indexHtmlContent = replaceHtmlPlaceholders(indexHtmlTemplateContent, {
|
|
233
|
+
env: applicationConfig$1.env,
|
|
234
|
+
headers: compiledHeaders
|
|
235
|
+
});
|
|
236
|
+
return _context.abrupt("return", {
|
|
237
|
+
env: applicationConfig$1.env,
|
|
238
|
+
headers: compiledHeaders,
|
|
239
|
+
indexHtmlContent: indexHtmlContent
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
case 5:
|
|
243
|
+
case "end":
|
|
244
|
+
return _context.stop();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}, _callee);
|
|
248
|
+
}));
|
|
249
|
+
return _compileHtml.apply(this, arguments);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
exports.generateTemplate = generateTemplate.generateTemplate;
|
|
253
|
+
exports.compileHtml = compileHtml;
|
|
254
|
+
exports.processHeaders = processHeaders;
|
|
255
|
+
exports.replaceHtmlPlaceholders = replaceHtmlPlaceholders;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _asyncToGenerator = require('@babel/runtime-corejs3/helpers/asyncToGenerator');
|
|
6
|
+
var _regeneratorRuntime = require('@babel/runtime-corejs3/regenerator');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var applicationConfig = require('@commercetools-frontend/application-config');
|
|
9
|
+
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
|
|
10
|
+
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
|
|
11
|
+
var _toConsumableArray = require('@babel/runtime-corejs3/helpers/toConsumableArray');
|
|
12
|
+
var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
|
|
13
|
+
var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
|
|
14
|
+
var _Object$assign = require('@babel/runtime-corejs3/core-js-stable/object/assign');
|
|
15
|
+
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
16
|
+
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
17
|
+
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
|
18
|
+
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
19
|
+
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
|
|
20
|
+
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
|
21
|
+
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
|
|
22
|
+
var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
|
|
23
|
+
var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
|
|
24
|
+
var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
|
|
25
|
+
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
|
|
26
|
+
var constants = require('@commercetools-frontend/constants');
|
|
27
|
+
var crypto = require('crypto');
|
|
28
|
+
var serialize = require('serialize-javascript');
|
|
29
|
+
var generateTemplate = require('./generate-template-600664a1.cjs.prod.js');
|
|
30
|
+
|
|
31
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
32
|
+
|
|
33
|
+
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
|
|
34
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
35
|
+
var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
|
|
36
|
+
var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
|
|
37
|
+
var _Object$assign__default = /*#__PURE__*/_interopDefault(_Object$assign);
|
|
38
|
+
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
39
|
+
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
40
|
+
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
|
41
|
+
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
42
|
+
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
|
|
43
|
+
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
|
44
|
+
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
|
|
45
|
+
var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
|
|
46
|
+
var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
|
|
47
|
+
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
|
|
48
|
+
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
|
|
49
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
50
|
+
var serialize__default = /*#__PURE__*/_interopDefault(serialize);
|
|
51
|
+
|
|
52
|
+
function createAssetHash(content) {
|
|
53
|
+
var sha256Hash = crypto__default["default"].createHash('sha256').update(content).digest('base64');
|
|
54
|
+
/**
|
|
55
|
+
* NOTE:
|
|
56
|
+
* We prefix the hash function type as the browser
|
|
57
|
+
* needs it when validating the contents of a script against
|
|
58
|
+
* CSP headers sent.
|
|
59
|
+
* For more information head to: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
return "sha256-".concat(sha256Hash);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var sanitizeAppEnvironment = function sanitizeAppEnvironment(env) {
|
|
66
|
+
return serialize__default["default"](env, {
|
|
67
|
+
isJSON: true
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function ownKeys(object, enumerableOnly) { var keys = _Object$keys__default["default"](object); if (_Object$getOwnPropertySymbols__default["default"]) { var symbols = _Object$getOwnPropertySymbols__default["default"](object); enumerableOnly && (symbols = _filterInstanceProperty__default["default"](symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor__default["default"](object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
72
|
+
|
|
73
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context11, _context12; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty__default["default"](_context11 = ownKeys(Object(source), !0)).call(_context11, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](target, _Object$getOwnPropertyDescriptors__default["default"](source)) : _forEachInstanceProperty__default["default"](_context12 = ownKeys(Object(source))).call(_context12, function (key) { _Object$defineProperty__default["default"](target, key, _Object$getOwnPropertyDescriptor__default["default"](source, key)); }); } return target; }
|
|
74
|
+
|
|
75
|
+
var htmlScripts$1 = {
|
|
76
|
+
"dataLayer": "window.dataLayer=[{\"gtm.start\":(new Date).getTime(),event:\"gtm.js\"}];",
|
|
77
|
+
"loadingScreen": "window.onAppLoaded=function(){const e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){const e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){const e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
78
|
+
"publicPath": "window.__dynamicImportHandler__=function(n){return window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n.replace(/^(\\.\\/)?/,\"\")},window.__dynamicImportPreload__=function(n){return n.map(n=>window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n)};"
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
var toArray = function toArray(value) {
|
|
82
|
+
return _Array$isArray__default["default"](value) ? value : [value];
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
var mergeCspDirectives = function mergeCspDirectives() {
|
|
86
|
+
for (var _len = arguments.length, directives = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
87
|
+
directives[_key] = arguments[_key];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return _reduceInstanceProperty__default["default"](directives).call(directives, function (mergedCsp, csp) {
|
|
91
|
+
var _context;
|
|
92
|
+
|
|
93
|
+
return _Object$assign__default["default"](mergedCsp, _reduceInstanceProperty__default["default"](_context = _Object$keys__default["default"](csp)).call(_context, function (acc, directiveKey) {
|
|
94
|
+
var _context2;
|
|
95
|
+
|
|
96
|
+
return _Object$assign__default["default"](acc, _defineProperty({}, directiveKey, _concatInstanceProperty__default["default"](_context2 = []).call(_context2, _toConsumableArray(toArray(mergedCsp[directiveKey] ? mergedCsp[directiveKey] : [])), _toConsumableArray(toArray(csp[directiveKey])))));
|
|
97
|
+
}, {}));
|
|
98
|
+
}, {});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
var toHeaderString = function toHeaderString() {
|
|
102
|
+
var _context3;
|
|
103
|
+
|
|
104
|
+
var directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
105
|
+
return _mapInstanceProperty__default["default"](_context3 = _Object$entries__default["default"](directives)).call(_context3, function (_ref) {
|
|
106
|
+
var _context4;
|
|
107
|
+
|
|
108
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
109
|
+
directive = _ref2[0],
|
|
110
|
+
value = _ref2[1];
|
|
111
|
+
|
|
112
|
+
return _concatInstanceProperty__default["default"](_context4 = "".concat(directive, " ")).call(_context4, _Array$isArray__default["default"](value) ? value.join(' ') : value);
|
|
113
|
+
}).join('; ');
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
var toStructuredHeaderString = function toStructuredHeaderString() {
|
|
117
|
+
var _context5;
|
|
118
|
+
|
|
119
|
+
var directives = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
120
|
+
return _mapInstanceProperty__default["default"](_context5 = _Object$entries__default["default"](directives)).call(_context5, function (_ref3) {
|
|
121
|
+
var _context6;
|
|
122
|
+
|
|
123
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
124
|
+
directive = _ref4[0],
|
|
125
|
+
value = _ref4[1];
|
|
126
|
+
|
|
127
|
+
return _concatInstanceProperty__default["default"](_context6 = "".concat(directive, "=")).call(_context6, _Array$isArray__default["default"](value) ? value.join(' ') : value);
|
|
128
|
+
}).join(', ');
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
var processHeaders = function processHeaders(applicationConfig) {
|
|
132
|
+
var _context7, _context8, _context9, _applicationConfig$he, _applicationConfig$he2, _applicationConfig$he3, _context10, _applicationConfig$he4, _applicationConfig$he5;
|
|
133
|
+
|
|
134
|
+
var isMcDevEnv = applicationConfig.env.env === 'development'; // List hashes for injected inline scripts.
|
|
135
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
|
|
136
|
+
|
|
137
|
+
var htmlScriptsHashes = [createAssetHash(htmlScripts$1.loadingScreen), createAssetHash("window.app = ".concat(sanitizeAppEnvironment(applicationConfig.env), ";")), createAssetHash(htmlScripts$1.publicPath), createAssetHash(htmlScripts$1.dataLayer)]; // // List hashes for injected inline styles.
|
|
138
|
+
// // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
|
|
139
|
+
// const htmlStylesHashes = [createAssetHash(htmlStyles.loadingScreen)];
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Content Security Policy (CSP)
|
|
143
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
var cspDirectives = _Object$assign__default["default"]({
|
|
147
|
+
'default-src': "'none'",
|
|
148
|
+
'script-src': _concatInstanceProperty__default["default"](_context7 = ["'self'", 'www.googletagmanager.com/gtm.js', 'www.google-analytics.com/analytics.js']).call(_context7, isMcDevEnv ? // Allow webpack to load source maps on runtime when errors occur
|
|
149
|
+
// using script tags
|
|
150
|
+
['localhost:*', "'unsafe-inline'"] : _mapInstanceProperty__default["default"](htmlScriptsHashes).call(htmlScriptsHashes, function (assetHash) {
|
|
151
|
+
return "'".concat(assetHash, "'");
|
|
152
|
+
})),
|
|
153
|
+
'connect-src': _concatInstanceProperty__default["default"](_context8 = ["'self'", 'app.launchdarkly.com', 'clientstream.launchdarkly.com', 'events.launchdarkly.com', 'app.getsentry.com', // Match all attempts to load from any subdomain of `sentry.io`
|
|
154
|
+
'*.sentry.io', 'www.google-analytics.com']).call(_context8, isMcDevEnv ? ['ws:', 'localhost:8080', 'webpack-internal:'] : []),
|
|
155
|
+
'img-src': ['*', 'data:'],
|
|
156
|
+
'style-src': _concatInstanceProperty__default["default"](_context9 = ["'self'", 'fonts.googleapis.com', 'data:']).call(_context9, // TODO: investigate what needs to be done to avoid unsafe-inline styles
|
|
157
|
+
// https://github.com/commercetools/merchant-center-frontend/pull/5223#discussion_r210367636
|
|
158
|
+
["'unsafe-inline'"] // TODO: enable this once we can avoid unsafe-inline
|
|
159
|
+
// htmlStylesHashes.map(assetHash => `'${assetHash}'`)
|
|
160
|
+
),
|
|
161
|
+
'font-src': ["'self'", 'fonts.gstatic.com', 'data:']
|
|
162
|
+
}, isMcDevEnv ? {
|
|
163
|
+
// NOTE: use this instead of `upgrade-insecure-requests` for local
|
|
164
|
+
// development to avoid `http://localhost` requests to be redirected
|
|
165
|
+
// to https.
|
|
166
|
+
'block-all-mixed-content': ''
|
|
167
|
+
} : {
|
|
168
|
+
// NOTE: prefer this over `block-all-mixed-content`.
|
|
169
|
+
// https://youtu.be/j-0Bj40juMI?t=11m47s
|
|
170
|
+
'upgrade-insecure-requests': ''
|
|
171
|
+
} // NOTE: we might want to define further policies in the future, for example
|
|
172
|
+
// - `require-sri-for style script` (at the moment not possible because
|
|
173
|
+
// GTM and Intercom scripts are apparently not meant for this)
|
|
174
|
+
); // Recursively merge the directives
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
var mergedCsp = mergeCspDirectives(cspDirectives, (_applicationConfig$he = (_applicationConfig$he2 = applicationConfig.headers) === null || _applicationConfig$he2 === void 0 ? void 0 : _applicationConfig$he2.csp) !== null && _applicationConfig$he !== void 0 ? _applicationConfig$he : {});
|
|
178
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, constants.HTTP_SECURITY_HEADERS), {}, {
|
|
179
|
+
// The `Content-Security-Policy` header is always generated
|
|
180
|
+
// based on the Custom Application config.
|
|
181
|
+
'Content-Security-Policy': toHeaderString(mergedCsp)
|
|
182
|
+
}, ((_applicationConfig$he3 = applicationConfig.headers) === null || _applicationConfig$he3 === void 0 ? void 0 : _applicationConfig$he3.strictTransportSecurity) && {
|
|
183
|
+
'Strict-Transport-Security': _concatInstanceProperty__default["default"](_context10 = [constants.HTTP_SECURITY_HEADERS['Strict-Transport-Security']]).call(_context10, _toConsumableArray(applicationConfig.headers.strictTransportSecurity)).join('; ')
|
|
184
|
+
}), ((_applicationConfig$he4 = applicationConfig.headers) === null || _applicationConfig$he4 === void 0 ? void 0 : _applicationConfig$he4.featurePolicies) && {
|
|
185
|
+
'Feature-Policy': toHeaderString(applicationConfig.headers.featurePolicies)
|
|
186
|
+
}), ((_applicationConfig$he5 = applicationConfig.headers) === null || _applicationConfig$he5 === void 0 ? void 0 : _applicationConfig$he5.permissionsPolicies) && {
|
|
187
|
+
'Permissions-Policy': toStructuredHeaderString(applicationConfig.headers.permissionsPolicies)
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
var htmlScripts = {
|
|
192
|
+
"dataLayer": "window.dataLayer=[{\"gtm.start\":(new Date).getTime(),event:\"gtm.js\"}];",
|
|
193
|
+
"loadingScreen": "window.onAppLoaded=function(){const e=document.querySelector(\"#app-loader\");e&&e.parentNode.removeChild(e)},setTimeout(function(){const e=document.querySelector(\".loading-screen\");e&&e.classList.remove(\"loading-screen--hidden\")},250),setTimeout(function(){const e=document.querySelector(\".long-loading-notice\");e&&e.classList.remove(\"long-loading-notice--hidden\")},2e3);",
|
|
194
|
+
"publicPath": "window.__dynamicImportHandler__=function(n){return window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n.replace(/^(\\.\\/)?/,\"\")},window.__dynamicImportPreload__=function(n){return n.map(n=>window.app.cdnUrl.replace(/\\/$/,\"\")+\"/\"+n)};"
|
|
195
|
+
}; // https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros
|
|
196
|
+
|
|
197
|
+
var htmlStyles = {
|
|
198
|
+
"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}"
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
var trimTrailingSlash = function trimTrailingSlash(value) {
|
|
202
|
+
return value.replace(/\/$/, '');
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
var getGtmTrackingScript = function getGtmTrackingScript(gtmId) {
|
|
206
|
+
if (!gtmId) return '';
|
|
207
|
+
var url = "https://www.googletagmanager.com/gtm.js?id=".concat(gtmId);
|
|
208
|
+
return "\n<script async type=\"text/javascript\" src=\"".concat(url, "\" referrerpolicy=\"no-referrer\"></script>\n ");
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
var replaceHtmlPlaceholders = function replaceHtmlPlaceholders(indexHtmlContent, options) {
|
|
212
|
+
var _options$headers$Cont, _options$headers;
|
|
213
|
+
|
|
214
|
+
return indexHtmlContent.replace(new RegExp('__CSP__', 'g'), (_options$headers$Cont = (_options$headers = options.headers) === null || _options$headers === void 0 ? void 0 : _options$headers['Content-Security-Policy']) !== null && _options$headers$Cont !== void 0 ? _options$headers$Cont : '').replace(new RegExp('__CDN_URL__', 'g'), options.env.cdnUrl ? // Ensure there is a trailing slash
|
|
215
|
+
"".concat(trimTrailingSlash(options.env.cdnUrl), "/") : '').replace(new RegExp('__MC_API_URL__', 'g'), trimTrailingSlash(options.env.mcApiUrl)).replace(new RegExp('__APPLICATION_ENVIRONMENT__', 'g'), sanitizeAppEnvironment(options.env)).replace(new RegExp('__GTM_SCRIPT__', 'g'), getGtmTrackingScript(options.env.trackingGtm)).replace(new RegExp('__DATALAYER_JS__', 'g'), "<script>".concat(htmlScripts.dataLayer, "</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>"));
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
function compileHtml(_x) {
|
|
219
|
+
return _compileHtml.apply(this, arguments);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function _compileHtml() {
|
|
223
|
+
_compileHtml = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee(indexHtmlTemplatePath) {
|
|
224
|
+
var applicationConfig$1, compiledHeaders, indexHtmlTemplateContent, indexHtmlContent;
|
|
225
|
+
return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
|
|
226
|
+
while (1) {
|
|
227
|
+
switch (_context.prev = _context.next) {
|
|
228
|
+
case 0:
|
|
229
|
+
applicationConfig$1 = applicationConfig.processConfig();
|
|
230
|
+
compiledHeaders = processHeaders(applicationConfig$1);
|
|
231
|
+
indexHtmlTemplateContent = fs__default["default"].readFileSync(indexHtmlTemplatePath, 'utf8');
|
|
232
|
+
indexHtmlContent = replaceHtmlPlaceholders(indexHtmlTemplateContent, {
|
|
233
|
+
env: applicationConfig$1.env,
|
|
234
|
+
headers: compiledHeaders
|
|
235
|
+
});
|
|
236
|
+
return _context.abrupt("return", {
|
|
237
|
+
env: applicationConfig$1.env,
|
|
238
|
+
headers: compiledHeaders,
|
|
239
|
+
indexHtmlContent: indexHtmlContent
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
case 5:
|
|
243
|
+
case "end":
|
|
244
|
+
return _context.stop();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}, _callee);
|
|
248
|
+
}));
|
|
249
|
+
return _compileHtml.apply(this, arguments);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
exports.generateTemplate = generateTemplate.generateTemplate;
|
|
253
|
+
exports.compileHtml = compileHtml;
|
|
254
|
+
exports.processHeaders = processHeaders;
|
|
255
|
+
exports.replaceHtmlPlaceholders = replaceHtmlPlaceholders;
|