dbsc-toolkit 2.6.1 → 2.8.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 (122) hide show
  1. package/README.md +5 -3
  2. package/dist/client/index.d.ts +8 -1
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +49 -0
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/client/installFetchInterceptor.d.ts +41 -0
  7. package/dist/client/installFetchInterceptor.d.ts.map +1 -0
  8. package/dist/client/installFetchInterceptor.js +79 -0
  9. package/dist/client/installFetchInterceptor.js.map +1 -0
  10. package/dist/client/wrapFetch.d.ts +7 -1
  11. package/dist/client/wrapFetch.d.ts.map +1 -1
  12. package/dist/client/wrapFetch.js +1 -1
  13. package/dist/client/wrapFetch.js.map +1 -1
  14. package/dist/core/bound/proof.d.ts +8 -1
  15. package/dist/core/bound/proof.d.ts.map +1 -1
  16. package/dist/core/bound/proof.js +19 -2
  17. package/dist/core/bound/proof.js.map +1 -1
  18. package/dist/core/bound/refresh.d.ts.map +1 -1
  19. package/dist/core/bound/refresh.js +7 -3
  20. package/dist/core/bound/refresh.js.map +1 -1
  21. package/dist/core/bound/registration.d.ts.map +1 -1
  22. package/dist/core/bound/registration.js +14 -3
  23. package/dist/core/bound/registration.js.map +1 -1
  24. package/dist/core/errors.d.ts +3 -0
  25. package/dist/core/errors.d.ts.map +1 -1
  26. package/dist/core/errors.js +7 -0
  27. package/dist/core/errors.js.map +1 -1
  28. package/dist/core/index.d.ts +3 -1
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/core/index.js +2 -0
  31. package/dist/core/index.js.map +1 -1
  32. package/dist/core/protect-policy.d.ts +17 -10
  33. package/dist/core/protect-policy.d.ts.map +1 -1
  34. package/dist/core/protect-policy.js.map +1 -1
  35. package/dist/core/protocol/refresh.js +2 -2
  36. package/dist/core/protocol/refresh.js.map +1 -1
  37. package/dist/core/protocol/registration.d.ts.map +1 -1
  38. package/dist/core/protocol/registration.js +3 -2
  39. package/dist/core/protocol/registration.js.map +1 -1
  40. package/dist/core/replay/interface.d.ts +10 -0
  41. package/dist/core/replay/interface.d.ts.map +1 -0
  42. package/dist/core/replay/interface.js +11 -0
  43. package/dist/core/replay/interface.js.map +1 -0
  44. package/dist/core/telemetry/polyfill-missing.d.ts +21 -0
  45. package/dist/core/telemetry/polyfill-missing.d.ts.map +1 -0
  46. package/dist/core/telemetry/polyfill-missing.js +35 -0
  47. package/dist/core/telemetry/polyfill-missing.js.map +1 -0
  48. package/dist/core/testing/memory-storage-stub.d.ts +3 -3
  49. package/dist/core/testing/memory-storage-stub.d.ts.map +1 -1
  50. package/dist/core/testing/memory-storage-stub.js +20 -8
  51. package/dist/core/testing/memory-storage-stub.js.map +1 -1
  52. package/dist/core/types.d.ts +75 -3
  53. package/dist/core/types.d.ts.map +1 -1
  54. package/dist/express/index.d.ts +3 -1
  55. package/dist/express/index.d.ts.map +1 -1
  56. package/dist/express/index.js +34 -4
  57. package/dist/express/index.js.map +1 -1
  58. package/dist/express/proof.d.ts +16 -2
  59. package/dist/express/proof.d.ts.map +1 -1
  60. package/dist/express/proof.js +2 -1
  61. package/dist/express/proof.js.map +1 -1
  62. package/dist/express/require-proof.d.ts.map +1 -1
  63. package/dist/express/require-proof.js +1 -0
  64. package/dist/express/require-proof.js.map +1 -1
  65. package/dist/fastify/index.d.ts +2 -1
  66. package/dist/fastify/index.d.ts.map +1 -1
  67. package/dist/fastify/index.js +27 -4
  68. package/dist/fastify/index.js.map +1 -1
  69. package/dist/fastify/proof.d.ts +8 -2
  70. package/dist/fastify/proof.d.ts.map +1 -1
  71. package/dist/fastify/proof.js +2 -1
  72. package/dist/fastify/proof.js.map +1 -1
  73. package/dist/fastify/require-proof.d.ts.map +1 -1
  74. package/dist/fastify/require-proof.js +1 -0
  75. package/dist/fastify/require-proof.js.map +1 -1
  76. package/dist/hono/index.d.ts +2 -1
  77. package/dist/hono/index.d.ts.map +1 -1
  78. package/dist/hono/index.js +27 -4
  79. package/dist/hono/index.js.map +1 -1
  80. package/dist/hono/proof.d.ts +8 -2
  81. package/dist/hono/proof.d.ts.map +1 -1
  82. package/dist/hono/proof.js +2 -1
  83. package/dist/hono/proof.js.map +1 -1
  84. package/dist/hono/require-proof.d.ts.map +1 -1
  85. package/dist/hono/require-proof.js +1 -0
  86. package/dist/hono/require-proof.js.map +1 -1
  87. package/dist/nextjs/create-dbsc.d.ts.map +1 -1
  88. package/dist/nextjs/create-dbsc.js +5 -1
  89. package/dist/nextjs/create-dbsc.js.map +1 -1
  90. package/dist/nextjs/index.d.ts +2 -0
  91. package/dist/nextjs/index.d.ts.map +1 -1
  92. package/dist/nextjs/index.js +32 -4
  93. package/dist/nextjs/index.js.map +1 -1
  94. package/dist/nextjs/proof.d.ts +8 -2
  95. package/dist/nextjs/proof.d.ts.map +1 -1
  96. package/dist/nextjs/proof.js +2 -1
  97. package/dist/nextjs/proof.js.map +1 -1
  98. package/dist/nextjs/require-proof.d.ts.map +1 -1
  99. package/dist/nextjs/require-proof.js +1 -0
  100. package/dist/nextjs/require-proof.js.map +1 -1
  101. package/dist/storage/memory/index.d.ts +4 -3
  102. package/dist/storage/memory/index.d.ts.map +1 -1
  103. package/dist/storage/memory/index.js +23 -8
  104. package/dist/storage/memory/index.js.map +1 -1
  105. package/dist/storage/memory/replay-cache.d.ts +15 -0
  106. package/dist/storage/memory/replay-cache.d.ts.map +1 -0
  107. package/dist/storage/memory/replay-cache.js +28 -0
  108. package/dist/storage/memory/replay-cache.js.map +1 -0
  109. package/dist/storage/postgres/index.d.ts +3 -3
  110. package/dist/storage/postgres/index.d.ts.map +1 -1
  111. package/dist/storage/postgres/index.js +24 -7
  112. package/dist/storage/postgres/index.js.map +1 -1
  113. package/dist/storage/redis/index.d.ts +4 -3
  114. package/dist/storage/redis/index.d.ts.map +1 -1
  115. package/dist/storage/redis/index.js +49 -10
  116. package/dist/storage/redis/index.js.map +1 -1
  117. package/dist/storage/redis/replay-cache.d.ts +17 -0
  118. package/dist/storage/redis/replay-cache.d.ts.map +1 -0
  119. package/dist/storage/redis/replay-cache.js +22 -0
  120. package/dist/storage/redis/replay-cache.js.map +1 -0
  121. package/migrations/002_bound_key_kind.sql +26 -0
  122. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  export class MemoryStorage {
2
2
  sessions = new Map();
3
+ // Keyed by `${sessionId}:${kind}`. A session can hold up to two rows
4
+ // (one per kind) — see BoundKey.kind in core/types.ts.
3
5
  keys = new Map();
4
6
  challenges = new Map();
5
7
  revoked = new Set();
@@ -18,16 +20,26 @@ export class MemoryStorage {
18
20
  }
19
21
  async deleteSession(id) {
20
22
  this.sessions.delete(id);
21
- this.keys.delete(id);
23
+ this.keys.delete(`${id}:native`);
24
+ this.keys.delete(`${id}:bound`);
22
25
  }
23
- async getBoundKey(sessionId) {
24
- return this.keys.get(sessionId) ?? null;
26
+ async getBoundKey(sessionId, kind) {
27
+ if (kind)
28
+ return this.keys.get(`${sessionId}:${kind}`) ?? null;
29
+ return (this.keys.get(`${sessionId}:native`) ??
30
+ this.keys.get(`${sessionId}:bound`) ??
31
+ null);
25
32
  }
26
33
  async setBoundKey(key) {
27
- this.keys.set(key.sessionId, key);
34
+ this.keys.set(`${key.sessionId}:${key.kind}`, key);
28
35
  }
29
- async deleteBoundKey(sessionId) {
30
- this.keys.delete(sessionId);
36
+ async deleteBoundKey(sessionId, kind) {
37
+ if (kind) {
38
+ this.keys.delete(`${sessionId}:${kind}`);
39
+ return;
40
+ }
41
+ this.keys.delete(`${sessionId}:native`);
42
+ this.keys.delete(`${sessionId}:bound`);
31
43
  }
32
44
  async getChallenge(jti) {
33
45
  const challenge = this.challenges.get(jti);
@@ -52,14 +64,16 @@ export class MemoryStorage {
52
64
  async revokeSession(sessionId) {
53
65
  this.revoked.add(sessionId);
54
66
  this.sessions.delete(sessionId);
55
- this.keys.delete(sessionId);
67
+ this.keys.delete(`${sessionId}:native`);
68
+ this.keys.delete(`${sessionId}:bound`);
56
69
  }
57
70
  async revokeAllForUser(userId) {
58
71
  for (const [id, sess] of this.sessions.entries()) {
59
72
  if (sess.userId === userId) {
60
73
  this.revoked.add(id);
61
74
  this.sessions.delete(id);
62
- this.keys.delete(id);
75
+ this.keys.delete(`${id}:native`);
76
+ this.keys.delete(`${id}:bound`);
63
77
  }
64
78
  }
65
79
  }
@@ -76,4 +90,5 @@ export class MemoryStorage {
76
90
  }
77
91
  }
78
92
  }
93
+ export { MemoryReplayCache } from "./replay-cache.js";
79
94
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/memory/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/memory/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ProofReplayCache } from "../../core/index.js";
2
+ /**
3
+ * In-process replay cache for per-request proofs. Dev / single-process only —
4
+ * does not synchronize across replicas. Each entry expires automatically via
5
+ * setTimeout, so memory does not grow unbounded.
6
+ *
7
+ * For production, use `RedisReplayCache` from `dbsc-toolkit/storage/redis`.
8
+ */
9
+ export declare class MemoryReplayCache implements ProofReplayCache {
10
+ private readonly seen;
11
+ checkAndRecord(key: string, ttlMs: number): Promise<boolean>;
12
+ /** Drop all entries. Useful in tests. */
13
+ clear(): void;
14
+ }
15
+ //# sourceMappingURL=replay-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-cache.d.ts","sourceRoot":"","sources":["../../../src/storage/memory/replay-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;;;;;GAMG;AACH,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoD;IAEnE,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWlE,yCAAyC;IACzC,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * In-process replay cache for per-request proofs. Dev / single-process only —
3
+ * does not synchronize across replicas. Each entry expires automatically via
4
+ * setTimeout, so memory does not grow unbounded.
5
+ *
6
+ * For production, use `RedisReplayCache` from `dbsc-toolkit/storage/redis`.
7
+ */
8
+ export class MemoryReplayCache {
9
+ seen = new Map();
10
+ async checkAndRecord(key, ttlMs) {
11
+ if (this.seen.has(key))
12
+ return false;
13
+ const handle = setTimeout(() => this.seen.delete(key), ttlMs);
14
+ // Allow the Node process to exit even if entries are still in the map.
15
+ if (typeof handle.unref === "function") {
16
+ handle.unref();
17
+ }
18
+ this.seen.set(key, handle);
19
+ return true;
20
+ }
21
+ /** Drop all entries. Useful in tests. */
22
+ clear() {
23
+ for (const handle of this.seen.values())
24
+ clearTimeout(handle);
25
+ this.seen.clear();
26
+ }
27
+ }
28
+ //# sourceMappingURL=replay-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-cache.js","sourceRoot":"","sources":["../../../src/storage/memory/replay-cache.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACX,IAAI,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEzE,KAAK,CAAC,cAAc,CAAC,GAAW,EAAE,KAAa;QAC7C,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9D,uEAAuE;QACvE,IAAI,OAAQ,MAAiC,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAClE,MAAgC,CAAC,KAAK,EAAE,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yCAAyC;IACzC,KAAK;QACH,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;CACF"}
@@ -1,14 +1,14 @@
1
1
  import type { Pool } from "pg";
2
- import type { StorageAdapter, Session, BoundKey, Challenge } from "../../core/index.js";
2
+ import type { StorageAdapter, Session, BoundKey, BoundKeyKind, Challenge } from "../../core/index.js";
3
3
  export declare class PostgresStorage implements StorageAdapter {
4
4
  private readonly pool;
5
5
  constructor(pool: Pool);
6
6
  getSession(id: string): Promise<Session | null>;
7
7
  setSession(session: Session): Promise<void>;
8
8
  deleteSession(id: string): Promise<void>;
9
- getBoundKey(sessionId: string): Promise<BoundKey | null>;
9
+ getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
10
10
  setBoundKey(key: BoundKey): Promise<void>;
11
- deleteBoundKey(sessionId: string): Promise<void>;
11
+ deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
12
12
  getChallenge(jti: string): Promise<Challenge | null>;
13
13
  setChallenge(challenge: Challenge): Promise<void>;
14
14
  consumeChallenge(jti: string): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAExF,qBAAa,eAAgB,YAAW,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IA6B/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAsBxD,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAwBpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CASrC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,SAAS,EACV,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,eAAgB,YAAW,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IA6B/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAqC7E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAwBpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CASrC"}
@@ -28,24 +28,41 @@ export class PostgresStorage {
28
28
  async deleteSession(id) {
29
29
  await this.pool.query("DELETE FROM dbsc_sessions WHERE id = $1", [id]);
30
30
  }
31
- async getBoundKey(sessionId) {
32
- const { rows } = await this.pool.query("SELECT session_id, jwk, algorithm, created_at FROM dbsc_bound_keys WHERE session_id = $1", [sessionId]);
33
- const row = rows[0];
31
+ async getBoundKey(sessionId, kind) {
32
+ let row;
33
+ if (kind) {
34
+ const { rows } = await this.pool.query("SELECT session_id, kind, jwk, algorithm, created_at FROM dbsc_bound_keys WHERE session_id = $1 AND kind = $2", [sessionId, kind]);
35
+ row = rows[0];
36
+ }
37
+ else {
38
+ // Prefer "native" over "bound" so the v2.6 single-key callers keep
39
+ // their previous behavior on Chromium-style sessions.
40
+ const { rows } = await this.pool.query(`SELECT session_id, kind, jwk, algorithm, created_at FROM dbsc_bound_keys
41
+ WHERE session_id = $1
42
+ ORDER BY CASE kind WHEN 'native' THEN 0 ELSE 1 END
43
+ LIMIT 1`, [sessionId]);
44
+ row = rows[0];
45
+ }
34
46
  if (!row)
35
47
  return null;
36
48
  return {
37
49
  sessionId: row.session_id,
50
+ kind: row.kind ?? "native",
38
51
  jwk: row.jwk,
39
52
  algorithm: row.algorithm,
40
53
  createdAt: parseInt(row.created_at, 10),
41
54
  };
42
55
  }
43
56
  async setBoundKey(key) {
44
- await this.pool.query(`INSERT INTO dbsc_bound_keys (session_id, jwk, algorithm, created_at)
45
- VALUES ($1, $2, $3, $4)
46
- ON CONFLICT (session_id) DO UPDATE SET jwk = $2, algorithm = $3`, [key.sessionId, JSON.stringify(key.jwk), key.algorithm, key.createdAt]);
57
+ await this.pool.query(`INSERT INTO dbsc_bound_keys (session_id, kind, jwk, algorithm, created_at)
58
+ VALUES ($1, $2, $3, $4, $5)
59
+ ON CONFLICT (session_id, kind) DO UPDATE SET jwk = $3, algorithm = $4`, [key.sessionId, key.kind, JSON.stringify(key.jwk), key.algorithm, key.createdAt]);
47
60
  }
48
- async deleteBoundKey(sessionId) {
61
+ async deleteBoundKey(sessionId, kind) {
62
+ if (kind) {
63
+ await this.pool.query("DELETE FROM dbsc_bound_keys WHERE session_id = $1 AND kind = $2", [sessionId, kind]);
64
+ return;
65
+ }
49
66
  await this.pool.query("DELETE FROM dbsc_bound_keys WHERE session_id = $1", [sessionId]);
50
67
  }
51
68
  async getChallenge(jti) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/postgres/index.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,19 @@
1
1
  import type { Redis } from "ioredis";
2
- import type { StorageAdapter, Session, BoundKey, Challenge } from "../../core/index.js";
2
+ import type { StorageAdapter, Session, BoundKey, BoundKeyKind, Challenge } from "../../core/index.js";
3
3
  export declare class RedisStorage implements StorageAdapter {
4
4
  private readonly client;
5
5
  constructor(client: Redis);
6
6
  getSession(id: string): Promise<Session | null>;
7
7
  setSession(session: Session): Promise<void>;
8
8
  deleteSession(id: string): Promise<void>;
9
- getBoundKey(sessionId: string): Promise<BoundKey | null>;
9
+ getBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<BoundKey | null>;
10
10
  setBoundKey(key: BoundKey): Promise<void>;
11
- deleteBoundKey(sessionId: string): Promise<void>;
11
+ deleteBoundKey(sessionId: string, kind?: BoundKeyKind): Promise<void>;
12
12
  getChallenge(jti: string): Promise<Challenge | null>;
13
13
  setChallenge(challenge: Challenge): Promise<void>;
14
14
  consumeChallenge(jti: string): Promise<boolean>;
15
15
  revokeSession(sessionId: string): Promise<void>;
16
16
  revokeAllForUser(userId: string): Promise<void>;
17
17
  }
18
+ export { RedisReplayCache } from "./replay-cache.js";
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AA0BxF,qBAAa,YAAa,YAAW,cAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK;IAEpC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAM/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMxD,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAMpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYtD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,SAAS,EACV,MAAM,qBAAqB,CAAC;AA8B7B,qBAAa,YAAa,YAAW,cAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK;IAEpC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAM/C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA6B7E,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAarE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAMpD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CActD;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,6 +1,10 @@
1
1
  const KEY = {
2
2
  session: (id) => `dbsc:session:${id}`,
3
- key: (sessionId) => `dbsc:key:${sessionId}`,
3
+ // v2.7+ keys include the kind suffix. The unsuffixed v2.6 layout is read once
4
+ // as a back-compat fallback in getBoundKey and rewritten under the new layout
5
+ // the next time the key is set.
6
+ key: (sessionId, kind) => `dbsc:key:${sessionId}:${kind}`,
7
+ legacyKey: (sessionId) => `dbsc:key:${sessionId}`,
4
8
  challenge: (jti) => `dbsc:challenge:${jti}`,
5
9
  userSessions: (userId) => `dbsc:user:${userId}:sessions`,
6
10
  };
@@ -41,19 +45,51 @@ export class RedisStorage {
41
45
  const sess = JSON.parse(raw);
42
46
  await this.client.srem(KEY.userSessions(sess.userId), id);
43
47
  }
44
- await this.client.del(KEY.session(id), KEY.key(id));
48
+ await this.client.del(KEY.session(id), KEY.key(id, "native"), KEY.key(id, "bound"), KEY.legacyKey(id));
45
49
  }
46
- async getBoundKey(sessionId) {
47
- const raw = await this.client.get(KEY.key(sessionId));
48
- if (!raw)
50
+ async getBoundKey(sessionId, kind) {
51
+ if (kind) {
52
+ const raw = await this.client.get(KEY.key(sessionId, kind));
53
+ if (raw)
54
+ return JSON.parse(raw);
55
+ // v2.6 back-compat: an unsuffixed row was always a native key.
56
+ if (kind === "native") {
57
+ const legacy = await this.client.get(KEY.legacyKey(sessionId));
58
+ if (legacy) {
59
+ const parsed = JSON.parse(legacy);
60
+ // Older rows may not carry `kind`; treat as native.
61
+ return { ...parsed, kind: "native" };
62
+ }
63
+ }
49
64
  return null;
50
- return JSON.parse(raw);
65
+ }
66
+ const [n, b] = await this.client.mget(KEY.key(sessionId, "native"), KEY.key(sessionId, "bound"));
67
+ if (n)
68
+ return JSON.parse(n);
69
+ if (b)
70
+ return JSON.parse(b);
71
+ const legacy = await this.client.get(KEY.legacyKey(sessionId));
72
+ if (legacy) {
73
+ const parsed = JSON.parse(legacy);
74
+ return { ...parsed, kind: "native" };
75
+ }
76
+ return null;
51
77
  }
52
78
  async setBoundKey(key) {
53
- await this.client.set(KEY.key(key.sessionId), JSON.stringify(key));
79
+ await this.client.set(KEY.key(key.sessionId, key.kind), JSON.stringify(key));
80
+ // Stamp out the legacy unsuffixed key so a future read can't shadow the new layout.
81
+ if (key.kind === "native") {
82
+ await this.client.del(KEY.legacyKey(key.sessionId));
83
+ }
54
84
  }
55
- async deleteBoundKey(sessionId) {
56
- await this.client.del(KEY.key(sessionId));
85
+ async deleteBoundKey(sessionId, kind) {
86
+ if (kind) {
87
+ await this.client.del(KEY.key(sessionId, kind));
88
+ if (kind === "native")
89
+ await this.client.del(KEY.legacyKey(sessionId));
90
+ return;
91
+ }
92
+ await this.client.del(KEY.key(sessionId, "native"), KEY.key(sessionId, "bound"), KEY.legacyKey(sessionId));
57
93
  }
58
94
  async getChallenge(jti) {
59
95
  const raw = await this.client.get(KEY.challenge(jti));
@@ -79,10 +115,13 @@ export class RedisStorage {
79
115
  const pipeline = this.client.pipeline();
80
116
  for (const id of sessionIds) {
81
117
  pipeline.del(KEY.session(id));
82
- pipeline.del(KEY.key(id));
118
+ pipeline.del(KEY.key(id, "native"));
119
+ pipeline.del(KEY.key(id, "bound"));
120
+ pipeline.del(KEY.legacyKey(id));
83
121
  }
84
122
  pipeline.del(KEY.userSessions(userId));
85
123
  await pipeline.exec();
86
124
  }
87
125
  }
126
+ export { RedisReplayCache } from "./replay-cache.js";
88
127
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/redis/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Redis } from "ioredis";
2
+ import type { ProofReplayCache } from "../../core/index.js";
3
+ /**
4
+ * Redis-backed replay cache for per-request proofs. Multi-process safe. Use in
5
+ * production behind any deployment with >1 instance (load-balanced, autoscaled,
6
+ * blue/green). Backed by `SET NX EX`, so the check-and-record is atomic.
7
+ *
8
+ * Keys live under `dbsc:proof:` and expire automatically via Redis TTL — no
9
+ * background GC required.
10
+ */
11
+ export declare class RedisReplayCache implements ProofReplayCache {
12
+ private readonly client;
13
+ private readonly keyPrefix;
14
+ constructor(client: Redis, keyPrefix?: string);
15
+ checkAndRecord(key: string, ttlMs: number): Promise<boolean>;
16
+ }
17
+ //# sourceMappingURL=replay-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-cache.d.ts","sourceRoot":"","sources":["../../../src/storage/redis/replay-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;;;;;;GAOG;AACH,qBAAa,gBAAiB,YAAW,gBAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAS,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAzC,MAAM,EAAE,KAAK,EAAmB,SAAS,SAAgB;IAEhF,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAWnE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Redis-backed replay cache for per-request proofs. Multi-process safe. Use in
3
+ * production behind any deployment with >1 instance (load-balanced, autoscaled,
4
+ * blue/green). Backed by `SET NX EX`, so the check-and-record is atomic.
5
+ *
6
+ * Keys live under `dbsc:proof:` and expire automatically via Redis TTL — no
7
+ * background GC required.
8
+ */
9
+ export class RedisReplayCache {
10
+ client;
11
+ keyPrefix;
12
+ constructor(client, keyPrefix = "dbsc:proof:") {
13
+ this.client = client;
14
+ this.keyPrefix = keyPrefix;
15
+ }
16
+ async checkAndRecord(key, ttlMs) {
17
+ const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));
18
+ const result = await this.client.set(`${this.keyPrefix}${key}`, "1", "EX", ttlSeconds, "NX");
19
+ return result === "OK";
20
+ }
21
+ }
22
+ //# sourceMappingURL=replay-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-cache.js","sourceRoot":"","sources":["../../../src/storage/redis/replay-cache.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAgB;IACE;IAAgC;IAA7D,YAA6B,MAAa,EAAmB,YAAY,aAAa;QAAzD,WAAM,GAAN,MAAM,CAAO;QAAmB,cAAS,GAAT,SAAS,CAAgB;IAAG,CAAC;IAE1F,KAAK,CAAC,cAAc,CAAC,GAAW,EAAE,KAAa;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAClC,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,EAAE,EACzB,GAAG,EACH,IAAI,EACJ,UAAU,EACV,IAAI,CACL,CAAC;QACF,OAAO,MAAM,KAAK,IAAI,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ -- v2.7.0: a single session can hold two bound keys — one TPM/native key used
2
+ -- by /dbsc/refresh, and one polyfill ECDSA key used by requireProof() on
3
+ -- every guarded request and by /dbsc-bound/refresh. The composite primary
4
+ -- key (session_id, kind) replaces session_id alone.
5
+ --
6
+ -- The migration is non-destructive: every existing row was a native key
7
+ -- (Chromium TPM) or a polyfill key written by the same code path, and v2.6
8
+ -- never wrote two rows per session — so back-filling kind='native' matches
9
+ -- the prior call-site semantics. Apps that ran the bound polyfill before
10
+ -- v2.7 will read those rows under kind='native' once; the next refresh
11
+ -- rewrites them under kind='bound'. The kind-less getBoundKey() in the
12
+ -- v2.7 adapter prefers native then falls back to bound, which is what every
13
+ -- old call site expected.
14
+
15
+ BEGIN;
16
+
17
+ ALTER TABLE dbsc_bound_keys
18
+ ADD COLUMN IF NOT EXISTS kind TEXT NOT NULL DEFAULT 'native'
19
+ CHECK (kind IN ('native', 'bound'));
20
+
21
+ ALTER TABLE dbsc_bound_keys DROP CONSTRAINT IF EXISTS dbsc_bound_keys_pkey;
22
+
23
+ ALTER TABLE dbsc_bound_keys
24
+ ADD CONSTRAINT dbsc_bound_keys_pkey PRIMARY KEY (session_id, kind);
25
+
26
+ COMMIT;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbsc-toolkit",
3
- "version": "2.6.1",
3
+ "version": "2.8.0",
4
4
  "description": "Server-side Device Bound Session Credentials (DBSC) for Node.js plus a Web Crypto polyfill for Firefox, Safari, and older Chromium. Cookie-theft protection on every modern browser.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",