@proteinjs/user-server 1.10.1 → 1.10.3

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
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.10.3](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.10.2...@proteinjs/user-server@1.10.3) (2026-08-28)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * avatar route reads bytes through the driver door — its own access decision, not the gated service read ([0fbf954](https://github.com/proteinjs/user/commit/0fbf95439b11bb4c67ad6109eb7d519d0c8788e1))
12
+
13
+
14
+
15
+
16
+
17
+ ## [1.10.2](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.10.1...@proteinjs/user-server@1.10.2) (2026-08-27)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * /dev/login first-hit lands on the login form — diagnosed to runtime passport skew; establishSession now refuses a non-regenerating login instead of silently racing ([a34a85e](https://github.com/proteinjs/user/commit/a34a85e088dcf212d4bb1e79c162b716e8d6a444))
23
+
24
+
25
+
26
+
27
+
6
28
  ## [1.10.1](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.10.0...@proteinjs/user-server@1.10.1) (2026-08-26)
7
29
 
8
30
 
@@ -19,8 +19,15 @@
19
19
  * real passport machinery.
20
20
  *
21
21
  * COUPLED to the passport 0.6 upgrade in @proteinjs/server (which supplies the runtime passport
22
- * middleware): under passport 0.4, `request.login` neither regenerates nor saves — shipping this
23
- * package against a pre-0.6 @proteinjs/server would silently reopen both holes.
22
+ * middleware): under passport 0.4, `request.login` neither regenerates nor saves. That skew is
23
+ * NOT silent here: the post-login guard below verifies the one observable trace of the contract —
24
+ * express-session's regenerate always REPLACES `request.session` with a fresh Session — and
25
+ * REFUSES (rejects) when the session object survived the login. A pre-0.6 runtime (a stale
26
+ * @proteinjs/server < 3.5.1 checkout symlinked into a dev workspace, live-observed as
27
+ * DEV_SMOKE_OVERNIGHT 2026-08-26 finding 7: /dev/login's redirected navigation raced the
28
+ * deferred session write and landed on the login form) then fails loudly at the seam instead of
29
+ * degrading into fixation-vulnerable, race-prone logins. The guard is a post-condition, not a
30
+ * fallback — establishSession never does passport's regenerate/save itself.
24
31
  *
25
32
  * `request` is typed loosely because passport augments the express request at runtime; the
26
33
  * routes in this package share that convention. A login failure (regenerate/serialize/save
@@ -1 +1 @@
1
- {"version":3,"file":"establishSession.d.ts","sourceRoot":"","sources":["../../../src/authentication/establishSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjF"}
1
+ {"version":3,"file":"establishSession.d.ts","sourceRoot":"","sources":["../../../src/authentication/establishSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAejF"}
@@ -58,8 +58,15 @@ exports.establishSession = void 0;
58
58
  * real passport machinery.
59
59
  *
60
60
  * COUPLED to the passport 0.6 upgrade in @proteinjs/server (which supplies the runtime passport
61
- * middleware): under passport 0.4, `request.login` neither regenerates nor saves — shipping this
62
- * package against a pre-0.6 @proteinjs/server would silently reopen both holes.
61
+ * middleware): under passport 0.4, `request.login` neither regenerates nor saves. That skew is
62
+ * NOT silent here: the post-login guard below verifies the one observable trace of the contract —
63
+ * express-session's regenerate always REPLACES `request.session` with a fresh Session — and
64
+ * REFUSES (rejects) when the session object survived the login. A pre-0.6 runtime (a stale
65
+ * @proteinjs/server < 3.5.1 checkout symlinked into a dev workspace, live-observed as
66
+ * DEV_SMOKE_OVERNIGHT 2026-08-26 finding 7: /dev/login's redirected navigation raced the
67
+ * deferred session write and landed on the login form) then fails loudly at the seam instead of
68
+ * degrading into fixation-vulnerable, race-prone logins. The guard is a post-condition, not a
69
+ * fallback — establishSession never does passport's regenerate/save itself.
63
70
  *
64
71
  * `request` is typed loosely because passport augments the express request at runtime; the
65
72
  * routes in this package share that convention. A login failure (regenerate/serialize/save
@@ -67,13 +74,24 @@ exports.establishSession = void 0;
67
74
  */
68
75
  function establishSession(request, email) {
69
76
  return __awaiter(this, void 0, void 0, function () {
77
+ var preLoginSession;
70
78
  return __generator(this, function (_a) {
71
79
  switch (_a.label) {
72
- case 0: return [4 /*yield*/, new Promise(function (resolve, reject) {
73
- return request.login(email, function (error) { return (error ? reject(error) : resolve()); });
74
- })];
80
+ case 0:
81
+ preLoginSession = request.session;
82
+ return [4 /*yield*/, new Promise(function (resolve, reject) {
83
+ return request.login(email, function (error) { return (error ? reject(error) : resolve()); });
84
+ })];
75
85
  case 1:
76
86
  _a.sent();
87
+ if (request.session === preLoginSession) {
88
+ throw new Error('establishSession: request.login resolved without replacing request.session, so the runtime passport ' +
89
+ 'did not regenerate the session id (pre-0.6 shape — the runtime middleware comes from ' +
90
+ '@proteinjs/server, which supplies passport 0.6 as of 3.5.1; check for a stale checkout or ' +
91
+ 'node_modules). Refusing to answer success: without regenerate → save-before-response, the ' +
92
+ 'post-login navigation races the session write (first hit lands unauthenticated) and session ' +
93
+ 'fixation (CVE-2022-25896) reopens.');
94
+ }
77
95
  return [2 /*return*/];
78
96
  }
79
97
  });
@@ -1 +1 @@
1
- {"version":3,"file":"establishSession.js","sourceRoot":"","sources":["../../../src/authentication/establishSession.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAsB,gBAAgB,CAAC,OAAY,EAAE,KAAa;;;;wBAChE,qBAAM,IAAI,OAAO,CAAO,UAAC,OAAO,EAAE,MAAM;wBACtC,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,UAAC,KAAc,IAAK,OAAA,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAnC,CAAmC,CAAC;oBAA7E,CAA6E,CAC9E,EAAA;;oBAFD,SAEC,CAAC;;;;;CACH;AAJD,4CAIC"}
1
+ {"version":3,"file":"establishSession.js","sourceRoot":"","sources":["../../../src/authentication/establishSession.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,SAAsB,gBAAgB,CAAC,OAAY,EAAE,KAAa;;;;;;oBAC1D,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;oBACxC,qBAAM,IAAI,OAAO,CAAO,UAAC,OAAO,EAAE,MAAM;4BACtC,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,UAAC,KAAc,IAAK,OAAA,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAnC,CAAmC,CAAC;wBAA7E,CAA6E,CAC9E,EAAA;;oBAFD,SAEC,CAAC;oBACF,IAAI,OAAO,CAAC,OAAO,KAAK,eAAe,EAAE;wBACvC,MAAM,IAAI,KAAK,CACb,sGAAsG;4BACpG,uFAAuF;4BACvF,4FAA4F;4BAC5F,4FAA4F;4BAC5F,8FAA8F;4BAC9F,oCAAoC,CACvC,CAAC;qBACH;;;;;CACF;AAfD,4CAeC"}
@@ -8,7 +8,10 @@ import { Route } from '@proteinjs/server-api';
8
8
  * System-read surface is exactly: the user row (for `avatarFileId`), that one file row (for the
9
9
  * Content-Type), and its bytes. The file id is never taken from the request — only the id stored
10
10
  * on the user row is served, so this can never read arbitrary files. `:userId` is a keyed lookup
11
- * (no path/filesystem interpretation).
11
+ * (no path/filesystem interpretation). Bytes come through the deliberately-unscoped DRIVER read:
12
+ * the route has already made its own access decision above, and the gated service read
13
+ * (`FileStorage.getFileData` — the caller's row-read as the byte-access check) would refuse every
14
+ * viewer but the avatar's owner.
12
15
  *
13
16
  * Cache contract (mirrored by `avatarRoute` in @proteinjs/user routes.ts): the path is stable per
14
17
  * user, so responses carry `max-age=86400, immutable`; clients bust with `?v=<avatarFileId>`,
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQ9C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM,EAAE,KAgCpB,CAAC"}
1
+ {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQ9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,MAAM,EAAE,KAgCpB,CAAC"}
@@ -51,7 +51,10 @@ var logger = new logger_1.Logger({ name: 'avatarRoute' });
51
51
  * System-read surface is exactly: the user row (for `avatarFileId`), that one file row (for the
52
52
  * Content-Type), and its bytes. The file id is never taken from the request — only the id stored
53
53
  * on the user row is served, so this can never read arbitrary files. `:userId` is a keyed lookup
54
- * (no path/filesystem interpretation).
54
+ * (no path/filesystem interpretation). Bytes come through the deliberately-unscoped DRIVER read:
55
+ * the route has already made its own access decision above, and the gated service read
56
+ * (`FileStorage.getFileData` — the caller's row-read as the byte-access check) would refuse every
57
+ * viewer but the avatar's owner.
55
58
  *
56
59
  * Cache contract (mirrored by `avatarRoute` in @proteinjs/user routes.ts): the path is stable per
57
60
  * user, so responses carry `max-age=86400, immutable`; clients bust with `?v=<avatarFileId>`,
@@ -88,7 +91,7 @@ exports.avatar = {
88
91
  response.status(404).send('No avatar photo');
89
92
  return [2 /*return*/];
90
93
  }
91
- return [4 /*yield*/, new db_file_1.FileStorage().getFileData(file.id)];
94
+ return [4 /*yield*/, db_file_1.FileStorage.getDriver().getFileData(file.id)];
92
95
  case 4:
93
96
  fileDataBase64 = _a.sent();
94
97
  response.setHeader('Content-Type', file.type);
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oCAA8C;AAC9C,wCAAwE;AACxE,8CAA6E;AAC7E,4CAA2C;AAE3C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACU,QAAA,MAAM,GAAU;IAC3B,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;;;;oBACjC,IAAI,CAAC,eAAQ,CAAC,UAAU,EAAE,EAAE;wBAC1B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;wBAChD,sBAAO;qBACR;;;;oBAGO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;oBACxB,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAA7D,IAAI,GAAG,SAAsD;oBACnE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;wBAC/B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEY,qBAAM,IAAA,0BAAmB,GAAQ,CAAC,GAAG,CAAC,gBAAU,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,EAAA;;oBAAxF,IAAI,GAAG,SAAiF;oBAC9F,IAAI,CAAC,IAAI,EAAE;wBACT,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEsB,qBAAM,IAAI,qBAAW,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAA;;oBAA7D,cAAc,GAAG,SAA4C;oBACnE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9C,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,kCAAkC,CAAC,CAAC;oBACxE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;;;;oBAErD,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAA,EAAE,CAAC,CAAC;oBAC3D,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;;;;;SAEtD;CACF,CAAC"}
1
+ {"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oCAA8C;AAC9C,wCAAwE;AACxE,8CAA6E;AAC7E,4CAA2C;AAE3C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,MAAM,GAAU;IAC3B,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;;;;oBACjC,IAAI,CAAC,eAAQ,CAAC,UAAU,EAAE,EAAE;wBAC1B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;wBAChD,sBAAO;qBACR;;;;oBAGO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;oBACxB,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAA7D,IAAI,GAAG,SAAsD;oBACnE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;wBAC/B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEY,qBAAM,IAAA,0BAAmB,GAAQ,CAAC,GAAG,CAAC,gBAAU,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,EAAA;;oBAAxF,IAAI,GAAG,SAAiF;oBAC9F,IAAI,CAAC,IAAI,EAAE;wBACT,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEsB,qBAAM,qBAAW,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAA;;oBAAnE,cAAc,GAAG,SAAkD;oBACzE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9C,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,kCAAkC,CAAC,CAAC;oBACxE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;;;;oBAErD,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAA,EAAE,CAAC,CAAC;oBAC3D,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;;;;;SAEtD;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=DevLoginStaleCookieFirstHit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevLoginStaleCookieFirstHit.test.d.ts","sourceRoot":"","sources":["../../test/DevLoginStaleCookieFirstHit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
41
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
42
+ return new (P || (P = Promise))(function (resolve, reject) {
43
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
44
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
45
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
46
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
47
+ });
48
+ };
49
+ var __generator = (this && this.__generator) || function (thisArg, body) {
50
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
51
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
52
+ function verb(n) { return function (v) { return step([n, v]); }; }
53
+ function step(op) {
54
+ if (f) throw new TypeError("Generator is already executing.");
55
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
56
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
57
+ if (y = 0, t) op = [op[0] & 2, t.value];
58
+ switch (op[0]) {
59
+ case 0: case 1: t = op; break;
60
+ case 4: _.label++; return { value: op[1], done: false };
61
+ case 5: _.label++; y = op[1]; op = [0]; continue;
62
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
63
+ default:
64
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
65
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
66
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
67
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
68
+ if (t[2]) _.ops.pop();
69
+ _.trys.pop(); continue;
70
+ }
71
+ op = body.call(thisArg, _);
72
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
73
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
74
+ }
75
+ };
76
+ var __importDefault = (this && this.__importDefault) || function (mod) {
77
+ return (mod && mod.__esModule) ? mod : { "default": mod };
78
+ };
79
+ Object.defineProperty(exports, "__esModule", { value: true });
80
+ var http_1 = __importDefault(require("http"));
81
+ var express_session_1 = __importStar(require("express-session"));
82
+ var passport_1 = __importDefault(require("passport"));
83
+ var devLogin_1 = require("../src/routes/devLogin");
84
+ var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
85
+ var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
86
+ /**
87
+ * DEV_SMOKE_OVERNIGHT (2026-08-26) finding 7: a browser holding a STALE session cookie (a sid
88
+ * absent from the store — prior server generation, swept row, or reseeded dev db) hits
89
+ * `GET /dev/login`, gets the 302, and lands on the LOGIN FORM; the second hit lands home.
90
+ *
91
+ * The mechanism is write-ordering at the session-establishment seam: a browser follows a redirect
92
+ * the moment RESPONSE HEADERS arrive — it never waits for the body. So the session row for the
93
+ * sid named by the 302's Set-Cookie must be COMMITTED to the store before those headers flush.
94
+ * passport 0.6's `request.login` guarantees exactly that (regenerate → bind → save, committed
95
+ * before the login callback — see establishSession); under a pre-0.6 passport runtime the save
96
+ * is deferred to express-session's end-of-response proxy, whose split-response write flushes the
97
+ * 302's headers BEFORE the store write commits — the redirected navigation races the commit and
98
+ * loses, reads no session, and the SPA routes to /login.
99
+ *
100
+ * This suite drives the REAL stack a browser meets — express-session 1.17.1 (the exact
101
+ * @proteinjs/server configureSession options and dev cookie-name shape) + real passport +
102
+ * the devLogin route — against a store with honest commit latency, and asserts the contract
103
+ * from the client's side: follow the 302 the instant headers arrive, carrying exactly the
104
+ * cookies the response set, and the follow-up MUST read as authenticated on the FIRST pass.
105
+ */
106
+ var SESSION_COOKIE_NAME = 'n3xa.sid.9876'; // dev cookie-name shape: n3xa.sid.${SERVER_PORT}
107
+ var SESSION_SECRET = 'dev-first-hit-test-secret';
108
+ var ENV_EMAIL = 'dev@test.local';
109
+ /** Store commit latency. Generous so a pre-0.6 runtime (write racing the redirect) loses the
110
+ * race DETERMINISTICALLY; under the passport 0.6 contract the row commits before the redirect
111
+ * is even issued, so green never depends on this number. */
112
+ var COMMIT_LATENCY_MS = 150;
113
+ var READ_LATENCY_MS = 5;
114
+ /**
115
+ * In-memory session store with DbSessionStore's contract: callbacks fire only after the
116
+ * operation commits, and commits take real time (Spanner in dev). Rows are inspectable so the
117
+ * test can assert store truth directly and clear it to model a next server generation.
118
+ */
119
+ var CommitLatencySessionStore = /** @class */ (function (_super) {
120
+ __extends(CommitLatencySessionStore, _super);
121
+ function CommitLatencySessionStore() {
122
+ var _this = _super !== null && _super.apply(this, arguments) || this;
123
+ _this.rows = new Map();
124
+ _this.get = function (sessionId, cb) {
125
+ var timer = setTimeout(function () {
126
+ var row = _this.rows.get(sessionId);
127
+ cb(null, row ? JSON.parse(row) : undefined);
128
+ }, READ_LATENCY_MS);
129
+ timer.unref();
130
+ };
131
+ _this.set = function (sessionId, session, cb) {
132
+ var timer = setTimeout(function () {
133
+ _this.rows.set(sessionId, JSON.stringify(session));
134
+ if (cb) {
135
+ cb();
136
+ }
137
+ }, COMMIT_LATENCY_MS);
138
+ timer.unref();
139
+ };
140
+ _this.destroy = function (sessionId, cb) {
141
+ var timer = setTimeout(function () {
142
+ _this.rows.delete(sessionId);
143
+ if (cb) {
144
+ cb();
145
+ }
146
+ }, READ_LATENCY_MS);
147
+ timer.unref();
148
+ };
149
+ return _this;
150
+ }
151
+ return CommitLatencySessionStore;
152
+ }(express_session_1.Store));
153
+ describe('devLogin first hit through the real session middleware stack', function () {
154
+ var originalEnv = {
155
+ DEVELOPMENT: process.env.DEVELOPMENT,
156
+ DEV_AUTO_LOGIN_EMAIL: process.env.DEV_AUTO_LOGIN_EMAIL,
157
+ };
158
+ var store = new CommitLatencySessionStore();
159
+ var server;
160
+ var port;
161
+ beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
162
+ return __generator(this, function (_a) {
163
+ switch (_a.label) {
164
+ case 0: return [4 /*yield*/, testEnv.beforeAll()];
165
+ case 1:
166
+ _a.sent();
167
+ return [4 /*yield*/, testEnv.createUser({ name: 'Dev Default', email: ENV_EMAIL })];
168
+ case 2:
169
+ _a.sent();
170
+ server = createServerWithRealSessionStack(store);
171
+ return [4 /*yield*/, new Promise(function (resolve) { return server.listen(0, resolve); })];
172
+ case 3:
173
+ _a.sent();
174
+ port = server.address().port;
175
+ return [2 /*return*/];
176
+ }
177
+ });
178
+ }); });
179
+ afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
180
+ return __generator(this, function (_a) {
181
+ switch (_a.label) {
182
+ case 0: return [4 /*yield*/, new Promise(function (resolve, reject) { return server.close(function (error) { return (error ? reject(error) : resolve()); }); })];
183
+ case 1:
184
+ _a.sent();
185
+ return [4 /*yield*/, testEnv.afterAll()];
186
+ case 2:
187
+ _a.sent();
188
+ return [2 /*return*/];
189
+ }
190
+ });
191
+ }); });
192
+ beforeEach(function () {
193
+ process.env.DEVELOPMENT = 'true';
194
+ process.env.DEV_AUTO_LOGIN_EMAIL = ENV_EMAIL;
195
+ });
196
+ afterEach(function () {
197
+ for (var _i = 0, _a = Object.entries(originalEnv); _i < _a.length; _i++) {
198
+ var _b = _a[_i], key = _b[0], value = _b[1];
199
+ if (value === undefined) {
200
+ delete process.env[key];
201
+ }
202
+ else {
203
+ process.env[key] = value;
204
+ }
205
+ }
206
+ });
207
+ it('stale-cookie first hit: following the 302 on HEADERS reads as authenticated, first pass', function () { return __awaiter(void 0, void 0, void 0, function () {
208
+ var priorHit, staleCookie, firstHit, followUpCookie, followUp;
209
+ return __generator(this, function (_a) {
210
+ switch (_a.label) {
211
+ case 0: return [4 /*yield*/, request(port, '/dev/login', { waitForBody: true })];
212
+ case 1:
213
+ priorHit = _a.sent();
214
+ staleCookie = sessionCookiePair(priorHit);
215
+ store.rows.clear();
216
+ return [4 /*yield*/, request(port, '/dev/login', { cookie: staleCookie })];
217
+ case 2:
218
+ firstHit = _a.sent();
219
+ expect(firstHit.statusCode).toBe(302);
220
+ expect(firstHit.headers.location).toBe('/');
221
+ followUpCookie = sessionCookiePair(firstHit);
222
+ expect(sidOf(followUpCookie)).not.toBe(sidOf(staleCookie));
223
+ return [4 /*yield*/, request(port, '/whoami', { cookie: followUpCookie, waitForBody: true })];
224
+ case 3:
225
+ followUp = _a.sent();
226
+ expect(JSON.parse(followUp.body)).toEqual({ user: ENV_EMAIL });
227
+ return [2 /*return*/];
228
+ }
229
+ });
230
+ }); });
231
+ it('cookieless first hit: same first-pass guarantee for a fresh browser', function () { return __awaiter(void 0, void 0, void 0, function () {
232
+ var firstHit, followUp;
233
+ return __generator(this, function (_a) {
234
+ switch (_a.label) {
235
+ case 0:
236
+ store.rows.clear();
237
+ return [4 /*yield*/, request(port, '/dev/login')];
238
+ case 1:
239
+ firstHit = _a.sent();
240
+ expect(firstHit.statusCode).toBe(302);
241
+ return [4 /*yield*/, request(port, '/whoami', { cookie: sessionCookiePair(firstHit), waitForBody: true })];
242
+ case 2:
243
+ followUp = _a.sent();
244
+ expect(JSON.parse(followUp.body)).toEqual({ user: ENV_EMAIL });
245
+ return [2 /*return*/];
246
+ }
247
+ });
248
+ }); });
249
+ });
250
+ /**
251
+ * The real middleware stack a request traverses in front of the route — express-session with
252
+ * @proteinjs/server configureSession's exact options (resave: false, saveUninitialized: false,
253
+ * rolling: true, the dev port-scoped cookie name) + passport initialize/session with the
254
+ * identity (de)serialization @proteinjs/server registers — on a raw node http server, so
255
+ * header-flush timing is the genuine article.
256
+ */
257
+ function createServerWithRealSessionStack(store) {
258
+ var sixtyDays = 1000 * 60 * 60 * 24 * 60;
259
+ var sessionMiddleware = (0, express_session_1.default)({
260
+ name: SESSION_COOKIE_NAME,
261
+ secret: SESSION_SECRET,
262
+ store: store,
263
+ resave: false,
264
+ saveUninitialized: false,
265
+ cookie: { maxAge: sixtyDays },
266
+ rolling: true,
267
+ });
268
+ var authenticator = new passport_1.default.Passport();
269
+ authenticator.serializeUser(function (user, done) { return done(null, user); });
270
+ authenticator.deserializeUser(function (id, done) { return done(null, id); });
271
+ var middleware = [
272
+ sessionMiddleware,
273
+ authenticator.initialize(),
274
+ authenticator.session(),
275
+ ];
276
+ return http_1.default.createServer(function (req, res) {
277
+ runMiddleware(middleware, req, res, function (error) {
278
+ if (error) {
279
+ res.statusCode = 500;
280
+ res.end(String(error));
281
+ return;
282
+ }
283
+ void dispatch(req, res);
284
+ });
285
+ });
286
+ }
287
+ function runMiddleware(middleware, req, res, done) {
288
+ var next = function (index) { return function (error) {
289
+ if (error || index >= middleware.length) {
290
+ done(error);
291
+ return;
292
+ }
293
+ middleware[index](req, res, next(index + 1));
294
+ }; };
295
+ next(0)();
296
+ }
297
+ function dispatch(req, res) {
298
+ var _a, _b, _c;
299
+ return __awaiter(this, void 0, void 0, function () {
300
+ var url, request_1, query_1, error_1, session;
301
+ return __generator(this, function (_d) {
302
+ switch (_d.label) {
303
+ case 0:
304
+ url = new URL((_a = req.url) !== null && _a !== void 0 ? _a : '/', 'http://localhost');
305
+ if (!(url.pathname === '/dev/login')) return [3 /*break*/, 5];
306
+ request_1 = req;
307
+ query_1 = {};
308
+ url.searchParams.forEach(function (value, key) { return (query_1[key] = value); });
309
+ request_1.query = query_1;
310
+ _d.label = 1;
311
+ case 1:
312
+ _d.trys.push([1, 3, , 4]);
313
+ return [4 /*yield*/, devLogin_1.devLogin.onRequest(req, expressResponseShim(res))];
314
+ case 2:
315
+ _d.sent();
316
+ return [3 /*break*/, 4];
317
+ case 3:
318
+ error_1 = _d.sent();
319
+ // Mirrors @proteinjs/server's wrapRoute: a route throw is caught and logged, never a
320
+ // hung response. (There it falls through to the star route; here we end with 500.)
321
+ console.error(error_1);
322
+ if (!res.writableEnded) {
323
+ res.statusCode = 500;
324
+ res.end();
325
+ }
326
+ return [3 /*break*/, 4];
327
+ case 4: return [2 /*return*/];
328
+ case 5:
329
+ if (url.pathname === '/whoami') {
330
+ session = req.session;
331
+ res.setHeader('Content-Type', 'application/json');
332
+ res.end(JSON.stringify({ user: (_c = (_b = session === null || session === void 0 ? void 0 : session.passport) === null || _b === void 0 ? void 0 : _b.user) !== null && _c !== void 0 ? _c : null }));
333
+ return [2 /*return*/];
334
+ }
335
+ res.statusCode = 404;
336
+ res.end();
337
+ return [2 /*return*/];
338
+ }
339
+ });
340
+ });
341
+ }
342
+ /** The express response surface devLogin touches, over the RAW response object — so
343
+ * express-session's proxied `res.end` (the commit point under test) is the one that runs. */
344
+ function expressResponseShim(res) {
345
+ var shim = {
346
+ status: function (code) {
347
+ res.statusCode = code;
348
+ return shim;
349
+ },
350
+ send: function (body) {
351
+ res.end(body === undefined ? undefined : String(body));
352
+ },
353
+ redirect: function (path) {
354
+ var body = "Found. Redirecting to ".concat(path);
355
+ res.statusCode = 302;
356
+ res.setHeader('Location', path);
357
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
358
+ res.setHeader('Content-Length', Buffer.byteLength(body));
359
+ res.end(body);
360
+ },
361
+ };
362
+ return shim;
363
+ }
364
+ /**
365
+ * GET `path`. By default resolves the moment response HEADERS arrive (browser-following-a-
366
+ * redirect semantics — the body may still be in flight and its socket is left to drain);
367
+ * `waitForBody` resolves after the full body, which with express-session's end proxy also
368
+ * means the response's session write has committed.
369
+ */
370
+ function request(port, path, options) {
371
+ if (options === void 0) { options = {}; }
372
+ return new Promise(function (resolve, reject) {
373
+ var clientRequest = http_1.default.get({ port: port, path: path, headers: options.cookie ? { cookie: options.cookie } : {}, agent: false }, function (res) {
374
+ if (!options.waitForBody) {
375
+ resolve({ statusCode: res.statusCode, headers: res.headers });
376
+ res.resume();
377
+ return;
378
+ }
379
+ var body = '';
380
+ res.on('data', function (chunk) { return (body += chunk); });
381
+ res.on('end', function () { return resolve({ statusCode: res.statusCode, headers: res.headers, body: body }); });
382
+ });
383
+ clientRequest.on('error', reject);
384
+ });
385
+ }
386
+ /** The `name=value` pair of the response's session Set-Cookie — what the browser sends back. */
387
+ function sessionCookiePair(response) {
388
+ var _a;
389
+ var setCookies = (_a = response.headers['set-cookie']) !== null && _a !== void 0 ? _a : [];
390
+ var sessionCookie = setCookies.find(function (cookie) { return cookie.startsWith("".concat(SESSION_COOKIE_NAME, "=")); });
391
+ if (!sessionCookie) {
392
+ throw new Error("response set no ".concat(SESSION_COOKIE_NAME, " cookie (Set-Cookie: ").concat(JSON.stringify(setCookies), ")"));
393
+ }
394
+ return sessionCookie.split(';')[0];
395
+ }
396
+ /** The raw sid inside a signed session cookie pair (`name=s%3A<sid>.<signature>`). */
397
+ function sidOf(cookiePair) {
398
+ var value = decodeURIComponent(cookiePair.slice(cookiePair.indexOf('=') + 1));
399
+ return value.startsWith('s:') ? value.slice(2, value.indexOf('.')) : value;
400
+ }
401
+ //# sourceMappingURL=DevLoginStaleCookieFirstHit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevLoginStaleCookieFirstHit.test.js","sourceRoot":"","sources":["../../test/DevLoginStaleCookieFirstHit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EstablishSessionRuntimeContract.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EstablishSessionRuntimeContract.test.d.ts","sourceRoot":"","sources":["../../test/EstablishSessionRuntimeContract.test.ts"],"names":[],"mappings":""}