@adobe/helix-html-pipeline 5.1.3 → 5.3.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 CHANGED
@@ -1,3 +1,17 @@
1
+ # [5.3.0](https://github.com/adobe/helix-html-pipeline/compare/v5.2.0...v5.3.0) (2023-12-05)
2
+
3
+
4
+ ### Features
5
+
6
+ * add xfh debug ([#468](https://github.com/adobe/helix-html-pipeline/issues/468)) ([940a57b](https://github.com/adobe/helix-html-pipeline/commit/940a57bee7a0b7c394c08da59c3a66b7a1d5868d))
7
+
8
+ # [5.2.0](https://github.com/adobe/helix-html-pipeline/compare/v5.1.3...v5.2.0) (2023-11-15)
9
+
10
+
11
+ ### Features
12
+
13
+ * implement partition specific auth ([#456](https://github.com/adobe/helix-html-pipeline/issues/456)) ([89fa4f1](https://github.com/adobe/helix-html-pipeline/commit/89fa4f1a7a8ddaecad3659f6eaa37416a4452744)), closes [#274](https://github.com/adobe/helix-html-pipeline/issues/274)
14
+
1
15
  ## [5.1.3](https://github.com/adobe/helix-html-pipeline/compare/v5.1.2...v5.1.3) (2023-11-11)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "5.1.3",
3
+ "version": "5.3.0",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -53,10 +53,10 @@
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.1.0",
56
+ "jose": "5.1.3",
57
57
  "mdast-util-to-hast": "13.0.2",
58
58
  "mdast-util-to-string": "4.0.0",
59
- "mime": "3.0.0",
59
+ "mime": "4.0.0",
60
60
  "rehype-format": "5.0.0",
61
61
  "rehype-parse": "9.0.0",
62
62
  "remark-parse": "11.0.0",
@@ -70,26 +70,26 @@
70
70
  "unist-util-visit-parents": "6.0.1"
71
71
  },
72
72
  "devDependencies": {
73
- "@adobe/eslint-config-helix": "2.0.4",
73
+ "@adobe/eslint-config-helix": "2.0.5",
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
77
  "@semantic-release/npm": "11.0.1",
78
78
  "c8": "8.0.1",
79
- "eslint": "8.53.0",
79
+ "eslint": "8.55.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
83
  "esmock": "2.6.0",
84
84
  "husky": "8.0.3",
85
85
  "js-yaml": "4.1.0",
86
- "jsdom": "22.1.0",
86
+ "jsdom": "23.0.1",
87
87
  "junit-report-builder": "3.1.0",
88
88
  "lint-staged": "15.1.0",
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.7"
92
+ "semantic-release": "22.0.8"
93
93
  },
94
94
  "lint-staged": {
95
95
  "*.js": "eslint",
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
  import { getAuthInfo, makeAuthError } from '../utils/auth.js';
13
+ import { toArray } from './utils.js';
13
14
 
14
15
  /**
15
16
  * Checks if the given email is allowed.
@@ -27,6 +28,26 @@ export function isAllowed(email = '', allows = []) {
27
28
  return allows.findIndex((a) => a === email || a === wild) >= 0;
28
29
  }
29
30
 
31
+ /**
32
+ * Returns the normalized access configuration for the current partition.
33
+ * @param state
34
+ * @return {{}}
35
+ */
36
+ export function getAccessConfig(state) {
37
+ const { access } = state.config;
38
+ if (!access) {
39
+ return {
40
+ allow: [],
41
+ apiKeyId: [],
42
+ };
43
+ }
44
+ const { partition } = state;
45
+ return {
46
+ allow: toArray(access[partition]?.allow ?? access.allow),
47
+ apiKeyId: toArray(access[partition]?.apiKeyId ?? access.apiKeyId),
48
+ };
49
+ }
50
+
30
51
  /**
31
52
  * Handles authentication
32
53
  * @type PipelineStep
@@ -43,8 +64,11 @@ export async function authenticate(state, req, res) {
43
64
  return;
44
65
  }
45
66
 
67
+ // get partition relative auth info
68
+ const access = getAccessConfig(state);
69
+
46
70
  // if not protected, do nothing
47
- if (!state.config?.access?.allow) {
71
+ if (!access.allow.length) {
48
72
  return;
49
73
  }
50
74
 
@@ -77,20 +101,15 @@ export async function authenticate(state, req, res) {
77
101
 
78
102
  // validate jti
79
103
  if (jti) {
80
- const ids = Array.isArray(state.config.access.apiKeyId)
81
- ? state.config.access.apiKeyId
82
- : [state.config.access.apiKeyId];
83
- if (ids.indexOf(jti) < 0) {
84
- state.log.warn(`[auth] invalid jti ${jti}: does not match configured id ${state.config.access.apiKeyId}`);
104
+ if (access.apiKeyId.indexOf(jti) < 0) {
105
+ state.log.warn(`[auth] invalid jti ${jti}: does not match configured id ${access.apiKeyId}`);
85
106
  makeAuthError(state, req, res, 'invalid-jti');
86
107
  }
87
108
  }
88
109
 
89
110
  // check profile is allowed
90
- const { allow } = state.config.access;
91
- const allows = Array.isArray(allow) ? allow : [allow];
92
- if (!isAllowed(email, allows)) {
93
- state.log.warn(`[auth] profile not allowed for ${allows}`);
111
+ if (!isAllowed(email, access.allow)) {
112
+ state.log.warn(`[auth] profile not allowed for ${access.allow}`);
94
113
  makeAuthError(state, req, res, 'forbidden', 403);
95
114
  }
96
115
  }
@@ -216,3 +216,10 @@ export function rewriteUrl(state, url) {
216
216
 
217
217
  return url;
218
218
  }
219
+
220
+ export function toArray(v) {
221
+ if (!v) {
222
+ return [];
223
+ }
224
+ return Array.isArray(v) ? v : [v];
225
+ }
package/src/utils/auth.js CHANGED
@@ -109,7 +109,8 @@ export async function decodeIdToken(state, idToken, lenient = false) {
109
109
  function getRequestHostAndProto(state, req) {
110
110
  // determine the location of 'this' document based on the xfh header. so that logins to
111
111
  // .page stay on .page. etc. but fallback to the config.host if non set
112
- let host = req.headers.get('x-forwarded-host');
112
+ const xfh = req.headers.get('x-forwarded-host');
113
+ let host = xfh;
113
114
  if (host) {
114
115
  host = host.split(',')[0].trim();
115
116
  }
@@ -118,7 +119,7 @@ function getRequestHostAndProto(state, req) {
118
119
  }
119
120
  // fastly overrides the x-forwarded-proto, so we use x-forwarded-scheme
120
121
  const proto = req.headers.get('x-forwarded-scheme') || req.headers.get('x-forwarded-proto') || 'https';
121
- state.log.info(`request host is: ${host} (${proto})`);
122
+ state.log.info(`request host is: ${host} (${proto}) (xfh=${xfh})`);
122
123
  return {
123
124
  host,
124
125
  proto,
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
  import { PipelineStatusError } from '../PipelineStatusError.js';
13
+ import { toArray } from '../steps/utils.js';
13
14
 
14
15
  const TYPE_KEY = ':type';
15
16
 
@@ -78,7 +79,7 @@ export default function jsonFilter(state, res, query) {
78
79
  }
79
80
 
80
81
  state.timer?.update('json-filter');
81
- const requestedSheets = Array.isArray(sheet) ? sheet : [sheet];
82
+ const requestedSheets = toArray(sheet);
82
83
  if (requestedSheets.length === 0 && 'default' in json) {
83
84
  requestedSheets.push('default');
84
85
  }