@adobe/helix-html-pipeline 6.0.0 → 6.1.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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/PipelineState.d.ts +12 -0
- package/src/PipelineState.js +7 -0
- package/src/html-pipe.js +12 -5
- package/src/index.js +1 -0
- package/src/steps/authenticate.js +0 -7
- package/src/steps/fetch-content.js +0 -4
- package/src/utils/auth.js +13 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [6.1.0](https://github.com/adobe/helix-html-pipeline/compare/v6.0.1...v6.1.0) (2024-01-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* export state decoding ([#489](https://github.com/adobe/helix-html-pipeline/issues/489)) ([dd60f81](https://github.com/adobe/helix-html-pipeline/commit/dd60f81e52e52652616edd67779f6e9098e50a1b))
|
|
7
|
+
|
|
8
|
+
## [6.0.1](https://github.com/adobe/helix-html-pipeline/compare/v6.0.0...v6.0.1) (2024-01-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* enforce rso ([#488](https://github.com/adobe/helix-html-pipeline/issues/488)) ([4b38e25](https://github.com/adobe/helix-html-pipeline/commit/4b38e2524514a3d64a041d456bf14fe8b2e416cb))
|
|
14
|
+
|
|
1
15
|
# [6.0.0](https://github.com/adobe/helix-html-pipeline/compare/v5.4.4...v6.0.0) (2024-01-10)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
package/src/PipelineState.d.ts
CHANGED
|
@@ -43,6 +43,8 @@ declare interface PipelineOptions {
|
|
|
43
43
|
path: string;
|
|
44
44
|
timer: PipelineTimer;
|
|
45
45
|
env: object;
|
|
46
|
+
site: string;
|
|
47
|
+
org: string;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
declare class PipelineState {
|
|
@@ -70,6 +72,16 @@ declare class PipelineState {
|
|
|
70
72
|
*/
|
|
71
73
|
partition: string;
|
|
72
74
|
|
|
75
|
+
/**
|
|
76
|
+
* project site
|
|
77
|
+
*/
|
|
78
|
+
site: string;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* project org
|
|
82
|
+
*/
|
|
83
|
+
org: string;
|
|
84
|
+
|
|
73
85
|
/**
|
|
74
86
|
* Repository owner
|
|
75
87
|
*/
|
package/src/PipelineState.js
CHANGED
|
@@ -31,6 +31,8 @@ export class PipelineState {
|
|
|
31
31
|
config: opts.config,
|
|
32
32
|
content: new PipelineContent(),
|
|
33
33
|
contentBusId: opts.config.contentBusId,
|
|
34
|
+
site: opts.site,
|
|
35
|
+
org: opts.org,
|
|
34
36
|
owner: opts.config.owner,
|
|
35
37
|
repo: opts.config.repo,
|
|
36
38
|
ref: opts.ref,
|
|
@@ -44,6 +46,11 @@ export class PipelineState {
|
|
|
44
46
|
timer: opts.timer,
|
|
45
47
|
type: 'html',
|
|
46
48
|
});
|
|
49
|
+
for (const prop of ['org', 'site', 'contentBusId', 'repo', 'owner', 'ref', 'partition']) {
|
|
50
|
+
if (!this[prop]) {
|
|
51
|
+
throw new Error(`${prop} required`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
// eslint-disable-next-line class-methods-use-this
|
package/src/html-pipe.js
CHANGED
|
@@ -36,7 +36,7 @@ import tohtml from './steps/stringify-response.js';
|
|
|
36
36
|
import { PipelineStatusError } from './PipelineStatusError.js';
|
|
37
37
|
import { PipelineResponse } from './PipelineResponse.js';
|
|
38
38
|
import { validatePathInfo } from './utils/path.js';
|
|
39
|
-
import {
|
|
39
|
+
import { getAuthInfo } from './utils/auth.js';
|
|
40
40
|
import fetchMappedMetadata from './steps/fetch-mapped-metadata.js';
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -104,11 +104,18 @@ export async function htmlPipe(state, req) {
|
|
|
104
104
|
},
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
// check if
|
|
108
|
-
if (state.partition === '.auth'
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
// check if `.auth` route to validate and exchange token
|
|
108
|
+
if (state.partition === '.auth') {
|
|
109
|
+
const authInfo = await getAuthInfo(state, req);
|
|
110
|
+
await authInfo.exchangeToken(state, req, res);
|
|
111
|
+
/* c8 ignore next */
|
|
112
|
+
const level = res.status >= 500 ? 'error' : 'info';
|
|
113
|
+
log[level](`pipeline status: ${res.status} ${res.error}`);
|
|
114
|
+
res.headers.set('x-error', cleanupHeaderValue(res.error));
|
|
115
|
+
if (res.status < 500) {
|
|
116
|
+
await setCustomResponseHeaders(state, req, res);
|
|
111
117
|
}
|
|
118
|
+
return res;
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
try {
|
package/src/index.js
CHANGED
|
@@ -36,13 +36,6 @@ export function isAllowed(email = '', allows = []) {
|
|
|
36
36
|
* @returns {Promise<void>}
|
|
37
37
|
*/
|
|
38
38
|
export async function authenticate(state, req, res) {
|
|
39
|
-
// check if `.auth` route to validate and exchange token
|
|
40
|
-
if (state.info.path === '/.auth') {
|
|
41
|
-
const authInfo = await getAuthInfo(state, req);
|
|
42
|
-
await authInfo.exchangeToken(state, req, res);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
39
|
// get partition relative auth info
|
|
47
40
|
const access = state.config.access?.[state.partition] || {
|
|
48
41
|
allow: [],
|
|
@@ -24,10 +24,6 @@ export default async function fetchContent(state, req, res) {
|
|
|
24
24
|
const {
|
|
25
25
|
log, contentBusId, info, partition, owner, repo, ref,
|
|
26
26
|
} = state;
|
|
27
|
-
if (info.resourcePath === '/.auth') {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
27
|
const isCode = state.content.sourceBus === 'code';
|
|
32
28
|
const key = isCode
|
|
33
29
|
? `${owner}/${repo}/${ref}${info.resourcePath}`
|
package/src/utils/auth.js
CHANGED
|
@@ -239,8 +239,9 @@ export class AuthInfo {
|
|
|
239
239
|
const url = new URL(idp.discovery.authorization_endpoint);
|
|
240
240
|
|
|
241
241
|
const tokenState = await signJWT(state, new SignJWT({
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
ref: state.ref,
|
|
243
|
+
org: state.org,
|
|
244
|
+
site: state.site,
|
|
244
245
|
// this is our own login redirect, i.e. the current document
|
|
245
246
|
requestPath: state.info.path,
|
|
246
247
|
requestHost: host,
|
|
@@ -369,9 +370,8 @@ export class AuthInfo {
|
|
|
369
370
|
}
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
export async function
|
|
373
|
-
const { log } =
|
|
374
|
-
|
|
373
|
+
export async function validateAuthState(ctx, req) {
|
|
374
|
+
const { log } = ctx;
|
|
375
375
|
// use request headers if present
|
|
376
376
|
if (req.headers.get('x-hlx-auth-state')) {
|
|
377
377
|
log.info('[auth] override params.state from header.');
|
|
@@ -384,28 +384,24 @@ export async function initAuthRoute(state, req, res) {
|
|
|
384
384
|
|
|
385
385
|
if (!req.params.state) {
|
|
386
386
|
log.warn('[auth] unable to exchange token: no state.');
|
|
387
|
-
|
|
388
|
-
return false;
|
|
387
|
+
throw new Error('missing state parameter.');
|
|
389
388
|
}
|
|
390
389
|
|
|
391
390
|
try {
|
|
392
391
|
req.params.rawState = req.params.state;
|
|
393
|
-
req.params.state = await verifyJwt(
|
|
392
|
+
req.params.state = await verifyJwt(ctx, req.params.state);
|
|
394
393
|
delete req.params.state.aud;
|
|
395
394
|
delete req.params.state.iss;
|
|
396
395
|
} catch (e) {
|
|
397
396
|
log.warn(`[auth] error decoding state parameter: invalid state: ${e.message}`);
|
|
398
|
-
|
|
399
|
-
return false;
|
|
397
|
+
throw new Error('invalid state parameter.');
|
|
400
398
|
}
|
|
401
399
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
state.info.path = '/.auth';
|
|
408
|
-
return true;
|
|
400
|
+
return {
|
|
401
|
+
ref: req.params.state.ref,
|
|
402
|
+
site: req.params.state.site,
|
|
403
|
+
org: req.params.state.org,
|
|
404
|
+
};
|
|
409
405
|
}
|
|
410
406
|
|
|
411
407
|
/**
|