ioredis-toolkit 0.0.10 → 0.5.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 (267) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/LICENSE +1 -1
  3. package/README.md +68 -1613
  4. package/dist/cache/cache.d.ts +30 -0
  5. package/dist/cache/cache.d.ts.map +1 -0
  6. package/dist/cache/cache.js +59 -0
  7. package/dist/cache/cache.js.map +1 -0
  8. package/dist/cache/config.d.ts +12 -0
  9. package/dist/cache/config.d.ts.map +1 -0
  10. package/dist/cache/config.js +13 -0
  11. package/dist/cache/config.js.map +1 -0
  12. package/dist/cache/types.d.ts +32 -0
  13. package/dist/cache/types.d.ts.map +1 -0
  14. package/dist/cache/types.js +5 -0
  15. package/dist/cache/types.js.map +1 -0
  16. package/dist/index.d.ts +43 -51
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +32 -44
  19. package/dist/index.js.map +1 -0
  20. package/dist/lock/config.d.ts +12 -0
  21. package/dist/lock/config.d.ts.map +1 -0
  22. package/dist/lock/config.js +8 -0
  23. package/dist/lock/config.js.map +1 -0
  24. package/dist/lock/lock.d.ts +20 -0
  25. package/dist/lock/lock.d.ts.map +1 -0
  26. package/dist/lock/lock.js +44 -0
  27. package/dist/lock/lock.js.map +1 -0
  28. package/dist/lock/types.d.ts +19 -0
  29. package/dist/lock/types.d.ts.map +1 -0
  30. package/dist/lock/types.js +2 -0
  31. package/dist/lock/types.js.map +1 -0
  32. package/dist/modules-config.d.ts +3 -0
  33. package/dist/modules-config.d.ts.map +1 -0
  34. package/dist/modules-config.js +2 -0
  35. package/dist/modules-config.js.map +1 -0
  36. package/dist/pubsub/config.d.ts +11 -0
  37. package/dist/pubsub/config.d.ts.map +1 -0
  38. package/dist/pubsub/config.js +6 -0
  39. package/dist/pubsub/config.js.map +1 -0
  40. package/dist/pubsub/pubsub.d.ts +20 -0
  41. package/dist/pubsub/pubsub.d.ts.map +1 -0
  42. package/dist/pubsub/pubsub.js +54 -0
  43. package/dist/pubsub/pubsub.js.map +1 -0
  44. package/dist/pubsub/types.d.ts +24 -0
  45. package/dist/pubsub/types.d.ts.map +1 -0
  46. package/dist/pubsub/types.js +2 -0
  47. package/dist/pubsub/types.js.map +1 -0
  48. package/dist/rate-limit/config.d.ts +12 -0
  49. package/dist/rate-limit/config.d.ts.map +1 -0
  50. package/dist/rate-limit/config.js +6 -0
  51. package/dist/rate-limit/config.js.map +1 -0
  52. package/dist/rate-limit/rate-limiter.d.ts +18 -0
  53. package/dist/rate-limit/rate-limiter.d.ts.map +1 -0
  54. package/dist/rate-limit/rate-limiter.js +37 -0
  55. package/dist/rate-limit/rate-limiter.js.map +1 -0
  56. package/dist/rate-limit/types.d.ts +27 -0
  57. package/dist/rate-limit/types.d.ts.map +1 -0
  58. package/dist/rate-limit/types.js +2 -0
  59. package/dist/rate-limit/types.js.map +1 -0
  60. package/dist/redis/client-facade.d.ts +77 -0
  61. package/dist/redis/client-facade.d.ts.map +1 -0
  62. package/dist/redis/client-facade.js +102 -0
  63. package/dist/redis/client-facade.js.map +1 -0
  64. package/dist/redis/client.d.ts +10 -0
  65. package/dist/redis/client.d.ts.map +1 -0
  66. package/dist/redis/client.js +29 -0
  67. package/dist/redis/client.js.map +1 -0
  68. package/dist/redis/cluster.d.ts +7 -0
  69. package/dist/redis/cluster.d.ts.map +1 -0
  70. package/dist/redis/cluster.js +47 -0
  71. package/dist/redis/cluster.js.map +1 -0
  72. package/dist/redis/config.d.ts +39 -0
  73. package/dist/redis/config.d.ts.map +1 -0
  74. package/dist/redis/config.js +52 -0
  75. package/dist/redis/config.js.map +1 -0
  76. package/dist/redis/errors.d.ts +5 -0
  77. package/dist/redis/errors.d.ts.map +1 -0
  78. package/dist/redis/errors.js +5 -0
  79. package/dist/redis/errors.js.map +1 -0
  80. package/dist/redis/types.d.ts +135 -0
  81. package/dist/redis/types.d.ts.map +1 -0
  82. package/dist/redis/types.js +2 -0
  83. package/dist/redis/types.js.map +1 -0
  84. package/dist/redis/wrapper.d.ts +88 -0
  85. package/dist/redis/wrapper.d.ts.map +1 -0
  86. package/dist/redis/wrapper.js +206 -0
  87. package/dist/redis/wrapper.js.map +1 -0
  88. package/dist/session/config.d.ts +47 -0
  89. package/dist/session/config.d.ts.map +1 -0
  90. package/dist/session/config.js +101 -0
  91. package/dist/session/config.js.map +1 -0
  92. package/dist/session/cookie.d.ts +16 -0
  93. package/dist/session/cookie.d.ts.map +1 -0
  94. package/dist/session/cookie.js +28 -0
  95. package/dist/session/cookie.js.map +1 -0
  96. package/dist/session/errors.d.ts +56 -0
  97. package/dist/session/errors.d.ts.map +1 -0
  98. package/dist/session/errors.js +58 -0
  99. package/dist/session/errors.js.map +1 -0
  100. package/dist/session/factory.d.ts +21 -0
  101. package/dist/session/factory.d.ts.map +1 -0
  102. package/dist/session/factory.js +30 -0
  103. package/dist/session/factory.js.map +1 -0
  104. package/dist/session/health.d.ts +12 -0
  105. package/dist/session/health.d.ts.map +1 -0
  106. package/dist/session/health.js +23 -0
  107. package/dist/session/health.js.map +1 -0
  108. package/dist/session/keys.d.ts +23 -0
  109. package/dist/session/keys.d.ts.map +1 -0
  110. package/dist/session/keys.js +27 -0
  111. package/dist/session/keys.js.map +1 -0
  112. package/dist/session/manager.d.ts +34 -0
  113. package/dist/session/manager.d.ts.map +1 -0
  114. package/dist/session/manager.js +31 -0
  115. package/dist/session/manager.js.map +1 -0
  116. package/dist/session/metrics.d.ts +11 -0
  117. package/dist/session/metrics.d.ts.map +1 -0
  118. package/dist/session/metrics.js +10 -0
  119. package/dist/session/metrics.js.map +1 -0
  120. package/dist/session/repository.d.ts +49 -0
  121. package/dist/session/repository.d.ts.map +1 -0
  122. package/dist/session/repository.js +203 -0
  123. package/dist/session/repository.js.map +1 -0
  124. package/dist/session/revocation.d.ts +22 -0
  125. package/dist/session/revocation.d.ts.map +1 -0
  126. package/dist/session/revocation.js +41 -0
  127. package/dist/session/revocation.js.map +1 -0
  128. package/dist/session/script-sources.d.ts +11 -0
  129. package/dist/session/script-sources.d.ts.map +1 -0
  130. package/dist/session/script-sources.js +140 -0
  131. package/dist/session/script-sources.js.map +1 -0
  132. package/dist/session/scripts.d.ts +15 -0
  133. package/dist/session/scripts.d.ts.map +1 -0
  134. package/dist/session/scripts.js +41 -0
  135. package/dist/session/scripts.js.map +1 -0
  136. package/dist/session/serializer.d.ts +12 -0
  137. package/dist/session/serializer.d.ts.map +1 -0
  138. package/dist/session/serializer.js +77 -0
  139. package/dist/session/serializer.js.map +1 -0
  140. package/dist/session/service.d.ts +48 -0
  141. package/dist/session/service.d.ts.map +1 -0
  142. package/dist/session/service.js +235 -0
  143. package/dist/session/service.js.map +1 -0
  144. package/dist/session/token.d.ts +16 -0
  145. package/dist/session/token.d.ts.map +1 -0
  146. package/dist/session/token.js +32 -0
  147. package/dist/session/token.js.map +1 -0
  148. package/dist/session/types.d.ts +134 -0
  149. package/dist/session/types.d.ts.map +1 -0
  150. package/dist/session/types.js +2 -0
  151. package/dist/session/types.js.map +1 -0
  152. package/dist/streams/config.d.ts +12 -0
  153. package/dist/streams/config.d.ts.map +1 -0
  154. package/dist/streams/config.js +6 -0
  155. package/dist/streams/config.js.map +1 -0
  156. package/dist/streams/streams.d.ts +24 -0
  157. package/dist/streams/streams.d.ts.map +1 -0
  158. package/dist/streams/streams.js +55 -0
  159. package/dist/streams/streams.js.map +1 -0
  160. package/dist/streams/types.d.ts +32 -0
  161. package/dist/streams/types.d.ts.map +1 -0
  162. package/dist/streams/types.js +2 -0
  163. package/dist/streams/types.js.map +1 -0
  164. package/docs/ACCEPTANCE-REPORT.md +70 -0
  165. package/docs/ARCHITECTURE.md +61 -0
  166. package/docs/CAPACITY.md +33 -0
  167. package/docs/DEPLOYMENT.md +22 -0
  168. package/docs/README-API.md +15 -0
  169. package/docs/STATE-MACHINE.md +38 -0
  170. package/docs/TESTING.md +37 -0
  171. package/docs/THREAT-MODEL.md +23 -0
  172. package/docs/TYPE-SAFETY.md +34 -0
  173. package/docs/modules/cache/README.md +7 -0
  174. package/docs/modules/cache/usage.md +156 -0
  175. package/docs/modules/lock/README.md +7 -0
  176. package/docs/modules/lock/usage.md +105 -0
  177. package/docs/modules/pubsub/README.md +7 -0
  178. package/docs/modules/pubsub/usage.md +106 -0
  179. package/docs/modules/rate-limit/README.md +7 -0
  180. package/docs/modules/rate-limit/usage.md +100 -0
  181. package/docs/modules/sessions/README.md +7 -0
  182. package/docs/modules/sessions/usage.md +262 -0
  183. package/docs/modules/streams/README.md +7 -0
  184. package/docs/modules/streams/usage.md +141 -0
  185. package/package.json +50 -60
  186. package/src/scripts/cleanup-index.lua +4 -0
  187. package/src/scripts/conditional-update.lua +21 -0
  188. package/src/scripts/consume-session.lua +21 -0
  189. package/src/scripts/create-session.lua +28 -0
  190. package/src/scripts/delete.lua +2 -0
  191. package/src/scripts/destroy-user.lua +13 -0
  192. package/src/scripts/enforce-limit.lua +17 -0
  193. package/src/scripts/revoke-session.lua +13 -0
  194. package/src/scripts/rotate.lua +24 -0
  195. package/src/scripts/touch-session.lua +28 -0
  196. package/src/scripts/update-session.lua +18 -0
  197. package/dist/cache.d.ts +0 -797
  198. package/dist/cache.js +0 -1115
  199. package/dist/client.d.ts +0 -287
  200. package/dist/client.js +0 -1113
  201. package/dist/cluster-slot.d.ts +0 -4
  202. package/dist/cluster-slot.js +0 -31
  203. package/dist/cluster.d.ts +0 -79
  204. package/dist/cluster.js +0 -156
  205. package/dist/errors.d.ts +0 -30
  206. package/dist/errors.js +0 -63
  207. package/dist/health.d.ts +0 -180
  208. package/dist/health.js +0 -239
  209. package/dist/lock.d.ts +0 -233
  210. package/dist/lock.js +0 -440
  211. package/dist/logger.d.ts +0 -12
  212. package/dist/logger.js +0 -40
  213. package/dist/pubsub.d.ts +0 -423
  214. package/dist/pubsub.js +0 -537
  215. package/dist/ratelimiter.d.ts +0 -441
  216. package/dist/ratelimiter.js +0 -539
  217. package/dist/session/index.d.ts +0 -23
  218. package/dist/session/index.js +0 -16
  219. package/dist/session/revocation-store.d.ts +0 -176
  220. package/dist/session/revocation-store.js +0 -318
  221. package/dist/session/scripts/cleanup-index.lua +0 -21
  222. package/dist/session/scripts/conditional-update-encrypted.lua +0 -60
  223. package/dist/session/scripts/conditional-update.lua +0 -63
  224. package/dist/session/scripts/create.lua +0 -83
  225. package/dist/session/scripts/delete-by-user.lua +0 -29
  226. package/dist/session/scripts/delete.lua +0 -15
  227. package/dist/session/scripts/enforce-limit.lua +0 -38
  228. package/dist/session/scripts/revoke.lua +0 -61
  229. package/dist/session/scripts/rotate-encrypted.lua +0 -149
  230. package/dist/session/scripts/rotate.lua +0 -167
  231. package/dist/session/scripts/touch-encrypted.lua +0 -89
  232. package/dist/session/scripts/touch.lua +0 -72
  233. package/dist/session/scripts/validate.lua +0 -90
  234. package/dist/session/session-circuit-breaker.d.ts +0 -42
  235. package/dist/session/session-circuit-breaker.js +0 -129
  236. package/dist/session/session-config.d.ts +0 -355
  237. package/dist/session/session-config.js +0 -171
  238. package/dist/session/session-cookie.d.ts +0 -72
  239. package/dist/session/session-cookie.js +0 -101
  240. package/dist/session/session-encryption.d.ts +0 -87
  241. package/dist/session/session-encryption.js +0 -139
  242. package/dist/session/session-errors.d.ts +0 -85
  243. package/dist/session/session-errors.js +0 -145
  244. package/dist/session/session-health.d.ts +0 -38
  245. package/dist/session/session-health.js +0 -60
  246. package/dist/session/session-keys.d.ts +0 -64
  247. package/dist/session/session-keys.js +0 -128
  248. package/dist/session/session-manager.d.ts +0 -73
  249. package/dist/session/session-manager.js +0 -94
  250. package/dist/session/session-metrics.d.ts +0 -41
  251. package/dist/session/session-metrics.js +0 -135
  252. package/dist/session/session-repository.d.ts +0 -184
  253. package/dist/session/session-repository.js +0 -763
  254. package/dist/session/session-scripts.d.ts +0 -36
  255. package/dist/session/session-scripts.js +0 -130
  256. package/dist/session/session-serializer.d.ts +0 -42
  257. package/dist/session/session-serializer.js +0 -267
  258. package/dist/session/session-service.d.ts +0 -123
  259. package/dist/session/session-service.js +0 -670
  260. package/dist/session/session-token.d.ts +0 -38
  261. package/dist/session/session-token.js +0 -86
  262. package/dist/session/session-types.d.ts +0 -281
  263. package/dist/session/session-types.js +0 -16
  264. package/dist/types.d.ts +0 -924
  265. package/dist/types.js +0 -151
  266. package/dist/utils/deepmerge.d.ts +0 -9
  267. package/dist/utils/deepmerge.js +0 -61
