@prosopo/api-express-router 3.1.98 → 3.2.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.
Files changed (35) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +7 -6
  2. package/.turbo/turbo-build$colon$tsc.log +21 -21
  3. package/.turbo/turbo-build.log +7 -6
  4. package/CHANGELOG.md +35 -0
  5. package/dist/cjs/index.cjs +2 -0
  6. package/dist/cjs/middlewares/authMiddleware.cjs +25 -14
  7. package/dist/cjs/middlewares/jwtReplayGuard.cjs +28 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/middlewares/authMiddleware.d.ts +7 -1
  13. package/dist/middlewares/authMiddleware.d.ts.map +1 -1
  14. package/dist/middlewares/authMiddleware.js +26 -15
  15. package/dist/middlewares/authMiddleware.js.map +1 -1
  16. package/dist/middlewares/jwtReplayGuard.d.ts +5 -0
  17. package/dist/middlewares/jwtReplayGuard.d.ts.map +1 -0
  18. package/dist/middlewares/jwtReplayGuard.js +28 -0
  19. package/dist/middlewares/jwtReplayGuard.js.map +1 -0
  20. package/dist/tests/apiExpressRouter.test-d.js +1 -1
  21. package/dist/tests/apiExpressRouter.test-d.js.map +1 -1
  22. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js +94 -8
  23. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js.map +1 -1
  24. package/dist/tests/unit/middlewares/jwtReplayGuard.unit.test.d.ts +2 -0
  25. package/dist/tests/unit/middlewares/jwtReplayGuard.unit.test.d.ts.map +1 -0
  26. package/dist/tests/unit/middlewares/jwtReplayGuard.unit.test.js +36 -0
  27. package/dist/tests/unit/middlewares/jwtReplayGuard.unit.test.js.map +1 -0
  28. package/package.json +9 -9
  29. package/src/index.ts +1 -0
  30. package/src/middlewares/authMiddleware.ts +73 -16
  31. package/src/middlewares/jwtReplayGuard.ts +56 -0
  32. package/src/tests/apiExpressRouter.test-d.ts +8 -2
  33. package/src/tests/unit/middlewares/authMiddleware.unit.test.ts +118 -11
  34. package/src/tests/unit/middlewares/jwtReplayGuard.unit.test.ts +53 -0
  35. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,7 @@
1
1
  import { ProsopoApiError } from "@prosopo/common";
2
2
  import { beforeEach, describe, expect, test, vi } from "vitest";
3
3
  import { authMiddleware, verifySignature, } from "../../../middlewares/authMiddleware.js";
4
+ import { createMemoryJwtReplayGuard } from "../../../middlewares/jwtReplayGuard.js";
4
5
  import { captureNext } from "../testDoubles.js";
