@adobe/helix-html-pipeline 3.4.6 → 3.6.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
+ # [3.6.0](https://github.com/adobe/helix-html-pipeline/compare/v3.5.0...v3.6.0) (2022-10-27)
2
+
3
+
4
+ ### Features
5
+
6
+ * also support x-fwd-scheme ([#172](https://github.com/adobe/helix-html-pipeline/issues/172)) ([845a5a0](https://github.com/adobe/helix-html-pipeline/commit/845a5a0dada33a3950ffed4f7d6a52090fa6de9a))
7
+
8
+ # [3.5.0](https://github.com/adobe/helix-html-pipeline/compare/v3.4.6...v3.5.0) (2022-10-26)
9
+
10
+
11
+ ### Features
12
+
13
+ * respect x-forwarded-proto in auth ([#171](https://github.com/adobe/helix-html-pipeline/issues/171)) ([cae61e1](https://github.com/adobe/helix-html-pipeline/commit/cae61e15f16903bc298c4dd5a4a6f7b1379e5ae5))
14
+
1
15
  ## [3.4.6](https://github.com/adobe/helix-html-pipeline/compare/v3.4.5...v3.4.6) (2022-10-22)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "3.4.6",
3
+ "version": "3.6.0",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -48,7 +48,7 @@
48
48
  "hast-util-to-html": "8.0.3",
49
49
  "hast-util-to-string": "2.0.0",
50
50
  "hastscript": "7.1.0",
51
- "jose": "4.10.0",
51
+ "jose": "4.10.3",
52
52
  "mdast-util-gfm-footnote": "1.0.1",
53
53
  "mdast-util-gfm-strikethrough": "1.0.1",
54
54
  "mdast-util-gfm-table": "1.0.6",
@@ -81,7 +81,7 @@
81
81
  "@semantic-release/git": "10.0.1",
82
82
  "@semantic-release/npm": "9.0.1",
83
83
  "c8": "7.12.0",
84
- "eslint": "8.25.0",
84
+ "eslint": "8.26.0",
85
85
  "eslint-import-resolver-exports": "1.0.0-beta.3",
86
86
  "eslint-plugin-header": "3.1.1",
87
87
  "eslint-plugin-import": "2.26.0",
@@ -91,7 +91,7 @@
91
91
  "jsdom": "20.0.1",
92
92
  "junit-report-builder": "3.0.1",
93
93
  "lint-staged": "13.0.3",
94
- "mocha": "10.0.0",
94
+ "mocha": "10.1.0",
95
95
  "mocha-multi-reporters": "1.5.1",
96
96
  "remark-gfm": "3.0.1",
97
97
  "semantic-release": "19.0.5"
@@ -11,21 +11,21 @@
11
11
  */
12
12
  import { parse, serialize } from 'cookie';
13
13
 
14
- export function clearAuthCookie() {
14
+ export function clearAuthCookie(secure) {
15
15
  return serialize('hlx-auth-token', '', {
16
16
  path: '/',
17
17
  httpOnly: true,
18
- secure: true,
18
+ secure,
19
19
  expires: new Date(0),
20
20
  sameSite: 'lax',
21
21
  });
22
22
  }
23
23
 
24
- export function setAuthCookie(idToken) {
24
+ export function setAuthCookie(idToken, secure) {
25
25
  return serialize('hlx-auth-token', idToken, {
26
26
  path: '/',
27
27
  httpOnly: true,
28
- secure: true,
28
+ secure,
29
29
  sameSite: 'lax',
30
30
  });
31
31
  }
package/src/utils/auth.js CHANGED
@@ -79,9 +79,9 @@ export async function decodeIdToken(state, idp, idToken, lenient = false) {
79
79
  *
80
80
  * @param {PipelineState} state
81
81
  * @param {PipelineRequest} req
82
- * @return {string}
82
+ * @returns {{proto: (*|string), host: string}} the request host and protocol.
83
83
  */
84
- function getRequestHost(state, req) {
84
+ function getRequestHostAndProto(state, req) {
85
85
  // determine the location of 'this' document based on the xfh header. so that logins to
86
86
  // .page stay on .page. etc. but fallback to the config.host if non set
87
87
  let host = req.headers.get('x-forwarded-host');
@@ -91,8 +91,13 @@ function getRequestHost(state, req) {
91
91
  if (!host) {
92
92
  host = state.config.host;
93
93
  }
94
- state.log.info(`request host is: ${host}`);
95
- return host;
94
+ // fastly overrides the x-forwarded-proto, so we use x-forwarded-scheme
95
+ const proto = req.headers.get('x-forwarded-scheme') || req.headers.get('x-forwarded-proto') || 'https';
96
+ state.log.info(`request host is: ${host} (${proto})`);
97
+ return {
98
+ host,
99
+ proto,
100
+ };
96
101
  }
97
102
 
98
103
  /**
@@ -181,7 +186,7 @@ export class AuthInfo {
181
186
 
182
187
  // determine the location of 'this' document based on the xfh header. so that logins to
183
188
  // .page stay on .page. etc. but fallback to the config.host if non set
184
- const host = getRequestHost(state, req);
189
+ const { host, proto } = getRequestHostAndProto(state, req);
185
190
  if (!host) {
186
191
  log.error('[auth] unable to create login redirect: no xfh or config.host.');
187
192
  res.status = 401;
@@ -199,6 +204,7 @@ export class AuthInfo {
199
204
  // this is our own login redirect, i.e. the current document
200
205
  requestPath: state.info.path,
201
206
  requestHost: host,
207
+ requestProto: proto,
202
208
  }).encode();
203
209
 
204
210
  url.searchParams.append('client_id', clientId);
@@ -213,7 +219,7 @@ export class AuthInfo {
213
219
  res.status = 302;
214
220
  res.body = '';
215
221
  res.headers.set('location', url.href);
216
- res.headers.set('set-cookie', clearAuthCookie());
222
+ res.headers.set('set-cookie', clearAuthCookie(proto === 'https'));
217
223
  res.headers.set('cache-control', 'no-store, private, must-revalidate');
218
224
  res.error = 'moved';
219
225
  }
@@ -239,9 +245,9 @@ export class AuthInfo {
239
245
 
240
246
  // ensure that the request is made to the target host
241
247
  if (req.params.state?.requestHost) {
242
- const host = getRequestHost(state, req);
248
+ const { host } = getRequestHostAndProto(state, req);
243
249
  if (host !== req.params.state.requestHost) {
244
- const url = new URL(`https://${req.params.state.requestHost}/.auth`);
250
+ const url = new URL(`${req.params.state.requestProto}://${req.params.state.requestHost}/.auth`);
245
251
  url.searchParams.append('state', req.params.rawState);
246
252
  url.searchParams.append('code', req.params.code);
247
253
  const location = state.createExternalLocation(url.href);
@@ -294,12 +300,12 @@ export class AuthInfo {
294
300
  // ctx.attributes.authInfo?.withCookieInvalid(false);
295
301
 
296
302
  const location = state.createExternalLocation(req.params.state.requestPath || '/');
297
- log.info('[auth] redirecting to home page with id_token cookie', location);
303
+ log.info('[auth] redirecting to original page with hlx-auth-token cookie: ', location);
298
304
  res.status = 302;
299
305
  res.body = `please go to <a href="${location}">${location}</a>`;
300
306
  res.headers.set('location', location);
301
307
  res.headers.set('content-tye', 'text/plain');
302
- res.headers.set('set-cookie', setAuthCookie(idToken));
308
+ res.headers.set('set-cookie', setAuthCookie(idToken, req.params.state.requestProto === 'https'));
303
309
  res.headers.set('cache-control', 'no-store, private, must-revalidate');
304
310
  res.error = 'moved';
305
311
  }