@adobe/helix-html-pipeline 5.0.12 → 5.1.1
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/CHANGELOG.md +21 -0
- package/package.json +6 -6
- package/src/options-pipe.js +59 -0
- package/src/steps/fetch-content.js +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [5.1.1](https://github.com/adobe/helix-html-pipeline/compare/v5.1.0...v5.1.1) (2023-11-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* append .plain.html in redirects if needed ([#452](https://github.com/adobe/helix-html-pipeline/issues/452)) ([d3035a1](https://github.com/adobe/helix-html-pipeline/commit/d3035a1f593b0ac39fd9bd2ce68c8bcb83fe06b4)), closes [#451](https://github.com/adobe/helix-html-pipeline/issues/451)
|
|
7
|
+
* increase test time ([336bda0](https://github.com/adobe/helix-html-pipeline/commit/336bda099dae3a3faea26c71984693a2cd3a998f))
|
|
8
|
+
|
|
9
|
+
# [5.1.0](https://github.com/adobe/helix-html-pipeline/compare/v5.0.12...v5.1.0) (2023-11-06)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **options:** use request.url.pathname ([0086a2d](https://github.com/adobe/helix-html-pipeline/commit/0086a2dd4d9b8dc6b8845dab6e7bf0f63132fbdc))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **domainkeys:** support arrays of domainkeys in config ([f90b3b6](https://github.com/adobe/helix-html-pipeline/commit/f90b3b6a6b67804cf8b6e24e950769cdf70313be))
|
|
20
|
+
* **options:** add support for domainkey challenges ([8153afc](https://github.com/adobe/helix-html-pipeline/commit/8153afc8fa49cfca20763c982cadb36f30382525))
|
|
21
|
+
|
|
1
22
|
## [5.0.12](https://github.com/adobe/helix-html-pipeline/compare/v5.0.11...v5.0.12) (2023-10-31)
|
|
2
23
|
|
|
3
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-html-pipeline",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "Helix HTML Pipeline",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"hast-util-to-html": "9.0.0",
|
|
54
54
|
"hast-util-to-string": "3.0.0",
|
|
55
55
|
"hastscript": "8.0.0",
|
|
56
|
-
"jose": "5.0
|
|
56
|
+
"jose": "5.1.0",
|
|
57
57
|
"mdast-util-to-hast": "13.0.2",
|
|
58
58
|
"mdast-util-to-string": "4.0.0",
|
|
59
59
|
"mime": "3.0.0",
|
|
@@ -74,13 +74,13 @@
|
|
|
74
74
|
"@markedjs/html-differ": "4.0.2",
|
|
75
75
|
"@semantic-release/changelog": "6.0.3",
|
|
76
76
|
"@semantic-release/git": "10.0.1",
|
|
77
|
-
"@semantic-release/npm": "11.0.
|
|
77
|
+
"@semantic-release/npm": "11.0.1",
|
|
78
78
|
"c8": "8.0.1",
|
|
79
|
-
"eslint": "8.
|
|
79
|
+
"eslint": "8.53.0",
|
|
80
80
|
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
|
81
81
|
"eslint-plugin-header": "3.1.1",
|
|
82
82
|
"eslint-plugin-import": "2.29.0",
|
|
83
|
-
"esmock": "2.5.
|
|
83
|
+
"esmock": "2.5.9",
|
|
84
84
|
"husky": "8.0.3",
|
|
85
85
|
"js-yaml": "4.1.0",
|
|
86
86
|
"jsdom": "22.1.0",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"mocha": "10.2.0",
|
|
90
90
|
"mocha-multi-reporters": "1.5.1",
|
|
91
91
|
"mocha-suppress-logs": "0.4.1",
|
|
92
|
-
"semantic-release": "22.0.
|
|
92
|
+
"semantic-release": "22.0.7"
|
|
93
93
|
},
|
|
94
94
|
"lint-staged": {
|
|
95
95
|
"*.js": "eslint",
|
package/src/options-pipe.js
CHANGED
|
@@ -10,12 +10,70 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
import { cleanupHeaderValue } from '@adobe/helix-shared-utils';
|
|
13
|
+
import { createHash } from 'crypto';
|
|
13
14
|
import { PipelineResponse } from './PipelineResponse.js';
|
|
14
15
|
import fetchConfigAll from './steps/fetch-config-all.js';
|
|
15
16
|
import setCustomResponseHeaders from './steps/set-custom-response-headers.js';
|
|
16
17
|
import fetchConfig from './steps/fetch-config.js';
|
|
17
18
|
import { PipelineStatusError } from './PipelineStatusError.js';
|
|
19
|
+
import { getOriginalHost } from './steps/utils.js';
|
|
18
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Hashes the domain and domainkey
|
|
23
|
+
* @param {string} domain the domain
|
|
24
|
+
* @param {string|string[]} domainkeys the domainkey or domainkeys
|
|
25
|
+
* @returns {string} the hash
|
|
26
|
+
*/
|
|
27
|
+
function hashMe(domain, domainkeys) {
|
|
28
|
+
return (Array.isArray(domainkeys) ? domainkeys : [domainkeys]).map((dk) => {
|
|
29
|
+
const hash = createHash('sha256');
|
|
30
|
+
hash.update(domain);
|
|
31
|
+
hash.update(dk);
|
|
32
|
+
return hash.digest('hex');
|
|
33
|
+
}).join(' ');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* If the request is a _rum-challenge request, then set the x-rum-challenge header
|
|
38
|
+
* A rum-challenge request is an OPTIONS request to any path ending with _rum-challenge
|
|
39
|
+
* and will return a 204 response with the x-rum-challenge header set to the hash of
|
|
40
|
+
* the x-forwarded-host and the domainkey. If no domainkey has been set in .helix/config
|
|
41
|
+
* then the `slack` channel will be used instead.
|
|
42
|
+
* @param {object} state current pipeline state
|
|
43
|
+
* @param {Request} request HTTP request
|
|
44
|
+
* @param {Response} response HTTP response
|
|
45
|
+
* @returns {void}
|
|
46
|
+
*/
|
|
47
|
+
function setDomainkeyHeader(state, request, response) {
|
|
48
|
+
// nope out if path does not end with _rum-challenge
|
|
49
|
+
if (!request.url.pathname.endsWith('/_rum-challenge')) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// get x-forwarded-host
|
|
53
|
+
const originalHost = getOriginalHost(request.headers);
|
|
54
|
+
// get liveHost
|
|
55
|
+
const { host } = state.config;
|
|
56
|
+
|
|
57
|
+
if (originalHost !== host) {
|
|
58
|
+
// these have to match
|
|
59
|
+
state.log.debug(`x-forwarded-host: ${originalHost} does not match prod host: ${host}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// get domainkey from config
|
|
63
|
+
const { domainkey } = state.config;
|
|
64
|
+
// get slack channel from config
|
|
65
|
+
const { slack } = state.config;
|
|
66
|
+
let hash;
|
|
67
|
+
if (typeof domainkey === 'string' || Array.isArray(domainkey)) {
|
|
68
|
+
hash = hashMe(originalHost, domainkey);
|
|
69
|
+
} else if (typeof slack === 'string' || Array.isArray(slack)) {
|
|
70
|
+
hash = hashMe(originalHost, slack);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (hash) {
|
|
74
|
+
response.headers.set('x-rum-challenge', hash);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
19
77
|
/**
|
|
20
78
|
* Handles options requests
|
|
21
79
|
* @param {PipelineState} state pipeline options
|
|
@@ -46,6 +104,7 @@ export async function optionsPipe(state, request) {
|
|
|
46
104
|
});
|
|
47
105
|
await fetchConfigAll(state, request, res);
|
|
48
106
|
await setCustomResponseHeaders(state, request, res);
|
|
107
|
+
setDomainkeyHeader(state, request, res);
|
|
49
108
|
|
|
50
109
|
return res;
|
|
51
110
|
} catch (e) {
|
|
@@ -37,10 +37,13 @@ export default async function fetchContent(state, req, res) {
|
|
|
37
37
|
const ret = await state.s3Loader.getObject(bucketId, key);
|
|
38
38
|
|
|
39
39
|
// check for redirect
|
|
40
|
-
|
|
40
|
+
let redirectLocation = ret.headers.get('x-amz-meta-redirect-location');
|
|
41
41
|
if (redirectLocation) {
|
|
42
42
|
res.status = 301;
|
|
43
43
|
res.body = '';
|
|
44
|
+
if (redirectLocation.startsWith('/') && state.info.selector === 'plain') {
|
|
45
|
+
redirectLocation += '.plain.html';
|
|
46
|
+
}
|
|
44
47
|
res.headers.set('location', redirectLocation);
|
|
45
48
|
res.headers.set('x-surrogate-key', await computeSurrogateKey(`${contentBusId}${info.path}`));
|
|
46
49
|
res.error = 'moved';
|