5
6
  const pairThat = (verify) => ({
6
7
  jwtVerify: vi.fn(verify),
@@ -13,7 +14,7 @@ const rejects = () => pairThat(() => ({ isValid: false }));
13
14
  const explodes = () => pairThat(() => {
14
15
  throw new Error("verifier unavailable");
15
16
  });
16
- const build = (headers = {}) => {
17
+ const build = (headers = {}, i18n) => {
17
18
  const json = vi.fn();
18
19
  const status = vi.fn();
19
20
  const res = { status, json };
@@ -21,6 +22,7 @@ const build = (headers = {}) => {
21
22
  const logged = vi.fn();
22
23
  const req = {
23
24
  headers,
25
+ i18n,
24
26
  logger: { error: logged },
25
27
  };
26
28
  return { req, res, next: captureNext(), status, json, logged };
@@ -32,8 +34,8 @@ let harness;
32
34
  beforeEach(() => {
33
35
  harness = build(bearer("token-1"));
34
36
  });
35
- const run = async (pair, authAccount) => {
36
- await authMiddleware(pair, authAccount)(harness.req, harness.res, harness.next.fn);
37
+ const run = async (pair, authAccount, options) => {
38
+ await authMiddleware(pair, authAccount, options)(harness.req, harness.res, harness.next.fn);
37
39
  };
38
40
  describe("a token one of the keys accepts", () => {
39
41
  test("passes the request through on the auth account", async () => {
@@ -61,7 +63,7 @@ describe("a token one of the keys accepts", () => {
61
63
  test("hands the verifier the token without its Bearer prefix", async () => {
62
64
  const pair = accepts();
63
65
  await run(pair, undefined);
64
- expect(pair.jwtVerify).toHaveBeenCalledWith("token-1");
66
+ expect(pair.jwtVerify).toHaveBeenCalledWith("token-1", undefined);
65
67
  });
66
68
  });
67
69
  describe("a token neither key accepts", () => {
@@ -74,7 +76,55 @@ describe("a token neither key accepts", () => {
74
76
  });
75
77
  test("is answered with an error body carrying the 401 code", () => {
76
78
  const body = harness.json.mock.calls[0]?.[0];
77
- expect(body.error.context?.code).toBe(401);
79
+ expect(body.error).toEqual({
80
+ code: 401,
81
+ key: "API.UNAUTHORIZED",
82
+ message: "API.UNAUTHORIZED",
83
+ });
84
+ });
85
+ test("does not serialise the request's i18n instance or error context", () => {
86
+ harness = build(bearer("token-1"), { t: (key) => `t:${key}` });
87
+ return run(rejects(), rejects()).then(() => {
88
+ const body = harness.json.mock.calls[0]?.[0];
89
+ expect(JSON.stringify(body)).not.toContain("context");
90
+ expect(body).toEqual({
91
+ error: {
92
+ code: 401,
93
+ key: "API.UNAUTHORIZED",
94
+ message: "t:API.UNAUTHORIZED",
95
+ },
96
+ });
97
+ });
98
+ });
99
+ });
100
+ describe("the 401 body for a thrown error", () => {
101
+ test("does not echo what a verifier threw", async () => {
102
+ const leaky = pairThat(() => {
103
+ throw new Error("mongodb://admin:hunter2@10.0.0.5/provider");
104
+ });
105
+ await run(leaky, undefined);
106
+ const body = harness.json.mock.calls[0]?.[0];
107
+ expect(JSON.stringify(body)).not.toContain("hunter2");
108
+ expect(body).toEqual({
109
+ error: {
110
+ code: 401,
111
+ key: "API.UNAUTHORIZED",
112
+ message: "API.UNAUTHORIZED",
113
+ },
114
+ });
115
+ });
116
+ test("reports only the translation key of a Prosopo error", async () => {
117
+ harness = build({});
118
+ await run(accepts(), undefined);
119
+ const body = harness.json.mock.calls[0]?.[0];
120
+ expect(JSON.stringify(body)).not.toContain("Missing Authorization header");
121
+ expect(body).toEqual({
122
+ error: {
123
+ code: 401,
124
+ key: "GENERAL.MISSING_AUTH_HEADER",
125
+ message: "GENERAL.MISSING_AUTH_HEADER",
126
+ },
127
+ });
78
128
  });
79
129
  });
80
130
  describe("a request with no usable credentials", () => {
@@ -124,21 +174,21 @@ describe("header handling quirks worth pinning down", () => {
124
174
  harness = build({ authorization: "token-1" });
125
175
  const pair = accepts();
126
176
  await run(pair, undefined);
127
- expect(pair.jwtVerify).toHaveBeenCalledWith("token-1");
177
+ expect(pair.jwtVerify).toHaveBeenCalledWith("token-1", undefined);
128
178
  expect(harness.next.calls).toHaveLength(1);
129
179
  });
130
180
  test("a capitalised Authorization key is read as well as the lowercase one", async () => {
131
181
  harness = build({ Authorization: "Bearer token-1" });
132
182
  const pair = accepts();
133
183
  await run(pair, undefined);
134
- expect(pair.jwtVerify).toHaveBeenCalledWith("token-1");
184
+ expect(pair.jwtVerify).toHaveBeenCalledWith("token-1", undefined);
135
185
  expect(harness.next.calls).toHaveLength(1);
136
186
  });
137
187
  test("a Bearer prefix appearing inside the token is also stripped", async () => {
138
188
  harness = build({ authorization: "abcBearer xyz" });
139
189
  const pair = accepts();
140
190
  await run(pair, undefined);
141
- expect(pair.jwtVerify).toHaveBeenCalledWith("abcxyz");
191
+ expect(pair.jwtVerify).toHaveBeenCalledWith("abcxyz", undefined);
142
192
  });
143
193
  });
144
194
  describe("a verifier that throws", () => {
@@ -215,4 +265,40 @@ describe("verifySignature", () => {
215
265
  expect(pair.verify).toHaveBeenCalledWith("", new Uint8Array([1, 2]), pair.publicKey);
216
266
  });
217
267
  });
268
+ describe("admin token claim options", () => {
269
+ const payload = (jti) => ({
270
+ sub: "0x01",
271
+ iat: 1,
272
+ exp: Date.now() / 1000 + 300,
273
+ ...(jti ? { jti } : {}),
274
+ });
275
+ test("passes the verify options to the key", async () => {
276
+ const pair = accepts();
277
+ const verify = { audience: ["https://p1.example"] };
278
+ await run(pair, undefined, { verify });
279
+ expect(pair.jwtVerify).toHaveBeenCalledWith("token-1", verify);
280
+ });
281
+ test("a token with a jti is accepted once and refused on replay", async () => {
282
+ const pair = pairThat(() => ({ isValid: true, payload: payload("n-1") }));
283
+ const options = {
284
+ replayGuard: createMemoryJwtReplayGuard(),
285
+ };
286
+ await run(pair, undefined, options);
287
+ expect(harness.next.calls).toHaveLength(1);
288
+ harness = build(bearer("token-1"));
289
+ await run(pair, undefined, options);
290
+ expect(harness.next.calls).toHaveLength(0);
291
+ expect(harness.status).toHaveBeenCalledWith(401);
292
+ });
293
+ test("a token without a jti can still be reused", async () => {
294
+ const pair = pairThat(() => ({ isValid: true, payload: payload() }));
295
+ const options = {
296
+ replayGuard: createMemoryJwtReplayGuard(),
297
+ };
298
+ await run(pair, undefined, options);
299
+ harness = build(bearer("token-1"));
300
+ await run(pair, undefined, options);
301
+ expect(harness.next.calls).toHaveLength(1);
302
+ });
303
+ });
218
304
  //# sourceMappingURL=authMiddleware.unit.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authMiddleware.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jwtReplayGuard.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwtReplayGuard.unit.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/jwtReplayGuard.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { createMemoryJwtReplayGuard } from "../../../middlewares/jwtReplayGuard.js";
3
+ describe("createMemoryJwtReplayGuard", () => {
4
+ test("accepts an id once and refuses it until it expires", () => {
5
+ let now = 1000;
6
+ const guard = createMemoryJwtReplayGuard(10, () => now);
7
+ expect(guard.claim("a", 1300)).toBe(true);
8
+ expect(guard.claim("a", 1300)).toBe(false);
9
+ now = 1301;
10
+ expect(guard.claim("a", 1600)).toBe(true);
11
+ });
12
+ test("tracks ids independently", () => {
13
+ const guard = createMemoryJwtReplayGuard(10, () => 0);
14
+ expect(guard.claim("a", 100)).toBe(true);
15
+ expect(guard.claim("b", 100)).toBe(true);
16
+ expect(guard.claim("b", 100)).toBe(false);
17
+ });
18
+ test("drops expired entries before evicting live ones when full", () => {
19
+ let now = 0;
20
+ const guard = createMemoryJwtReplayGuard(2, () => now);
21
+ guard.claim("short", 10);
22
+ guard.claim("long", 1000);
23
+ now = 20;
24
+ expect(guard.claim("new", 1000)).toBe(true);
25
+ expect(guard.claim("long", 1000)).toBe(false);
26
+ });
27
+ test("evicts the oldest live entry rather than growing past the cap", () => {
28
+ const guard = createMemoryJwtReplayGuard(2, () => 0);
29
+ guard.claim("a", 100);
30
+ guard.claim("b", 100);
31
+ guard.claim("c", 100);
32
+ expect(guard.claim("a", 100)).toBe(true);
33
+ expect(guard.claim("c", 100)).toBe(false);
34
+ });
35
+ });
36
+ //# sourceMappingURL=jwtReplayGuard.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwtReplayGuard.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/jwtReplayGuard.unit.test.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AAEpF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC3C,IAAI,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC/D,IAAI,GAAG,GAAG,IAAI,CAAC;QACf,MAAM,KAAK,GAAG,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,GAAG,GAAG,IAAI,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACrC,MAAM,KAAK,GAAG,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACtE,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,MAAM,KAAK,GAAG,0BAA0B,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACvD,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACzB,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1B,GAAG,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;QAC1E,MAAM,KAAK,GAAG,0BAA0B,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtB,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtB,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/api-express-router",
3
- "version": "3.1.98",
3
+ "version": "3.2.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -26,14 +26,14 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@polkadot/util": "14.0.3",
29
- "@prosopo/api-route": "2.6.61",
30
- "@prosopo/common": "3.1.60",
31
- "@prosopo/logger": "2.1.1",
32
- "@prosopo/env": "3.6.67",
33
- "@prosopo/locale": "3.6.1",
34
- "@prosopo/types": "5.11.1",
35
- "@prosopo/util": "3.3.12",
36
- "@prosopo/util-crypto": "13.5.33",
29
+ "@prosopo/api-route": "2.6.62",
30
+ "@prosopo/common": "3.1.61",
31
+ "@prosopo/logger": "2.1.2",
32
+ "@prosopo/env": "3.6.68",
33
+ "@prosopo/locale": "3.6.2",
34
+ "@prosopo/types": "5.12.0",
35
+ "@prosopo/util": "3.3.13",
36
+ "@prosopo/util-crypto": "13.6.0",
37
37
  "dotenv": "16.4.5",
38
38
  "express": "4.22.2",
39
39
  "i18next": "26.4.2",
package/src/index.ts CHANGED
@@ -34,4 +34,5 @@ export {
34
34
 
35
35
  export * from "./errorHandler.js";
36
36
  export * from "./middlewares/authMiddleware.js";
37
+ export * from "./middlewares/jwtReplayGuard.js";
37
38
  export * from "./middlewares/requestLoggerMiddleware.js";
@@ -13,45 +13,102 @@
13
13
  // limitations under the License.
14
14
 
15
15
  import { hexToU8a } from "@polkadot/util";
16
- import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
17
- import type { KeyringPair } from "@prosopo/types";
18
- import type { JWT } from "@prosopo/util-crypto";
16
+ import { ProsopoApiError, ProsopoBaseError } from "@prosopo/common";
17
+ import { type TranslationKey, isTranslationKey } from "@prosopo/locale";
18
+ import type { ApiJsonError, KeyringPair } from "@prosopo/types";
19
+ import type {
20
+ JWT,
21
+ JWTVerifyOptions,
22
+ JWTVerifyResult,
23
+ } from "@prosopo/util-crypto";
19
24
  import type { NextFunction, Request, Response } from "express";
25
+ import type { JwtReplayGuard } from "./jwtReplayGuard.js";
26
+
27
+ export type AuthMiddlewareOptions = {
28
+ /** Claim checks (audience, maximum lifetime) applied to every token. */
29
+ verify?: JWTVerifyOptions;
30
+ /**
31
+ * Makes a token that carries a `jti` single-use. Tokens without `jti` are
32
+ * unaffected, so existing issuers keep working until they add one.
33
+ */
34
+ replayGuard?: JwtReplayGuard;
35
+ };
36
+
37
+ const verifyWith = (
38
+ key: KeyringPair | undefined,
39
+ jwt: JWT,
40
+ options: AuthMiddlewareOptions,
41
+ ): JWTVerifyResult | undefined => {
42
+ if (!key) return undefined;
43
+ const result = key.jwtVerify(jwt, options.verify);
44
+ return result.isValid ? result : undefined;
45
+ };
46
+
47
+ const isReplay = (
48
+ result: JWTVerifyResult,
49
+ options: AuthMiddlewareOptions,
50
+ ): boolean => {
51
+ const payload = result.payload;
52
+ if (!options.replayGuard || !payload || typeof payload.jti !== "string") {
53
+ return false;
54
+ }
55
+ return !options.replayGuard.claim(
56
+ `${payload.sub}:${payload.jti}`,
57
+ payload.exp,
58
+ );
59
+ };
20
60
 
21
61
  export const authMiddleware = (
22
62
  pair: KeyringPair | undefined,
23
63
  authAccount?: KeyringPair | undefined,
64
+ options: AuthMiddlewareOptions = {},
24
65
  ) => {
25
66
  return async (req: Request, res: Response, next: NextFunction) => {
26
67
  try {
27
68
  const jwt = extractJWT(req);
28
69
 
29
- let error: ProsopoApiError | undefined;
70
+ const verified =
71
+ verifyWith(authAccount, jwt, options) ?? verifyWith(pair, jwt, options);
30
72
 
31
- if (authAccount?.jwtVerify(jwt).isValid) {
73
+ if (verified && !isReplay(verified, options)) {
32
74
  next();
33
75
  return;
34
76
  }
35
77
 
36
- if (pair?.jwtVerify(jwt).isValid) {
37
- next();
38
- return;
39
- }
40
-
41
- res.status(401).json({
42
- error: new ProsopoEnvError(error || "API.UNAUTHORIZED", {
43
- context: { i18n: req.i18n, code: 401 },
44
- }),
45
- });
78
+ unauthorized(req, res, "API.UNAUTHORIZED");
46
79
  return;
47
80
  } catch (err) {
48
81
  req.logger.error(() => ({ err, msg: "Auth Middleware Error" }));
49
- res.status(401).json({ error: "Unauthorized", message: err });
82
+ // The thrown value can carry request context, stack or config, so
83
+ // only its translation key goes back to the caller.
84
+ unauthorized(req, res, translationKeyOf(err));
50
85
  return;
51
86
  }
52
87
  };
53
88
  };
54
89
 
90
+ const translationKeyOf = (err: unknown): TranslationKey =>
91
+ err instanceof ProsopoBaseError &&
92
+ err.translationKey !== undefined &&
93
+ isTranslationKey(err.translationKey)
94
+ ? err.translationKey
95
+ : "API.UNAUTHORIZED";
96
+
97
+ const unauthorized = (
98
+ req: Request,
99
+ res: Response,
100
+ key: TranslationKey,
101
+ ): void => {
102
+ const body: { error: ApiJsonError } = {
103
+ error: {
104
+ code: 401,
105
+ key,
106
+ message: req.i18n ? req.i18n.t(key) : key,
107
+ },
108
+ };
109
+ res.status(401).json(body);
110
+ };
111
+
55
112
  const extractJWT = (req: Request) => {
56
113
  const authHeader = req.headers.Authorization || req.headers.authorization;
57
114
 
@@ -0,0 +1,56 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ export interface JwtReplayGuard {
16
+ /**
17
+ * Record a token id. Returns false when the id was already recorded and has
18
+ * not yet expired, i.e. the token is being replayed.
19
+ */
20
+ claim(id: string, expiresAtSeconds: number): boolean;
21
+ }
22
+
23
+ /**
24
+ * Per-process set of token ids seen until their expiry. Only tokens signed by
25
+ * an admin key reach it, so the size cap guards against a misbehaving issuer
26
+ * rather than an attacker; when full the oldest entry is dropped.
27
+ */
28
+ export const createMemoryJwtReplayGuard = (
29
+ maxEntries = 10_000,
30
+ nowSeconds: () => number = () => Date.now() / 1000,
31
+ ): JwtReplayGuard => {
32
+ const seen = new Map<string, number>();
33
+
34
+ const sweep = (now: number): void => {
35
+ for (const [id, exp] of seen) {
36
+ if (exp < now) seen.delete(id);
37
+ }
38
+ };
39
+
40
+ return {
41
+ claim(id: string, expiresAtSeconds: number): boolean {
42
+ const now = nowSeconds();
43
+ const previous = seen.get(id);
44
+ if (previous !== undefined && previous >= now) return false;
45
+ if (seen.size >= maxEntries) {
46
+ sweep(now);
47
+ if (seen.size >= maxEntries) {
48
+ const oldest = seen.keys().next();
49
+ if (!oldest.done) seen.delete(oldest.value);
50
+ }
51
+ }
52
+ seen.set(id, expiresAtSeconds);
53
+ return true;
54
+ },
55
+ };
56
+ };
@@ -27,6 +27,7 @@ import type { ZodType } from "zod";
27
27
  import type * as barrel from "../index.js";
28
28
  import {
29
29
  type ApiExpressEndpointAdapter,
30
+ type AuthMiddlewareOptions,
30
31
  apiExpressRouterFactory,
31
32
  authMiddleware,
32
33
  createApiExpressDefaultEndpointAdapter,
@@ -48,6 +49,7 @@ describe("the barrel's shape", () => {
48
49
  | "createApiExpressDefaultEndpointAdapter"
49
50
  | "handleErrors"
50
51
  | "authMiddleware"
52
+ | "createMemoryJwtReplayGuard"
51
53
  | "verifySignature"
52
54
  | "requestLoggerMiddleware"
53
55
  >();
@@ -123,9 +125,13 @@ describe("the endpoint adapter interface", () => {
123
125
  });
124
126
 
125
127
  describe("the middleware", () => {
126
- test("authMiddleware takes an optional pair and an optional auth account", () => {
128
+ test("authMiddleware takes an optional pair, auth account and options", () => {
127
129
  expectTypeOf(authMiddleware).parameters.toEqualTypeOf<
128
- [pair: KeyringPair | undefined, authAccount?: KeyringPair | undefined]
130
+ [
131
+ pair: KeyringPair | undefined,
132
+ authAccount?: KeyringPair | undefined,
133
+ options?: AuthMiddlewareOptions,
134
+ ]
129
135
  >();
130
136
  });
131
137