@@ -1,135 +0,0 @@
1
- /* -------------------------------------------------------------------------- */
2
- /* Session metrics: minimal, dependency-free observability. */
3
- /* */
4
- /* An adapter is injected by the application (Prometheus, StatsD, OpenTelemetry*/
5
- /* - whichever the app already uses). Without an adapter every call is a */
6
- /* no-op; metrics never throw and never affect the hot path. */
7
- /* */
8
- /* No session tokens or raw identifiers ever reach a metric label. */
9
- /* -------------------------------------------------------------------------- */
10
- const OPERATIONS = [
11
- 'create',
12
- 'validate',
13
- 'touch',
14
- 'rotate',
15
- 'update',
16
- 'destroy',
17
- 'revoke',
18
- 'revoke_all',
19
- 'delete_by_user',
20
- 'list',
21
- 'find_by_user',
22
- 'set_security_version',
23
- 'reconcile_user',
24
- 'health',
25
- ];
26
- /**
27
- * Internal session metrics facade. Safe no-op without an adapter.
28
- */
29
- export class SessionMetrics {
30
- adapter;
31
- topology;
32
- constructor(adapter, topology) {
33
- this.adapter = adapter ?? null;
34
- this.topology = topology ?? null;
35
- }
36
- /** Adds the constant topology label to an attribute set. */
37
- withTopology(attributes) {
38
- if (this.topology !== null)
39
- attributes.topology = this.topology;
40
- return attributes;
41
- }
42
- /** Counts a completed session operation, with its outcome. */
43
- operation(op, outcome, code) {
44
- if (!this.adapter)
45
- return;
46
- try {
47
- const attributes = { outcome };
48
- if (code)
49
- attributes.code = code;
50
- this.adapter.incCounter(`session.${op}.total`, 1, this.withTopology(attributes));
51
- }
52
- catch {
53
- // Metrics must never break authentication.
54
- }
55
- }
56
- /** Records operation latency in milliseconds. */
57
- latency(op, ms) {
58
- if (!this.adapter)
59
- return;
60
- try {
61
- this.adapter.recordHistogram(`session.${op}.duration_ms`, ms, this.topology !== null ? { topology: this.topology } : undefined);
62
- }
63
- catch {
64
- // Metrics must never break authentication.
65
- }
66
- }
67
- /** Records the circuit breaker state transition. */
68
- breakerState(state) {
69
- if (!this.adapter)
70
- return;
71
- try {
72
- this.adapter.setGauge('session.circuit_breaker.state', state === 'open' ? 2 : state === 'half_open' ? 1 : 0, this.topology !== null ? { topology: this.topology } : undefined);
73
- this.adapter.incCounter(`session.circuit_breaker.${state}`, 1, this.withTopology({}));
74
- }
75
- catch {
76
- // Metrics must never break authentication.
77
- }
78
- }
79
- /** Records a fail-closed revocation-store failure (a security-relevant miss). */
80
- revocationMiss() {
81
- if (!this.adapter)
82
- return;
83
- try {
84
- this.adapter.incCounter('session.revocation_store.fail_closed', 1, this.topology !== null ? { topology: this.topology } : undefined);
85
- }
86
- catch {
87
- // Metrics must never break authentication.
88
- }
89
- }
90
- /** Records encryption failures (key rotation issues, corruption). */
91
- encryptionError(reason) {
92
- if (!this.adapter)
93
- return;
94
- try {
95
- this.adapter.incCounter('session.encryption.errors', 1, this.withTopology({ reason }));
96
- }
97
- catch {
98
- // Metrics must never break authentication.
99
- }
100
- }
101
- /** Records a failed best-effort jti index write (derived-state degradation). */
102
- jtiIndexWriteFailure() {
103
- if (!this.adapter)
104
- return;
105
- try {
106
- this.adapter.incCounter('session.jti_index.write_failures', 1, this.topology !== null ? { topology: this.topology } : undefined);
107
- }
108
- catch {
109
- // Metrics must never break authentication.
110
- }
111
- }
112
- /**
113
- * Records the outcome of one reconcileUser() repair pass: how many
114
- * missing/stale jti-index entries it found and repaired or removed.
115
- * A non-zero count indicates upstream partial-write drift (ยง67), not an
116
- * authentication problem - the session record was authoritative and
117
- * correct throughout.
118
- */
119
- reconcileUser(repaired, removed) {
120
- if (!this.adapter)
121
- return;
122
- try {
123
- if (repaired > 0) {
124
- this.adapter.incCounter('session.jti_index.reconciled_repaired', repaired, this.topology !== null ? { topology: this.topology } : undefined);
125
- }
126
- if (removed > 0) {
127
- this.adapter.incCounter('session.jti_index.reconciled_removed', removed, this.topology !== null ? { topology: this.topology } : undefined);
128
- }
129
- }
130
- catch {
131
- // Metrics must never break authentication.
132
- }
133
- }
134
- }
135
- export const SESSION_OPERATIONS = OPERATIONS;
@@ -1,184 +0,0 @@
1
- import type { RedisClientWrapper } from '../client.js';
2
- import type { SessionConfig } from './session-config.js';
3
- import type { SessionKeyProvider } from './session-encryption.js';
4
- import type { SessionKeyStrategy } from './session-keys.js';
5
- import type { SessionScriptRegistry } from './session-scripts.js';
6
- import type { SessionRecord, SessionUpdatePatch, TouchOutcome } from './session-types.js';
7
- export declare class SessionRepository {
8
- private readonly client;
9
- private readonly keys;
10
- private readonly config;
11
- private readonly scripts;
12
- /** Encryption key provider, or null when encryption is disabled. */
13
- readonly keyProvider: SessionKeyProvider | null;
14
- constructor(options: {
15
- client: RedisClientWrapper;
16
- keys: SessionKeyStrategy;
17
- config: SessionConfig;
18
- scripts: SessionScriptRegistry;
19
- keyProvider?: SessionKeyProvider | null;
20
- });
21
- /** True when the repository can decrypt stored sessions. */
22
- hasKeyProvider(): boolean;
23
- private get encrypted();
24
- private get jtiIndexEnabled();
25
- private get maxBatchSize();
26
- private get maxFanOut();
27
- /**
28
- * Stores a session atomically with its user index entry and (bounded)
29
- * max-session eviction. Returns the outcome; on idempotent replays the
30
- * claim's jti identifies the pre-existing session.
31
- */
32
- create(record: SessionRecord, ttl: number): Promise<{
33
- status: 'created';
34
- } | {
35
- status: 'replayed';
36
- jti: string;
37
- }>;
38
- /**
39
- * Reads and deserializes a session. Returns null when missing.
40
- * Throws SessionSerializationError when the stored payload is corrupt.
41
- */
42
- get(userId: string, jti: string): Promise<SessionRecord | null>;
43
- /**
44
- * Single-round-trip validation read (session + security version).
45
- * Returns { found: false } for missing records, or the raw envelope plus
46
- * the current security version for further app-side checks.
47
- */
48
- validateRead(userId: string, jti: string): Promise<{
49
- found: false;
50
- } | {
51
- found: true;
52
- raw: string;
53
- currentSecurityVersion: number | null;
54
- } | {
55
- found: true;
56
- code: -1;
57
- status: string;
58
- } | {
59
- found: true;
60
- code: -2;
61
- } | {
62
- found: true;
63
- code: -3;
64
- } | {
65
- found: true;
66
- code: -4;
67
- }>;
68
- /** Best-effort removal of a stale jti index entry (never throws). */
69
- private cleanupJtiIndex;
70
- /**
71
- * Throttled monotonic activity refresh.
72
- *
73
- * Plain sessions: one atomic script (server time). Encrypted sessions:
74
- * read + decrypt + re-encrypt + atomic CAS (two round trips).
75
- */
76
- touch(userId: string, jti: string, force: boolean): Promise<TouchOutcome>;
77
- /**
78
- * Atomic single-use rotation. Returns the successor jti on success.
79
- *
80
- * Plain sessions: one script (server time). Encrypted sessions: read +
81
- * decrypt + build + atomic script (two round trips).
82
- */
83
- rotate(options: {
84
- userId: string;
85
- oldJti: string;
86
- successor: SessionRecord;
87
- expectedVersion?: number;
88
- rotationNonceHash?: string;
89
- retainTombstone: boolean;
90
- revokeFamilyOnReplay: boolean;
91
- }): Promise<{
92
- code: number;
93
- successorJti?: string;
94
- status?: string;
95
- familyId?: string;
96
- headJtiRevoked?: string;
97
- }>;
98
- /**
99
- * Optimistic-concurrency patch update. Returns the updated record, or
100
- * null when missing. Throws SessionConcurrencyError on version conflict.
101
- */
102
- update(userId: string, jti: string, patch: SessionUpdatePatch, expectedVersion?: number): Promise<SessionRecord | null>;
103
- /** Physically deletes a session and its index entry. Idempotent. */
104
- destroy(userId: string, jti: string): Promise<boolean>;
105
- /**
106
- * Logically revokes a session with a bounded tombstone TTL.
107
- * Returns 'revoked' | 'already_revoked' | 'not_found'.
108
- */
109
- revoke(userId: string, jti: string, tombstoneTtl: number): Promise<string>;
110
- /**
111
- * Lists a user's sessions (oldest first), lazily cleaning stale index
112
- * members. Bounded: fetches at most `limit` members plus cleanup batches.
113
- */
114
- listByUser(userId: string, options?: {
115
- limit?: number;
116
- offset?: number;
117
- }): Promise<SessionRecord[]>;
118
- /**
119
- * Bounded per-user repair pass (ยง25/ยง67/ยง68): removes stale user-index
120
- * entries (same mechanism as {@link listByUser}) and, when the global jti
121
- * index is enabled, repairs any live active session whose jti-index entry
122
- * is missing or stale (partial-write drift after create/rotate - the
123
- * session record itself was authoritative and correct the whole time,
124
- * only JTI-only lookup was degraded). Never touches consumed/revoked/
125
- * expired sessions: repairing their index entry would make them
126
- * JTI-lookupable again, which is unnecessary and works against prompt
127
- * self-expiry.
128
- *
129
- * Bounded by `limit` (capped like every other list/admin operation);
130
- * never scans the whole cluster and is safe to call from an
131
- * administrative endpoint, not a hot auth path.
132
- */
133
- reconcileUser(userId: string, limit: number, now: number): Promise<{
134
- checked: number;
135
- staleIndexRemoved: number;
136
- jtiIndexRepaired: number;
137
- }>;
138
- /**
139
- * Deletes all of a user's sessions in bounded same-slot batches.
140
- * Returns the jtis whose records were deleted.
141
- */
142
- deleteByUser(userId: string): Promise<string[]>;
143
- /**
144
- * Removes stale (missing) members from a user's index. Bounded, safe to
145
- * run repeatedly.
146
- */
147
- cleanupUserIndex(userId: string): Promise<number>;
148
- /** Removes specific stale entries from a user's index (bounded). */
149
- cleanupIndexEntries(userId: string, jtis: string[]): Promise<string[]>;
150
- /**
151
- * Standalone max-session enforcement (used after revokeAll-style bulk
152
- * operations and by admin repair). Loops in bounded steps until the
153
- * index fits the limit or a hard cap is reached.
154
- */
155
- enforceLimit(userId: string): Promise<number>;
156
- /** Sets the current security version for a user (invalidates older sessions). */
157
- setSecurityVersion(userId: string, version: number): Promise<void>;
158
- /** Reads the current security version for a user, or null when unset. */
159
- getSecurityVersion(userId: string): Promise<number | null>;
160
- /** Best-effort write of the JTI lookup index (cross-slot, self-healing). */
161
- writeJtiIndex(jti: string, userId: string, ttl: number): Promise<boolean>;
162
- /** Reads the JTI lookup index (only valid when the index is enabled). */
163
- readJtiIndex(jti: string): Promise<string | null>;
164
- /** Deletes one JTI index entry (idempotent, cross-slot). */
165
- deleteJtiIndex(jti: string): Promise<void>;
166
- /**
167
- * Deletes JTI index entries through bounded slot-grouped pipelines
168
- * (cross-slot fan-out lives here, not in the session layer).
169
- */
170
- deleteJtiIndexMany(jtis: string[]): Promise<void>;
171
- /** Returns the user id behind a jti via the index, or null. */
172
- resolveUserIdByJti(jti: string): Promise<string | null>;
173
- /** Server time in seconds (authoritative clock). */
174
- serverTime(): Promise<number>;
175
- /** Number of sessions currently in a user's index. */
176
- countByUser(userId: string): Promise<number>;
177
- /**
178
- * Lists the jtis of a user's sessions (oldest first), bounded to `max`.
179
- * Used by bulk operations (revokeAll, deleteByUser).
180
- */
181
- listJtis(userId: string, max: number): Promise<string[]>;
182
- }
183
- /** Validates and normalizes an externally provided record (defense in depth). */
184
- export declare function normalizeRecord(value: unknown): SessionRecord;