@strapi/core 5.49.0 → 5.50.1

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 (272) hide show
  1. package/dist/Strapi.d.ts.map +1 -1
  2. package/dist/Strapi.js +2 -0
  3. package/dist/Strapi.js.map +1 -1
  4. package/dist/Strapi.mjs +2 -0
  5. package/dist/Strapi.mjs.map +1 -1
  6. package/dist/configuration/config-loader.d.ts.map +1 -1
  7. package/dist/configuration/get-dirs.d.ts.map +1 -1
  8. package/dist/configuration/index.d.ts +0 -3
  9. package/dist/configuration/index.d.ts.map +1 -1
  10. package/dist/configuration/index.js +0 -3
  11. package/dist/configuration/index.js.map +1 -1
  12. package/dist/configuration/index.mjs +0 -3
  13. package/dist/configuration/index.mjs.map +1 -1
  14. package/dist/configuration/server-config.d.ts +11 -0
  15. package/dist/configuration/server-config.d.ts.map +1 -0
  16. package/dist/configuration/server-config.js +16 -0
  17. package/dist/configuration/server-config.js.map +1 -0
  18. package/dist/configuration/server-config.mjs +14 -0
  19. package/dist/configuration/server-config.mjs.map +1 -0
  20. package/dist/configuration/urls.d.ts.map +1 -1
  21. package/dist/core-api/controller/collection-type.d.ts.map +1 -1
  22. package/dist/core-api/controller/single-type.d.ts.map +1 -1
  23. package/dist/core-api/controller/transform.d.ts.map +1 -1
  24. package/dist/core-api/routes/index.d.ts.map +1 -1
  25. package/dist/core-api/routes/validation/attributes.d.ts.map +1 -1
  26. package/dist/core-api/routes/validation/component.js +3 -3
  27. package/dist/core-api/routes/validation/component.js.map +1 -1
  28. package/dist/core-api/routes/validation/component.mjs +3 -3
  29. package/dist/core-api/routes/validation/component.mjs.map +1 -1
  30. package/dist/core-api/routes/validation/mappers.d.ts.map +1 -1
  31. package/dist/core-api/routes/validation/utils.d.ts.map +1 -1
  32. package/dist/core-api/service/collection-type.d.ts.map +1 -1
  33. package/dist/core-api/service/pagination.d.ts.map +1 -1
  34. package/dist/core-api/service/single-type.d.ts.map +1 -1
  35. package/dist/domain/content-type/index.d.ts.map +1 -1
  36. package/dist/domain/content-type/validator.d.ts.map +1 -1
  37. package/dist/domain/module/index.d.ts.map +1 -1
  38. package/dist/domain/module/validation.d.ts.map +1 -1
  39. package/dist/ee/index.d.ts +2 -1
  40. package/dist/ee/index.d.ts.map +1 -1
  41. package/dist/ee/license.d.ts.map +1 -1
  42. package/dist/factories.d.ts.map +1 -1
  43. package/dist/index.d.ts +4 -1
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js.map +1 -1
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/loaders/plugins/get-enabled-plugins.d.ts.map +1 -1
  48. package/dist/loaders/sanitizers.d.ts.map +1 -1
  49. package/dist/loaders/src-index.d.ts.map +1 -1
  50. package/dist/loaders/validators.d.ts.map +1 -1
  51. package/dist/middlewares/body.d.ts.map +1 -1
  52. package/dist/middlewares/body.js +1 -1
  53. package/dist/middlewares/body.js.map +1 -1
  54. package/dist/middlewares/body.mjs +1 -1
  55. package/dist/middlewares/body.mjs.map +1 -1
  56. package/dist/middlewares/cors.d.ts.map +1 -1
  57. package/dist/middlewares/errors.d.ts +5 -0
  58. package/dist/middlewares/errors.d.ts.map +1 -1
  59. package/dist/middlewares/errors.js.map +1 -1
  60. package/dist/middlewares/errors.mjs.map +1 -1
  61. package/dist/middlewares/favicon.d.ts +0 -1
  62. package/dist/middlewares/favicon.d.ts.map +1 -1
  63. package/dist/migrations/draft-publish.d.ts.map +1 -1
  64. package/dist/migrations/first-published-at.d.ts.map +1 -1
  65. package/dist/migrations/i18n.d.ts.map +1 -1
  66. package/dist/migrations/index.d.ts.map +1 -1
  67. package/dist/package.json.js +17 -20
  68. package/dist/package.json.js.map +1 -1
  69. package/dist/package.json.mjs +17 -20
  70. package/dist/package.json.mjs.map +1 -1
  71. package/dist/providers/provider.d.ts.map +1 -1
  72. package/dist/registries/apis.d.ts.map +1 -1
  73. package/dist/registries/components.d.ts +1 -1
  74. package/dist/registries/components.d.ts.map +1 -1
  75. package/dist/registries/content-types.d.ts +2 -3
  76. package/dist/registries/content-types.d.ts.map +1 -1
  77. package/dist/registries/controllers.d.ts +3 -3
  78. package/dist/registries/controllers.d.ts.map +1 -1
  79. package/dist/registries/custom-fields.d.ts.map +1 -1
  80. package/dist/registries/hooks.d.ts +3 -4
  81. package/dist/registries/hooks.d.ts.map +1 -1
  82. package/dist/registries/middlewares.d.ts +2 -3
  83. package/dist/registries/middlewares.d.ts.map +1 -1
  84. package/dist/registries/models.d.ts +1 -1
  85. package/dist/registries/modules.d.ts.map +1 -1
  86. package/dist/registries/namespace.d.ts.map +1 -1
  87. package/dist/registries/plugins.d.ts.map +1 -1
  88. package/dist/registries/policies.d.ts +1 -2
  89. package/dist/registries/policies.d.ts.map +1 -1
  90. package/dist/registries/sanitizers.d.ts +2 -2
  91. package/dist/registries/services.d.ts +3 -3
  92. package/dist/registries/services.d.ts.map +1 -1
  93. package/dist/registries/validators.d.ts +2 -2
  94. package/dist/services/ai.d.ts.map +1 -1
  95. package/dist/services/config.d.ts.map +1 -1
  96. package/dist/services/content-api/index.d.ts +4 -4
  97. package/dist/services/content-api/index.d.ts.map +1 -1
  98. package/dist/services/content-api/permissions/engine.d.ts.map +1 -1
  99. package/dist/services/content-api/permissions/index.d.ts +2 -2
  100. package/dist/services/content-api/permissions/index.d.ts.map +1 -1
  101. package/dist/services/content-api/permissions/providers/action.d.ts +1 -1
  102. package/dist/services/content-api/permissions/providers/action.d.ts.map +1 -1
  103. package/dist/services/content-api/permissions/providers/condition.d.ts +1 -1
  104. package/dist/services/content-api/permissions/providers/condition.d.ts.map +1 -1
  105. package/dist/services/content-source-maps.d.ts.map +1 -1
  106. package/dist/services/core-store.d.ts.map +1 -1
  107. package/dist/services/core-store.js +1 -1
  108. package/dist/services/core-store.js.map +1 -1
  109. package/dist/services/core-store.mjs +1 -1
  110. package/dist/services/core-store.mjs.map +1 -1
  111. package/dist/services/cron.d.ts +5 -5
  112. package/dist/services/custom-fields.d.ts.map +1 -1
  113. package/dist/services/document-service/attributes/index.d.ts +0 -1
  114. package/dist/services/document-service/attributes/index.d.ts.map +1 -1
  115. package/dist/services/document-service/common.d.ts.map +1 -1
  116. package/dist/services/document-service/components.d.ts +2 -2
  117. package/dist/services/document-service/components.d.ts.map +1 -1
  118. package/dist/services/document-service/components.js +7 -7
  119. package/dist/services/document-service/components.js.map +1 -1
  120. package/dist/services/document-service/components.mjs +7 -7
  121. package/dist/services/document-service/components.mjs.map +1 -1
  122. package/dist/services/document-service/draft-and-publish.d.ts +0 -1
  123. package/dist/services/document-service/draft-and-publish.d.ts.map +1 -1
  124. package/dist/services/document-service/entries.d.ts.map +1 -1
  125. package/dist/services/document-service/events.d.ts.map +1 -1
  126. package/dist/services/document-service/first-published-at.d.ts.map +1 -1
  127. package/dist/services/document-service/index.d.ts.map +1 -1
  128. package/dist/services/document-service/internationalization.d.ts +0 -1
  129. package/dist/services/document-service/internationalization.d.ts.map +1 -1
  130. package/dist/services/document-service/middlewares/middleware-manager.d.ts.map +1 -1
  131. package/dist/services/document-service/params.d.ts +1 -1
  132. package/dist/services/document-service/params.d.ts.map +1 -1
  133. package/dist/services/document-service/publication-filter.d.ts +1 -1
  134. package/dist/services/document-service/publication-filter.d.ts.map +1 -1
  135. package/dist/services/document-service/repository.d.ts.map +1 -1
  136. package/dist/services/document-service/repository.js +12 -8
  137. package/dist/services/document-service/repository.js.map +1 -1
  138. package/dist/services/document-service/repository.mjs +12 -8
  139. package/dist/services/document-service/repository.mjs.map +1 -1
  140. package/dist/services/document-service/transform/data.d.ts.map +1 -1
  141. package/dist/services/document-service/transform/fields.d.ts.map +1 -1
  142. package/dist/services/document-service/transform/id-map.d.ts.map +1 -1
  143. package/dist/services/document-service/transform/id-map.js +7 -4
  144. package/dist/services/document-service/transform/id-map.js.map +1 -1
  145. package/dist/services/document-service/transform/id-map.mjs +7 -4
  146. package/dist/services/document-service/transform/id-map.mjs.map +1 -1
  147. package/dist/services/document-service/transform/id-transform.d.ts +0 -1
  148. package/dist/services/document-service/transform/id-transform.d.ts.map +1 -1
  149. package/dist/services/document-service/transform/populate.d.ts.map +1 -1
  150. package/dist/services/document-service/transform/query.d.ts +0 -1
  151. package/dist/services/document-service/transform/query.d.ts.map +1 -1
  152. package/dist/services/document-service/transform/relations/extract/data-ids.d.ts.map +1 -1
  153. package/dist/services/document-service/transform/relations/transform/data-ids.d.ts.map +1 -1
  154. package/dist/services/document-service/transform/relations/transform/default-locale.d.ts.map +1 -1
  155. package/dist/services/document-service/transform/relations/utils/data.d.ts.map +1 -1
  156. package/dist/services/document-service/transform/relations/utils/dp.d.ts +1 -1
  157. package/dist/services/document-service/transform/relations/utils/dp.d.ts.map +1 -1
  158. package/dist/services/document-service/transform/relations/utils/i18n.d.ts.map +1 -1
  159. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts +0 -1
  160. package/dist/services/document-service/transform/relations/utils/map-relation.d.ts.map +1 -1
  161. package/dist/services/document-service/transform/relations/utils/xto-one.d.ts.map +1 -1
  162. package/dist/services/document-service/utils/bidirectional-relations.d.ts.map +1 -1
  163. package/dist/services/document-service/utils/bidirectional-relations.js +7 -2
  164. package/dist/services/document-service/utils/bidirectional-relations.js.map +1 -1
  165. package/dist/services/document-service/utils/bidirectional-relations.mjs +7 -2
  166. package/dist/services/document-service/utils/bidirectional-relations.mjs.map +1 -1
  167. package/dist/services/document-service/utils/clean-component-join-table.d.ts.map +1 -1
  168. package/dist/services/document-service/utils/ordered-parallel.d.ts.map +1 -1
  169. package/dist/services/document-service/utils/populate.d.ts.map +1 -1
  170. package/dist/services/document-service/utils/self-referential-relations.d.ts +6 -1
  171. package/dist/services/document-service/utils/self-referential-relations.d.ts.map +1 -1
  172. package/dist/services/document-service/utils/self-referential-relations.js +120 -7
  173. package/dist/services/document-service/utils/self-referential-relations.js.map +1 -1
  174. package/dist/services/document-service/utils/self-referential-relations.mjs +120 -7
  175. package/dist/services/document-service/utils/self-referential-relations.mjs.map +1 -1
  176. package/dist/services/document-service/utils/unidirectional-relations.d.ts.map +1 -1
  177. package/dist/services/entity-service/index.d.ts.map +1 -1
  178. package/dist/services/entity-service/index.js +1 -1
  179. package/dist/services/entity-service/index.js.map +1 -1
  180. package/dist/services/entity-service/index.mjs +1 -1
  181. package/dist/services/entity-service/index.mjs.map +1 -1
  182. package/dist/services/entity-validator/validators.d.ts.map +1 -1
  183. package/dist/services/entity-validator/validators.js +4 -2
  184. package/dist/services/entity-validator/validators.js.map +1 -1
  185. package/dist/services/entity-validator/validators.mjs +4 -2
  186. package/dist/services/entity-validator/validators.mjs.map +1 -1
  187. package/dist/services/errors.d.ts.map +1 -1
  188. package/dist/services/features.d.ts.map +1 -1
  189. package/dist/services/fs.d.ts.map +1 -1
  190. package/dist/services/mcp/authentication.d.ts.map +1 -1
  191. package/dist/services/mcp/handlers/handlePost.d.ts.map +1 -1
  192. package/dist/services/mcp/index.d.ts.map +1 -1
  193. package/dist/services/mcp/internal/McpCapabilityRegistry.d.ts +2 -2
  194. package/dist/services/mcp/internal/McpServerFactory.d.ts.map +1 -1
  195. package/dist/services/mcp/internal/syncMcpSessionCapabilities.d.ts.map +1 -1
  196. package/dist/services/mcp/metrics/metrics.d.ts.map +1 -1
  197. package/dist/services/mcp/metrics/normalizeMcpCapability.d.ts.map +1 -1
  198. package/dist/services/mcp/metrics/wrapCapabilityHandlerForMetrics.d.ts.map +1 -1
  199. package/dist/services/mcp/middleware/oauthDiscoveryFallback.d.ts.map +1 -1
  200. package/dist/services/mcp/prompt-registry.d.ts.map +1 -1
  201. package/dist/services/mcp/resource-registry.d.ts.map +1 -1
  202. package/dist/services/mcp/routes.d.ts +1 -1
  203. package/dist/services/mcp/routes.d.ts.map +1 -1
  204. package/dist/services/mcp/tool-registry.d.ts.map +1 -1
  205. package/dist/services/mcp/utils/createSafeCapabilityRegistration.d.ts.map +1 -1
  206. package/dist/services/mcp/utils/safeHandlerWrapper.d.ts.map +1 -1
  207. package/dist/services/mcp/utils/sendJsonRpcError.d.ts +0 -1
  208. package/dist/services/mcp/utils/sendJsonRpcError.d.ts.map +1 -1
  209. package/dist/services/mcp/utils/withTimeout.d.ts.map +1 -1
  210. package/dist/services/metrics/admin-user-hash.d.ts.map +1 -1
  211. package/dist/services/metrics/index.d.ts.map +1 -1
  212. package/dist/services/metrics/is-truthy.d.ts.map +1 -1
  213. package/dist/services/metrics/middleware.d.ts.map +1 -1
  214. package/dist/services/metrics/rate-limiter.d.ts +2 -1
  215. package/dist/services/metrics/rate-limiter.d.ts.map +1 -1
  216. package/dist/services/metrics/sender.d.ts.map +1 -1
  217. package/dist/services/query-params.d.ts.map +1 -1
  218. package/dist/services/reloader.d.ts.map +1 -1
  219. package/dist/services/request-context.d.ts.map +1 -1
  220. package/dist/services/server/admin-api.d.ts +3 -5
  221. package/dist/services/server/admin-api.d.ts.map +1 -1
  222. package/dist/services/server/api.d.ts +3 -4
  223. package/dist/services/server/api.d.ts.map +1 -1
  224. package/dist/services/server/compose-endpoint.d.ts.map +1 -1
  225. package/dist/services/server/content-api.d.ts +3 -5
  226. package/dist/services/server/content-api.d.ts.map +1 -1
  227. package/dist/services/server/http-server.d.ts +0 -1
  228. package/dist/services/server/http-server.d.ts.map +1 -1
  229. package/dist/services/server/index.d.ts.map +1 -1
  230. package/dist/services/server/koa-methods.d.ts +107 -0
  231. package/dist/services/server/koa-methods.d.ts.map +1 -0
  232. package/dist/services/server/koa-methods.js +24 -0
  233. package/dist/services/server/koa-methods.js.map +1 -0
  234. package/dist/services/server/koa-methods.mjs +22 -0
  235. package/dist/services/server/koa-methods.mjs.map +1 -0
  236. package/dist/services/server/koa.d.ts +0 -9
  237. package/dist/services/server/koa.d.ts.map +1 -1
  238. package/dist/services/server/koa.js +6 -9
  239. package/dist/services/server/koa.js.map +1 -1
  240. package/dist/services/server/koa.mjs +7 -9
  241. package/dist/services/server/koa.mjs.map +1 -1
  242. package/dist/services/server/middleware.d.ts.map +1 -1
  243. package/dist/services/server/openapi.d.ts.map +1 -1
  244. package/dist/services/server/policy.d.ts.map +1 -1
  245. package/dist/services/server/register-middlewares.d.ts.map +1 -1
  246. package/dist/services/server/register-routes.d.ts.map +1 -1
  247. package/dist/services/server/routing.d.ts +0 -2
  248. package/dist/services/server/routing.d.ts.map +1 -1
  249. package/dist/services/session-manager.d.ts +20 -0
  250. package/dist/services/session-manager.d.ts.map +1 -1
  251. package/dist/services/session-manager.js +57 -0
  252. package/dist/services/session-manager.js.map +1 -1
  253. package/dist/services/session-manager.mjs +57 -0
  254. package/dist/services/session-manager.mjs.map +1 -1
  255. package/dist/services/webhook-store.d.ts.map +1 -1
  256. package/dist/utils/convert-custom-field-type.d.ts.map +1 -1
  257. package/dist/utils/cron.d.ts.map +1 -1
  258. package/dist/utils/fetch.d.ts.map +1 -1
  259. package/dist/utils/filepath-to-prop-path.d.ts.map +1 -1
  260. package/dist/utils/is-initialized.d.ts.map +1 -1
  261. package/dist/utils/load-config-file.d.ts.map +1 -1
  262. package/dist/utils/load-files.d.ts +1 -1
  263. package/dist/utils/load-files.d.ts.map +1 -1
  264. package/dist/utils/open-browser.d.ts +0 -1
  265. package/dist/utils/open-browser.d.ts.map +1 -1
  266. package/dist/utils/resolve-working-dirs.d.ts.map +1 -1
  267. package/dist/utils/signals.d.ts.map +1 -1
  268. package/dist/utils/startup-logger.d.ts.map +1 -1
  269. package/dist/utils/transform-content-types-to-models.d.ts +3 -3
  270. package/dist/utils/transform-content-types-to-models.d.ts.map +1 -1
  271. package/dist/utils/update-notifier/index.d.ts.map +1 -1
  272. package/package.json +17 -20
@@ -24,6 +24,21 @@ class DatabaseSessionProvider {
24
24
  });
25
25
  return result;
26
26
  }
27
+ async findByUser(criteria) {
28
+ const results = await this.db.query(this.contentType).findMany({
29
+ where: {
30
+ userId: criteria.userId,
31
+ origin: criteria.origin,
32
+ ...criteria.status ? {
33
+ status: criteria.status
34
+ } : {}
35
+ },
36
+ orderBy: {
37
+ createdAt: 'DESC'
38
+ }
39
+ });
40
+ return results;
41
+ }
27
42
  async updateBySessionId(sessionId, data) {
28
43
  await this.db.query(this.contentType).update({
29
44
  where: {
@@ -88,6 +103,18 @@ class OriginSessionManager {
88
103
  return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);
89
104
  }
90
105
  /**
106
+ * Lists the active sessions of a user for this origin. Rotated/expired records
107
+ * are excluded so each live login family yields a single entry.
108
+ */ async listSessions(userId) {
109
+ return this.sessionManager.listSessions(this.origin, userId);
110
+ }
111
+ /**
112
+ * Revokes a single session by id, but only if it belongs to the given user and origin.
113
+ * Returns true when a matching session was found and deleted.
114
+ */ async revokeSessionById(userId, sessionId) {
115
+ return this.sessionManager.revokeSessionById(this.origin, userId, sessionId);
116
+ }
117
+ /**
91
118
  * Returns true when a session exists and is not expired for this origin.
92
119
  * If the session exists but is expired, it will be deleted as part of this check.
93
120
  */ async isSessionActive(sessionId) {
@@ -186,6 +213,9 @@ class SessionManager {
186
213
  childId: null,
187
214
  type: tokenType,
188
215
  status: 'active',
216
+ ...options?.metadata ? {
217
+ metadata: options.metadata
218
+ } : {},
189
219
  expiresAt,
190
220
  absoluteExpiresAt
191
221
  });
@@ -314,6 +344,28 @@ class SessionManager {
314
344
  deviceId
315
345
  });
316
346
  }
347
+ async listSessions(origin, userId) {
348
+ if (!origin || typeof origin !== 'string') {
349
+ throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
350
+ }
351
+ return this.provider.findByUser({
352
+ userId,
353
+ origin,
354
+ status: 'active'
355
+ });
356
+ }
357
+ async revokeSessionById(origin, userId, sessionId) {
358
+ if (!origin || typeof origin !== 'string') {
359
+ throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
360
+ }
361
+ const session = await this.provider.findBySessionId(sessionId);
362
+ // Only allow revoking a session that belongs to the requesting user and origin.
363
+ if (session?.userId !== userId || session?.origin !== origin) {
364
+ return false;
365
+ }
366
+ await this.provider.deleteBySessionId(sessionId);
367
+ return true;
368
+ }
317
369
  async generateAccessToken(refreshToken, origin) {
318
370
  if (!origin || typeof origin !== 'string') {
319
371
  throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
@@ -432,6 +484,11 @@ class SessionManager {
432
484
  childId: null,
433
485
  type: tokenType,
434
486
  status: 'active',
487
+ // Preserve origin-defined metadata (e.g. deviceName, loginAt) across rotation so the
488
+ // active record always reflects the original session details.
489
+ ...current.metadata ? {
490
+ metadata: current.metadata
491
+ } : {},
435
492
  expiresAt: childExpiresAt,
436
493
  absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute)
437
494
  });
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sources":["../../src/services/session-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport type { VerifyOptions, Algorithm } from 'jsonwebtoken';\nimport type { Database } from '@strapi/database';\nimport { DEFAULT_ALGORITHM } from '../constants';\n\nexport interface SessionProvider {\n create(session: SessionData): Promise<SessionData>;\n findBySessionId(sessionId: string): Promise<SessionData | null>;\n updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void>;\n deleteBySessionId(sessionId: string): Promise<void>;\n deleteExpired(): Promise<void>;\n deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void>;\n}\n\nexport interface SessionData {\n id?: string;\n userId: string; // User ID stored as string (key-value store)\n sessionId: string;\n deviceId?: string; // Optional for origins that don't need device tracking\n origin: string;\n childId?: string | null;\n\n type?: 'refresh' | 'session';\n status?: 'active' | 'rotated' | 'revoked';\n expiresAt: Date;\n absoluteExpiresAt?: Date | null;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport interface RefreshTokenPayload {\n userId: string;\n sessionId: string;\n type: 'refresh';\n exp: number;\n iat: number;\n}\n\nexport interface AccessTokenPayload {\n userId: string;\n sessionId: string;\n type: 'access';\n exp: number;\n iat: number;\n}\n\nexport type TokenPayload = RefreshTokenPayload | AccessTokenPayload;\n\nexport interface ValidateRefreshTokenResult {\n isValid: boolean;\n userId?: string;\n sessionId?: string;\n error?:\n | 'invalid_token'\n | 'token_expired'\n | 'session_not_found'\n | 'session_expired'\n | 'wrong_token_type';\n}\n\nclass DatabaseSessionProvider implements SessionProvider {\n private db: Database;\n\n private contentType: string;\n\n constructor(db: Database, contentType: string) {\n this.db = db;\n this.contentType = contentType;\n }\n\n async create(session: SessionData): Promise<SessionData> {\n const result = await this.db.query(this.contentType).create({\n data: session,\n });\n return result as SessionData;\n }\n\n async findBySessionId(sessionId: string): Promise<SessionData | null> {\n const result = await this.db.query(this.contentType).findOne({\n where: { sessionId },\n });\n return result as SessionData | null;\n }\n\n async updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void> {\n await this.db.query(this.contentType).update({ where: { sessionId }, data });\n }\n\n async deleteBySessionId(sessionId: string): Promise<void> {\n await this.db.query(this.contentType).delete({\n where: { sessionId },\n });\n }\n\n async deleteExpired(): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: { absoluteExpiresAt: { $lt: new Date() } },\n });\n }\n\n async deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: {\n ...(criteria.userId ? { userId: criteria.userId } : {}),\n ...(criteria.origin ? { origin: criteria.origin } : {}),\n ...(criteria.deviceId ? { deviceId: criteria.deviceId } : {}),\n },\n });\n }\n}\n\nexport interface SessionManagerConfig {\n jwtSecret?: string;\n accessTokenLifespan: number;\n maxRefreshTokenLifespan: number;\n idleRefreshTokenLifespan: number;\n maxSessionLifespan: number;\n idleSessionLifespan: number;\n algorithm?: Algorithm;\n jwtOptions?: Record<string, unknown>;\n}\n\nclass OriginSessionManager {\n constructor(\n private sessionManager: SessionManager,\n private origin: string\n ) {}\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n options?: { type?: 'refresh' | 'session' }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n return this.sessionManager.generateRefreshToken(userId, deviceId, this.origin, options);\n }\n\n async generateAccessToken(refreshToken: string): Promise<{ token: string } | { error: string }> {\n return this.sessionManager.generateAccessToken(refreshToken, this.origin);\n }\n\n async rotateRefreshToken(refreshToken: string): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n return this.sessionManager.rotateRefreshToken(refreshToken, this.origin);\n }\n\n validateAccessToken(\n token: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n return this.sessionManager.validateAccessToken(token, this.origin);\n }\n\n async validateRefreshToken(token: string): Promise<ValidateRefreshTokenResult> {\n return this.sessionManager.validateRefreshToken(token, this.origin);\n }\n\n async invalidateRefreshToken(userId: string, deviceId?: string): Promise<void> {\n return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);\n }\n\n /**\n * Returns true when a session exists and is not expired for this origin.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string): Promise<boolean> {\n return this.sessionManager.isSessionActive(sessionId, this.origin);\n }\n}\n\nclass SessionManager {\n private provider: SessionProvider;\n\n // Store origin-specific configurations\n private originConfigs: Map<string, SessionManagerConfig> = new Map();\n\n // Run expired cleanup only every N calls to avoid extra queries\n private cleanupInvocationCounter: number = 0;\n\n private readonly cleanupEveryCalls: number = 50;\n\n constructor(provider: SessionProvider) {\n this.provider = provider;\n }\n\n /**\n * Define configuration for a specific origin\n */\n defineOrigin(origin: string, config: SessionManagerConfig): void {\n this.originConfigs.set(origin, config);\n }\n\n /**\n * Check if an origin is defined\n */\n hasOrigin(origin: string): boolean {\n return this.originConfigs.has(origin);\n }\n\n /**\n * Get configuration for a specific origin, throw error if not defined\n */\n private getConfigForOrigin(origin: string): SessionManagerConfig {\n const originConfig = this.originConfigs.get(origin);\n if (originConfig) {\n return originConfig;\n }\n throw new Error(\n `SessionManager: Origin '${origin}' is not defined. Please define it using defineOrigin('${origin}', config).`\n );\n }\n\n /**\n * Get the appropriate JWT key based on the algorithm\n */\n private getJwtKey(\n config: SessionManagerConfig,\n algorithm: Algorithm,\n operation: 'sign' | 'verify'\n ): string {\n const isAsymmetric =\n algorithm.startsWith('RS') || algorithm.startsWith('ES') || algorithm.startsWith('PS');\n\n if (isAsymmetric) {\n // For asymmetric algorithms, check if user has provided proper key configuration\n if (operation === 'sign') {\n const privateKey = config.jwtOptions?.privateKey as string;\n if (privateKey) {\n return privateKey;\n }\n throw new Error(\n `SessionManager: Private key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.privateKey.`\n );\n } else {\n const publicKey = config.jwtOptions?.publicKey as string;\n if (publicKey) {\n return publicKey;\n }\n throw new Error(\n `SessionManager: Public key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.publicKey.`\n );\n }\n } else {\n if (!config.jwtSecret) {\n throw new Error(\n `SessionManager: Secret key is required for symmetric algorithm ${algorithm}`\n );\n }\n return config.jwtSecret;\n }\n }\n\n generateSessionId(): string {\n return crypto.randomBytes(16).toString('hex');\n }\n\n private async maybeCleanupExpired(): Promise<void> {\n this.cleanupInvocationCounter += 1;\n if (this.cleanupInvocationCounter >= this.cleanupEveryCalls) {\n this.cleanupInvocationCounter = 0;\n\n await this.provider.deleteExpired();\n }\n }\n\n /**\n * Get the cleanup every calls threshold\n */\n get cleanupThreshold(): number {\n return this.cleanupEveryCalls;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n origin: string,\n options?: { type?: 'refresh' | 'session' }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n await this.maybeCleanupExpired();\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n const sessionId = this.generateSessionId();\n const tokenType = options?.type ?? 'refresh';\n const isRefresh = tokenType === 'refresh';\n\n const idleLifespan = isRefresh ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n const maxLifespan = isRefresh ? config.maxRefreshTokenLifespan : config.maxSessionLifespan;\n\n const now = Date.now();\n const expiresAt = new Date(now + idleLifespan * 1000);\n const absoluteExpiresAt = new Date(now + maxLifespan * 1000);\n\n // Create the root record first so createdAt can be used for signing.\n const record = await this.provider.create({\n userId,\n sessionId,\n ...(deviceId && { deviceId }),\n origin,\n childId: null,\n type: tokenType,\n status: 'active',\n expiresAt,\n absoluteExpiresAt,\n });\n\n const issuedAtSeconds = Math.floor(new Date(record.createdAt ?? new Date()).getTime() / 1000);\n const expiresAtSeconds = Math.floor(new Date(record.expiresAt).getTime() / 1000);\n\n const payload: RefreshTokenPayload = {\n userId,\n sessionId,\n type: 'refresh',\n iat: issuedAtSeconds,\n exp: expiresAtSeconds,\n };\n\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n return {\n token,\n sessionId,\n absoluteExpiresAt: absoluteExpiresAt.toISOString(),\n };\n }\n\n validateAccessToken(\n token: string,\n origin: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(token, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as TokenPayload;\n\n // Ensure this is an access token\n if (!payload || payload.type !== 'access') {\n return { isValid: false, payload: null };\n }\n\n return { isValid: true, payload };\n } catch (err) {\n return { isValid: false, payload: null };\n }\n }\n\n async validateRefreshToken(token: string, origin: string): Promise<ValidateRefreshTokenResult> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const verifyOptions: VerifyOptions = {\n algorithms: [algorithm],\n ...config.jwtOptions,\n };\n\n const payload = jwt.verify(token, jwtKey, verifyOptions) as RefreshTokenPayload;\n\n if (payload.type !== 'refresh') {\n return { isValid: false };\n }\n\n const session = await this.provider.findBySessionId(payload.sessionId);\n if (!session) {\n return { isValid: false };\n }\n\n const now = new Date();\n if (new Date(session.expiresAt) <= now) {\n return { isValid: false };\n }\n\n // Absolute family expiry check\n if (session.absoluteExpiresAt && new Date(session.absoluteExpiresAt) <= now) {\n return { isValid: false };\n }\n\n // Only 'active' sessions are eligible to create access tokens.\n if (session.status !== 'active') {\n return { isValid: false };\n }\n\n if (session.userId !== payload.userId) {\n return { isValid: false };\n }\n\n return {\n isValid: true,\n userId: payload.userId,\n sessionId: payload.sessionId,\n };\n } catch (error: any) {\n if (error instanceof jwt.JsonWebTokenError) {\n return { isValid: false };\n }\n\n throw error;\n }\n }\n\n async invalidateRefreshToken(origin: string, userId: string, deviceId?: string): Promise<void> {\n await this.provider.deleteBy({ userId, origin, deviceId });\n }\n\n async generateAccessToken(\n refreshToken: string,\n origin: string\n ): Promise<{ token: string } | { error: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const validation = await this.validateRefreshToken(refreshToken, origin);\n\n if (!validation.isValid) {\n return { error: 'invalid_refresh_token' };\n }\n\n const payload: Omit<AccessTokenPayload, 'iat' | 'exp'> = {\n userId: String(validation.userId!),\n sessionId: validation.sessionId!,\n type: 'access',\n };\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n expiresIn: config.accessTokenLifespan,\n ...jwtSignOptions,\n });\n\n return { token };\n }\n\n async rotateRefreshToken(\n refreshToken: string,\n origin: string\n ): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(refreshToken, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as RefreshTokenPayload;\n\n if (!payload || payload.type !== 'refresh') {\n return { error: 'invalid_refresh_token' };\n }\n\n const current = await this.provider.findBySessionId(payload.sessionId);\n if (!current) {\n return { error: 'invalid_refresh_token' };\n }\n\n // If parent already has a child, return the same child token\n if (current.childId) {\n const child = await this.provider.findBySessionId(current.childId);\n\n if (child) {\n const childIat = Math.floor(new Date(child.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(child.expiresAt).getTime() / 1000);\n\n const childPayload: RefreshTokenPayload = {\n userId: child.userId,\n sessionId: child.sessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(childPayload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n let absoluteExpiresAt;\n if (child.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof child.absoluteExpiresAt === 'string'\n ? child.absoluteExpiresAt\n : child.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(0).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: child.sessionId,\n absoluteExpiresAt,\n type: child.type ?? 'refresh',\n };\n }\n }\n\n const now = Date.now();\n const tokenType = current.type ?? 'refresh';\n const idleLifespan =\n tokenType === 'refresh' ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n // Enforce idle window since creation of the current token\n if (current.createdAt && now - new Date(current.createdAt).getTime() > idleLifespan * 1000) {\n return { error: 'idle_window_elapsed' };\n }\n\n // Enforce max family window using absoluteExpiresAt\n const absolute = current.absoluteExpiresAt\n ? new Date(current.absoluteExpiresAt).getTime()\n : now;\n if (absolute <= now) {\n return { error: 'max_window_elapsed' };\n }\n\n // Create child token\n const childSessionId = this.generateSessionId();\n const childExpiresAt = new Date(now + idleLifespan * 1000);\n\n const childRecord = await this.provider.create({\n userId: current.userId,\n sessionId: childSessionId,\n ...(current.deviceId && { deviceId: current.deviceId }),\n origin: current.origin,\n childId: null,\n type: tokenType,\n status: 'active',\n expiresAt: childExpiresAt,\n absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute),\n });\n\n const childIat = Math.floor(new Date(childRecord.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(childRecord.expiresAt).getTime() / 1000);\n const payloadOut: RefreshTokenPayload = {\n userId: current.userId,\n sessionId: childSessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(payloadOut, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n await this.provider.updateBySessionId(current.sessionId, {\n status: 'rotated',\n childId: childSessionId,\n });\n\n let absoluteExpiresAt;\n if (childRecord.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof childRecord.absoluteExpiresAt === 'string'\n ? childRecord.absoluteExpiresAt\n : childRecord.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(absolute).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: childSessionId,\n absoluteExpiresAt,\n type: tokenType,\n };\n } catch {\n return { error: 'invalid_refresh_token' };\n }\n }\n\n /**\n * Returns true when a session exists and is not expired.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string, origin: string): Promise<boolean> {\n const session = await this.provider.findBySessionId(sessionId);\n if (!session) {\n return false;\n }\n\n if (session.origin !== origin) {\n return false;\n }\n\n if (new Date(session.expiresAt) <= new Date()) {\n // Clean up expired session eagerly\n await this.provider.deleteBySessionId(sessionId);\n\n return false;\n }\n\n return true;\n }\n}\n\nconst createDatabaseProvider = (db: Database, contentType: string): SessionProvider => {\n return new DatabaseSessionProvider(db, contentType);\n};\n\nconst createSessionManager = ({\n db,\n}: {\n db: Database;\n}): SessionManager & ((origin: string) => OriginSessionManager) => {\n const provider = createDatabaseProvider(db, 'admin::session');\n const sessionManager = new SessionManager(provider);\n\n // Add callable functionality\n const fluentApi = (origin: string): OriginSessionManager => {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n return new OriginSessionManager(sessionManager, origin);\n };\n\n // Attach only the public SessionManagerService API to the callable\n const api = fluentApi as unknown as any;\n api.generateSessionId = sessionManager.generateSessionId.bind(sessionManager);\n api.defineOrigin = sessionManager.defineOrigin.bind(sessionManager);\n api.hasOrigin = sessionManager.hasOrigin.bind(sessionManager);\n // Note: isSessionActive is origin-scoped and exposed on OriginSessionManager only\n\n // Forward the cleanupThreshold getter (used in tests)\n Object.defineProperty(api, 'cleanupThreshold', {\n get() {\n return sessionManager.cleanupThreshold;\n },\n enumerable: true,\n });\n\n return api as SessionManager & ((origin: string) => OriginSessionManager);\n};\n\nexport { createSessionManager, createDatabaseProvider };\n"],"names":["DatabaseSessionProvider","create","session","result","db","query","contentType","data","findBySessionId","sessionId","findOne","where","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","criteria","userId","origin","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","isSessionActive","SessionManager","defineOrigin","config","originConfigs","set","hasOrigin","has","getConfigForOrigin","originConfig","get","Error","getJwtKey","algorithm","operation","isAsymmetric","startsWith","privateKey","jwtOptions","publicKey","jwtSecret","generateSessionId","crypto","randomBytes","toString","maybeCleanupExpired","cleanupInvocationCounter","cleanupEveryCalls","provider","cleanupThreshold","DEFAULT_ALGORITHM","jwtKey","tokenType","type","isRefresh","idleLifespan","idleRefreshTokenLifespan","idleSessionLifespan","maxLifespan","maxRefreshTokenLifespan","maxSessionLifespan","now","expiresAt","record","childId","status","issuedAtSeconds","Math","floor","createdAt","getTime","expiresAtSeconds","payload","iat","exp","expiresIn","jwtSignOptions","jwt","sign","noTimestamp","toISOString","verify","algorithms","isValid","err","verifyOptions","error","JsonWebTokenError","validation","String","accessTokenLifespan","current","child","childIat","childExp","childPayload","childToken","absolute","childSessionId","childExpiresAt","childRecord","payloadOut","Map","createDatabaseProvider","createSessionManager","fluentApi","api","bind","Object","defineProperty","enumerable"],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.js","sources":["../../src/services/session-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport type { VerifyOptions, Algorithm } from 'jsonwebtoken';\nimport type { Database } from '@strapi/database';\nimport { DEFAULT_ALGORITHM } from '../constants';\n\nexport interface SessionProvider {\n create(session: SessionData): Promise<SessionData>;\n findBySessionId(sessionId: string): Promise<SessionData | null>;\n findByUser(criteria: {\n userId: string;\n origin: string;\n status?: SessionData['status'];\n }): Promise<SessionData[]>;\n updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void>;\n deleteBySessionId(sessionId: string): Promise<void>;\n deleteExpired(): Promise<void>;\n deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void>;\n}\n\nexport interface SessionData {\n id?: string;\n userId: string; // User ID stored as string (key-value store)\n sessionId: string;\n deviceId?: string; // Optional for origins that don't need device tracking\n origin: string;\n childId?: string | null;\n\n type?: 'refresh' | 'session';\n status?: 'active' | 'rotated' | 'revoked';\n // Free-form, origin-defined metadata (e.g. deviceName, loginAt). The session manager only\n // persists and returns this verbatim; it never interprets its contents.\n metadata?: Record<string, unknown> | null;\n expiresAt: Date;\n absoluteExpiresAt?: Date | null;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport interface RefreshTokenPayload {\n userId: string;\n sessionId: string;\n type: 'refresh';\n exp: number;\n iat: number;\n}\n\nexport interface AccessTokenPayload {\n userId: string;\n sessionId: string;\n type: 'access';\n exp: number;\n iat: number;\n}\n\nexport type TokenPayload = RefreshTokenPayload | AccessTokenPayload;\n\nexport interface ValidateRefreshTokenResult {\n isValid: boolean;\n userId?: string;\n sessionId?: string;\n error?:\n | 'invalid_token'\n | 'token_expired'\n | 'session_not_found'\n | 'session_expired'\n | 'wrong_token_type';\n}\n\nclass DatabaseSessionProvider implements SessionProvider {\n private db: Database;\n\n private contentType: string;\n\n constructor(db: Database, contentType: string) {\n this.db = db;\n this.contentType = contentType;\n }\n\n async create(session: SessionData): Promise<SessionData> {\n const result = await this.db.query(this.contentType).create({\n data: session,\n });\n return result as SessionData;\n }\n\n async findBySessionId(sessionId: string): Promise<SessionData | null> {\n const result = await this.db.query(this.contentType).findOne({\n where: { sessionId },\n });\n return result as SessionData | null;\n }\n\n async findByUser(criteria: {\n userId: string;\n origin: string;\n status?: SessionData['status'];\n }): Promise<SessionData[]> {\n const results = await this.db.query(this.contentType).findMany({\n where: {\n userId: criteria.userId,\n origin: criteria.origin,\n ...(criteria.status ? { status: criteria.status } : {}),\n },\n orderBy: { createdAt: 'DESC' },\n });\n return results as SessionData[];\n }\n\n async updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void> {\n await this.db.query(this.contentType).update({ where: { sessionId }, data });\n }\n\n async deleteBySessionId(sessionId: string): Promise<void> {\n await this.db.query(this.contentType).delete({\n where: { sessionId },\n });\n }\n\n async deleteExpired(): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: { absoluteExpiresAt: { $lt: new Date() } },\n });\n }\n\n async deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: {\n ...(criteria.userId ? { userId: criteria.userId } : {}),\n ...(criteria.origin ? { origin: criteria.origin } : {}),\n ...(criteria.deviceId ? { deviceId: criteria.deviceId } : {}),\n },\n });\n }\n}\n\nexport interface SessionManagerConfig {\n jwtSecret?: string;\n accessTokenLifespan: number;\n maxRefreshTokenLifespan: number;\n idleRefreshTokenLifespan: number;\n maxSessionLifespan: number;\n idleSessionLifespan: number;\n algorithm?: Algorithm;\n jwtOptions?: Record<string, unknown>;\n}\n\nclass OriginSessionManager {\n private sessionManager: SessionManager;\n\n private origin: string;\n\n constructor(sessionManager: SessionManager, origin: string) {\n this.sessionManager = sessionManager;\n this.origin = origin;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n return this.sessionManager.generateRefreshToken(userId, deviceId, this.origin, options);\n }\n\n async generateAccessToken(refreshToken: string): Promise<{ token: string } | { error: string }> {\n return this.sessionManager.generateAccessToken(refreshToken, this.origin);\n }\n\n async rotateRefreshToken(refreshToken: string): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n return this.sessionManager.rotateRefreshToken(refreshToken, this.origin);\n }\n\n validateAccessToken(\n token: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n return this.sessionManager.validateAccessToken(token, this.origin);\n }\n\n async validateRefreshToken(token: string): Promise<ValidateRefreshTokenResult> {\n return this.sessionManager.validateRefreshToken(token, this.origin);\n }\n\n async invalidateRefreshToken(userId: string, deviceId?: string): Promise<void> {\n return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);\n }\n\n /**\n * Lists the active sessions of a user for this origin. Rotated/expired records\n * are excluded so each live login family yields a single entry.\n */\n async listSessions(userId: string): Promise<SessionData[]> {\n return this.sessionManager.listSessions(this.origin, userId);\n }\n\n /**\n * Revokes a single session by id, but only if it belongs to the given user and origin.\n * Returns true when a matching session was found and deleted.\n */\n async revokeSessionById(userId: string, sessionId: string): Promise<boolean> {\n return this.sessionManager.revokeSessionById(this.origin, userId, sessionId);\n }\n\n /**\n * Returns true when a session exists and is not expired for this origin.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string): Promise<boolean> {\n return this.sessionManager.isSessionActive(sessionId, this.origin);\n }\n}\n\nclass SessionManager {\n private provider: SessionProvider;\n\n // Store origin-specific configurations\n private originConfigs: Map<string, SessionManagerConfig> = new Map();\n\n // Run expired cleanup only every N calls to avoid extra queries\n private cleanupInvocationCounter: number = 0;\n\n private readonly cleanupEveryCalls: number = 50;\n\n constructor(provider: SessionProvider) {\n this.provider = provider;\n }\n\n /**\n * Define configuration for a specific origin\n */\n defineOrigin(origin: string, config: SessionManagerConfig): void {\n this.originConfigs.set(origin, config);\n }\n\n /**\n * Check if an origin is defined\n */\n hasOrigin(origin: string): boolean {\n return this.originConfigs.has(origin);\n }\n\n /**\n * Get configuration for a specific origin, throw error if not defined\n */\n private getConfigForOrigin(origin: string): SessionManagerConfig {\n const originConfig = this.originConfigs.get(origin);\n if (originConfig) {\n return originConfig;\n }\n throw new Error(\n `SessionManager: Origin '${origin}' is not defined. Please define it using defineOrigin('${origin}', config).`\n );\n }\n\n /**\n * Get the appropriate JWT key based on the algorithm\n */\n private getJwtKey(\n config: SessionManagerConfig,\n algorithm: Algorithm,\n operation: 'sign' | 'verify'\n ): string {\n const isAsymmetric =\n algorithm.startsWith('RS') || algorithm.startsWith('ES') || algorithm.startsWith('PS');\n\n if (isAsymmetric) {\n // For asymmetric algorithms, check if user has provided proper key configuration\n if (operation === 'sign') {\n const privateKey = config.jwtOptions?.privateKey as string;\n if (privateKey) {\n return privateKey;\n }\n throw new Error(\n `SessionManager: Private key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.privateKey.`\n );\n } else {\n const publicKey = config.jwtOptions?.publicKey as string;\n if (publicKey) {\n return publicKey;\n }\n throw new Error(\n `SessionManager: Public key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.publicKey.`\n );\n }\n } else {\n if (!config.jwtSecret) {\n throw new Error(\n `SessionManager: Secret key is required for symmetric algorithm ${algorithm}`\n );\n }\n return config.jwtSecret;\n }\n }\n\n generateSessionId(): string {\n return crypto.randomBytes(16).toString('hex');\n }\n\n private async maybeCleanupExpired(): Promise<void> {\n this.cleanupInvocationCounter += 1;\n if (this.cleanupInvocationCounter >= this.cleanupEveryCalls) {\n this.cleanupInvocationCounter = 0;\n\n await this.provider.deleteExpired();\n }\n }\n\n /**\n * Get the cleanup every calls threshold\n */\n get cleanupThreshold(): number {\n return this.cleanupEveryCalls;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n origin: string,\n options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n await this.maybeCleanupExpired();\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n const sessionId = this.generateSessionId();\n const tokenType = options?.type ?? 'refresh';\n const isRefresh = tokenType === 'refresh';\n\n const idleLifespan = isRefresh ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n const maxLifespan = isRefresh ? config.maxRefreshTokenLifespan : config.maxSessionLifespan;\n\n const now = Date.now();\n const expiresAt = new Date(now + idleLifespan * 1000);\n const absoluteExpiresAt = new Date(now + maxLifespan * 1000);\n\n // Create the root record first so createdAt can be used for signing.\n const record = await this.provider.create({\n userId,\n sessionId,\n ...(deviceId && { deviceId }),\n origin,\n childId: null,\n type: tokenType,\n status: 'active',\n ...(options?.metadata ? { metadata: options.metadata } : {}),\n expiresAt,\n absoluteExpiresAt,\n });\n\n const issuedAtSeconds = Math.floor(new Date(record.createdAt ?? new Date()).getTime() / 1000);\n const expiresAtSeconds = Math.floor(new Date(record.expiresAt).getTime() / 1000);\n\n const payload: RefreshTokenPayload = {\n userId,\n sessionId,\n type: 'refresh',\n iat: issuedAtSeconds,\n exp: expiresAtSeconds,\n };\n\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n return {\n token,\n sessionId,\n absoluteExpiresAt: absoluteExpiresAt.toISOString(),\n };\n }\n\n validateAccessToken(\n token: string,\n origin: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(token, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as TokenPayload;\n\n // Ensure this is an access token\n if (!payload || payload.type !== 'access') {\n return { isValid: false, payload: null };\n }\n\n return { isValid: true, payload };\n } catch (err) {\n return { isValid: false, payload: null };\n }\n }\n\n async validateRefreshToken(token: string, origin: string): Promise<ValidateRefreshTokenResult> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const verifyOptions: VerifyOptions = {\n algorithms: [algorithm],\n ...config.jwtOptions,\n };\n\n const payload = jwt.verify(token, jwtKey, verifyOptions) as RefreshTokenPayload;\n\n if (payload.type !== 'refresh') {\n return { isValid: false };\n }\n\n const session = await this.provider.findBySessionId(payload.sessionId);\n if (!session) {\n return { isValid: false };\n }\n\n const now = new Date();\n if (new Date(session.expiresAt) <= now) {\n return { isValid: false };\n }\n\n // Absolute family expiry check\n if (session.absoluteExpiresAt && new Date(session.absoluteExpiresAt) <= now) {\n return { isValid: false };\n }\n\n // Only 'active' sessions are eligible to create access tokens.\n if (session.status !== 'active') {\n return { isValid: false };\n }\n\n if (session.userId !== payload.userId) {\n return { isValid: false };\n }\n\n return {\n isValid: true,\n userId: payload.userId,\n sessionId: payload.sessionId,\n };\n } catch (error: any) {\n if (error instanceof jwt.JsonWebTokenError) {\n return { isValid: false };\n }\n\n throw error;\n }\n }\n\n async invalidateRefreshToken(origin: string, userId: string, deviceId?: string): Promise<void> {\n await this.provider.deleteBy({ userId, origin, deviceId });\n }\n\n async listSessions(origin: string, userId: string): Promise<SessionData[]> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n return this.provider.findByUser({ userId, origin, status: 'active' });\n }\n\n async revokeSessionById(origin: string, userId: string, sessionId: string): Promise<boolean> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const session = await this.provider.findBySessionId(sessionId);\n\n // Only allow revoking a session that belongs to the requesting user and origin.\n if (session?.userId !== userId || session?.origin !== origin) {\n return false;\n }\n\n await this.provider.deleteBySessionId(sessionId);\n return true;\n }\n\n async generateAccessToken(\n refreshToken: string,\n origin: string\n ): Promise<{ token: string } | { error: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const validation = await this.validateRefreshToken(refreshToken, origin);\n\n if (!validation.isValid) {\n return { error: 'invalid_refresh_token' };\n }\n\n const payload: Omit<AccessTokenPayload, 'iat' | 'exp'> = {\n userId: String(validation.userId!),\n sessionId: validation.sessionId!,\n type: 'access',\n };\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n expiresIn: config.accessTokenLifespan,\n ...jwtSignOptions,\n });\n\n return { token };\n }\n\n async rotateRefreshToken(\n refreshToken: string,\n origin: string\n ): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(refreshToken, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as RefreshTokenPayload;\n\n if (!payload || payload.type !== 'refresh') {\n return { error: 'invalid_refresh_token' };\n }\n\n const current = await this.provider.findBySessionId(payload.sessionId);\n if (!current) {\n return { error: 'invalid_refresh_token' };\n }\n\n // If parent already has a child, return the same child token\n if (current.childId) {\n const child = await this.provider.findBySessionId(current.childId);\n\n if (child) {\n const childIat = Math.floor(new Date(child.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(child.expiresAt).getTime() / 1000);\n\n const childPayload: RefreshTokenPayload = {\n userId: child.userId,\n sessionId: child.sessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(childPayload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n let absoluteExpiresAt;\n if (child.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof child.absoluteExpiresAt === 'string'\n ? child.absoluteExpiresAt\n : child.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(0).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: child.sessionId,\n absoluteExpiresAt,\n type: child.type ?? 'refresh',\n };\n }\n }\n\n const now = Date.now();\n const tokenType = current.type ?? 'refresh';\n const idleLifespan =\n tokenType === 'refresh' ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n // Enforce idle window since creation of the current token\n if (current.createdAt && now - new Date(current.createdAt).getTime() > idleLifespan * 1000) {\n return { error: 'idle_window_elapsed' };\n }\n\n // Enforce max family window using absoluteExpiresAt\n const absolute = current.absoluteExpiresAt\n ? new Date(current.absoluteExpiresAt).getTime()\n : now;\n if (absolute <= now) {\n return { error: 'max_window_elapsed' };\n }\n\n // Create child token\n const childSessionId = this.generateSessionId();\n const childExpiresAt = new Date(now + idleLifespan * 1000);\n\n const childRecord = await this.provider.create({\n userId: current.userId,\n sessionId: childSessionId,\n ...(current.deviceId && { deviceId: current.deviceId }),\n origin: current.origin,\n childId: null,\n type: tokenType,\n status: 'active',\n // Preserve origin-defined metadata (e.g. deviceName, loginAt) across rotation so the\n // active record always reflects the original session details.\n ...(current.metadata ? { metadata: current.metadata } : {}),\n expiresAt: childExpiresAt,\n absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute),\n });\n\n const childIat = Math.floor(new Date(childRecord.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(childRecord.expiresAt).getTime() / 1000);\n const payloadOut: RefreshTokenPayload = {\n userId: current.userId,\n sessionId: childSessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(payloadOut, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n await this.provider.updateBySessionId(current.sessionId, {\n status: 'rotated',\n childId: childSessionId,\n });\n\n let absoluteExpiresAt;\n if (childRecord.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof childRecord.absoluteExpiresAt === 'string'\n ? childRecord.absoluteExpiresAt\n : childRecord.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(absolute).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: childSessionId,\n absoluteExpiresAt,\n type: tokenType,\n };\n } catch {\n return { error: 'invalid_refresh_token' };\n }\n }\n\n /**\n * Returns true when a session exists and is not expired.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string, origin: string): Promise<boolean> {\n const session = await this.provider.findBySessionId(sessionId);\n if (!session) {\n return false;\n }\n\n if (session.origin !== origin) {\n return false;\n }\n\n if (new Date(session.expiresAt) <= new Date()) {\n // Clean up expired session eagerly\n await this.provider.deleteBySessionId(sessionId);\n\n return false;\n }\n\n return true;\n }\n}\n\nconst createDatabaseProvider = (db: Database, contentType: string): SessionProvider => {\n return new DatabaseSessionProvider(db, contentType);\n};\n\nconst createSessionManager = ({\n db,\n}: {\n db: Database;\n}): SessionManager & ((origin: string) => OriginSessionManager) => {\n const provider = createDatabaseProvider(db, 'admin::session');\n const sessionManager = new SessionManager(provider);\n\n // Add callable functionality\n const fluentApi = (origin: string): OriginSessionManager => {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n return new OriginSessionManager(sessionManager, origin);\n };\n\n // Attach only the public SessionManagerService API to the callable\n const api = fluentApi as unknown as any;\n api.generateSessionId = sessionManager.generateSessionId.bind(sessionManager);\n api.defineOrigin = sessionManager.defineOrigin.bind(sessionManager);\n api.hasOrigin = sessionManager.hasOrigin.bind(sessionManager);\n // Note: isSessionActive is origin-scoped and exposed on OriginSessionManager only\n\n // Forward the cleanupThreshold getter (used in tests)\n Object.defineProperty(api, 'cleanupThreshold', {\n get() {\n return sessionManager.cleanupThreshold;\n },\n enumerable: true,\n });\n\n return api as SessionManager & ((origin: string) => OriginSessionManager);\n};\n\nexport { createSessionManager, createDatabaseProvider };\n"],"names":["DatabaseSessionProvider","create","session","result","db","query","contentType","data","findBySessionId","sessionId","findOne","where","findByUser","criteria","results","findMany","userId","origin","status","orderBy","createdAt","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","listSessions","revokeSessionById","isSessionActive","SessionManager","defineOrigin","config","originConfigs","set","hasOrigin","has","getConfigForOrigin","originConfig","get","Error","getJwtKey","algorithm","operation","isAsymmetric","startsWith","privateKey","jwtOptions","publicKey","jwtSecret","generateSessionId","crypto","randomBytes","toString","maybeCleanupExpired","cleanupInvocationCounter","cleanupEveryCalls","provider","cleanupThreshold","DEFAULT_ALGORITHM","jwtKey","tokenType","type","isRefresh","idleLifespan","idleRefreshTokenLifespan","idleSessionLifespan","maxLifespan","maxRefreshTokenLifespan","maxSessionLifespan","now","expiresAt","record","childId","metadata","issuedAtSeconds","Math","floor","getTime","expiresAtSeconds","payload","iat","exp","expiresIn","jwtSignOptions","jwt","sign","noTimestamp","toISOString","verify","algorithms","isValid","err","verifyOptions","error","JsonWebTokenError","validation","String","accessTokenLifespan","current","child","childIat","childExp","childPayload","childToken","absolute","childSessionId","childExpiresAt","childRecord","payloadOut","Map","createDatabaseProvider","createSessionManager","fluentApi","api","bind","Object","defineProperty","enumerable"],"mappings":"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"}
@@ -17,6 +17,21 @@ class DatabaseSessionProvider {
17
17
  });
18
18
  return result;
19
19
  }
20
+ async findByUser(criteria) {
21
+ const results = await this.db.query(this.contentType).findMany({
22
+ where: {
23
+ userId: criteria.userId,
24
+ origin: criteria.origin,
25
+ ...criteria.status ? {
26
+ status: criteria.status
27
+ } : {}
28
+ },
29
+ orderBy: {
30
+ createdAt: 'DESC'
31
+ }
32
+ });
33
+ return results;
34
+ }
20
35
  async updateBySessionId(sessionId, data) {
21
36
  await this.db.query(this.contentType).update({
22
37
  where: {
@@ -81,6 +96,18 @@ class OriginSessionManager {
81
96
  return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);
82
97
  }
83
98
  /**
99
+ * Lists the active sessions of a user for this origin. Rotated/expired records
100
+ * are excluded so each live login family yields a single entry.
101
+ */ async listSessions(userId) {
102
+ return this.sessionManager.listSessions(this.origin, userId);
103
+ }
104
+ /**
105
+ * Revokes a single session by id, but only if it belongs to the given user and origin.
106
+ * Returns true when a matching session was found and deleted.
107
+ */ async revokeSessionById(userId, sessionId) {
108
+ return this.sessionManager.revokeSessionById(this.origin, userId, sessionId);
109
+ }
110
+ /**
84
111
  * Returns true when a session exists and is not expired for this origin.
85
112
  * If the session exists but is expired, it will be deleted as part of this check.
86
113
  */ async isSessionActive(sessionId) {
@@ -179,6 +206,9 @@ class SessionManager {
179
206
  childId: null,
180
207
  type: tokenType,
181
208
  status: 'active',
209
+ ...options?.metadata ? {
210
+ metadata: options.metadata
211
+ } : {},
182
212
  expiresAt,
183
213
  absoluteExpiresAt
184
214
  });
@@ -307,6 +337,28 @@ class SessionManager {
307
337
  deviceId
308
338
  });
309
339
  }
340
+ async listSessions(origin, userId) {
341
+ if (!origin || typeof origin !== 'string') {
342
+ throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
343
+ }
344
+ return this.provider.findByUser({
345
+ userId,
346
+ origin,
347
+ status: 'active'
348
+ });
349
+ }
350
+ async revokeSessionById(origin, userId, sessionId) {
351
+ if (!origin || typeof origin !== 'string') {
352
+ throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
353
+ }
354
+ const session = await this.provider.findBySessionId(sessionId);
355
+ // Only allow revoking a session that belongs to the requesting user and origin.
356
+ if (session?.userId !== userId || session?.origin !== origin) {
357
+ return false;
358
+ }
359
+ await this.provider.deleteBySessionId(sessionId);
360
+ return true;
361
+ }
310
362
  async generateAccessToken(refreshToken, origin) {
311
363
  if (!origin || typeof origin !== 'string') {
312
364
  throw new Error('SessionManager: Origin parameter is required and must be a non-empty string');
@@ -425,6 +477,11 @@ class SessionManager {
425
477
  childId: null,
426
478
  type: tokenType,
427
479
  status: 'active',
480
+ // Preserve origin-defined metadata (e.g. deviceName, loginAt) across rotation so the
481
+ // active record always reflects the original session details.
482
+ ...current.metadata ? {
483
+ metadata: current.metadata
484
+ } : {},
428
485
  expiresAt: childExpiresAt,
429
486
  absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute)
430
487
  });
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.mjs","sources":["../../src/services/session-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport type { VerifyOptions, Algorithm } from 'jsonwebtoken';\nimport type { Database } from '@strapi/database';\nimport { DEFAULT_ALGORITHM } from '../constants';\n\nexport interface SessionProvider {\n create(session: SessionData): Promise<SessionData>;\n findBySessionId(sessionId: string): Promise<SessionData | null>;\n updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void>;\n deleteBySessionId(sessionId: string): Promise<void>;\n deleteExpired(): Promise<void>;\n deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void>;\n}\n\nexport interface SessionData {\n id?: string;\n userId: string; // User ID stored as string (key-value store)\n sessionId: string;\n deviceId?: string; // Optional for origins that don't need device tracking\n origin: string;\n childId?: string | null;\n\n type?: 'refresh' | 'session';\n status?: 'active' | 'rotated' | 'revoked';\n expiresAt: Date;\n absoluteExpiresAt?: Date | null;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport interface RefreshTokenPayload {\n userId: string;\n sessionId: string;\n type: 'refresh';\n exp: number;\n iat: number;\n}\n\nexport interface AccessTokenPayload {\n userId: string;\n sessionId: string;\n type: 'access';\n exp: number;\n iat: number;\n}\n\nexport type TokenPayload = RefreshTokenPayload | AccessTokenPayload;\n\nexport interface ValidateRefreshTokenResult {\n isValid: boolean;\n userId?: string;\n sessionId?: string;\n error?:\n | 'invalid_token'\n | 'token_expired'\n | 'session_not_found'\n | 'session_expired'\n | 'wrong_token_type';\n}\n\nclass DatabaseSessionProvider implements SessionProvider {\n private db: Database;\n\n private contentType: string;\n\n constructor(db: Database, contentType: string) {\n this.db = db;\n this.contentType = contentType;\n }\n\n async create(session: SessionData): Promise<SessionData> {\n const result = await this.db.query(this.contentType).create({\n data: session,\n });\n return result as SessionData;\n }\n\n async findBySessionId(sessionId: string): Promise<SessionData | null> {\n const result = await this.db.query(this.contentType).findOne({\n where: { sessionId },\n });\n return result as SessionData | null;\n }\n\n async updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void> {\n await this.db.query(this.contentType).update({ where: { sessionId }, data });\n }\n\n async deleteBySessionId(sessionId: string): Promise<void> {\n await this.db.query(this.contentType).delete({\n where: { sessionId },\n });\n }\n\n async deleteExpired(): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: { absoluteExpiresAt: { $lt: new Date() } },\n });\n }\n\n async deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: {\n ...(criteria.userId ? { userId: criteria.userId } : {}),\n ...(criteria.origin ? { origin: criteria.origin } : {}),\n ...(criteria.deviceId ? { deviceId: criteria.deviceId } : {}),\n },\n });\n }\n}\n\nexport interface SessionManagerConfig {\n jwtSecret?: string;\n accessTokenLifespan: number;\n maxRefreshTokenLifespan: number;\n idleRefreshTokenLifespan: number;\n maxSessionLifespan: number;\n idleSessionLifespan: number;\n algorithm?: Algorithm;\n jwtOptions?: Record<string, unknown>;\n}\n\nclass OriginSessionManager {\n constructor(\n private sessionManager: SessionManager,\n private origin: string\n ) {}\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n options?: { type?: 'refresh' | 'session' }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n return this.sessionManager.generateRefreshToken(userId, deviceId, this.origin, options);\n }\n\n async generateAccessToken(refreshToken: string): Promise<{ token: string } | { error: string }> {\n return this.sessionManager.generateAccessToken(refreshToken, this.origin);\n }\n\n async rotateRefreshToken(refreshToken: string): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n return this.sessionManager.rotateRefreshToken(refreshToken, this.origin);\n }\n\n validateAccessToken(\n token: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n return this.sessionManager.validateAccessToken(token, this.origin);\n }\n\n async validateRefreshToken(token: string): Promise<ValidateRefreshTokenResult> {\n return this.sessionManager.validateRefreshToken(token, this.origin);\n }\n\n async invalidateRefreshToken(userId: string, deviceId?: string): Promise<void> {\n return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);\n }\n\n /**\n * Returns true when a session exists and is not expired for this origin.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string): Promise<boolean> {\n return this.sessionManager.isSessionActive(sessionId, this.origin);\n }\n}\n\nclass SessionManager {\n private provider: SessionProvider;\n\n // Store origin-specific configurations\n private originConfigs: Map<string, SessionManagerConfig> = new Map();\n\n // Run expired cleanup only every N calls to avoid extra queries\n private cleanupInvocationCounter: number = 0;\n\n private readonly cleanupEveryCalls: number = 50;\n\n constructor(provider: SessionProvider) {\n this.provider = provider;\n }\n\n /**\n * Define configuration for a specific origin\n */\n defineOrigin(origin: string, config: SessionManagerConfig): void {\n this.originConfigs.set(origin, config);\n }\n\n /**\n * Check if an origin is defined\n */\n hasOrigin(origin: string): boolean {\n return this.originConfigs.has(origin);\n }\n\n /**\n * Get configuration for a specific origin, throw error if not defined\n */\n private getConfigForOrigin(origin: string): SessionManagerConfig {\n const originConfig = this.originConfigs.get(origin);\n if (originConfig) {\n return originConfig;\n }\n throw new Error(\n `SessionManager: Origin '${origin}' is not defined. Please define it using defineOrigin('${origin}', config).`\n );\n }\n\n /**\n * Get the appropriate JWT key based on the algorithm\n */\n private getJwtKey(\n config: SessionManagerConfig,\n algorithm: Algorithm,\n operation: 'sign' | 'verify'\n ): string {\n const isAsymmetric =\n algorithm.startsWith('RS') || algorithm.startsWith('ES') || algorithm.startsWith('PS');\n\n if (isAsymmetric) {\n // For asymmetric algorithms, check if user has provided proper key configuration\n if (operation === 'sign') {\n const privateKey = config.jwtOptions?.privateKey as string;\n if (privateKey) {\n return privateKey;\n }\n throw new Error(\n `SessionManager: Private key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.privateKey.`\n );\n } else {\n const publicKey = config.jwtOptions?.publicKey as string;\n if (publicKey) {\n return publicKey;\n }\n throw new Error(\n `SessionManager: Public key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.publicKey.`\n );\n }\n } else {\n if (!config.jwtSecret) {\n throw new Error(\n `SessionManager: Secret key is required for symmetric algorithm ${algorithm}`\n );\n }\n return config.jwtSecret;\n }\n }\n\n generateSessionId(): string {\n return crypto.randomBytes(16).toString('hex');\n }\n\n private async maybeCleanupExpired(): Promise<void> {\n this.cleanupInvocationCounter += 1;\n if (this.cleanupInvocationCounter >= this.cleanupEveryCalls) {\n this.cleanupInvocationCounter = 0;\n\n await this.provider.deleteExpired();\n }\n }\n\n /**\n * Get the cleanup every calls threshold\n */\n get cleanupThreshold(): number {\n return this.cleanupEveryCalls;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n origin: string,\n options?: { type?: 'refresh' | 'session' }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n await this.maybeCleanupExpired();\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n const sessionId = this.generateSessionId();\n const tokenType = options?.type ?? 'refresh';\n const isRefresh = tokenType === 'refresh';\n\n const idleLifespan = isRefresh ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n const maxLifespan = isRefresh ? config.maxRefreshTokenLifespan : config.maxSessionLifespan;\n\n const now = Date.now();\n const expiresAt = new Date(now + idleLifespan * 1000);\n const absoluteExpiresAt = new Date(now + maxLifespan * 1000);\n\n // Create the root record first so createdAt can be used for signing.\n const record = await this.provider.create({\n userId,\n sessionId,\n ...(deviceId && { deviceId }),\n origin,\n childId: null,\n type: tokenType,\n status: 'active',\n expiresAt,\n absoluteExpiresAt,\n });\n\n const issuedAtSeconds = Math.floor(new Date(record.createdAt ?? new Date()).getTime() / 1000);\n const expiresAtSeconds = Math.floor(new Date(record.expiresAt).getTime() / 1000);\n\n const payload: RefreshTokenPayload = {\n userId,\n sessionId,\n type: 'refresh',\n iat: issuedAtSeconds,\n exp: expiresAtSeconds,\n };\n\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n return {\n token,\n sessionId,\n absoluteExpiresAt: absoluteExpiresAt.toISOString(),\n };\n }\n\n validateAccessToken(\n token: string,\n origin: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(token, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as TokenPayload;\n\n // Ensure this is an access token\n if (!payload || payload.type !== 'access') {\n return { isValid: false, payload: null };\n }\n\n return { isValid: true, payload };\n } catch (err) {\n return { isValid: false, payload: null };\n }\n }\n\n async validateRefreshToken(token: string, origin: string): Promise<ValidateRefreshTokenResult> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const verifyOptions: VerifyOptions = {\n algorithms: [algorithm],\n ...config.jwtOptions,\n };\n\n const payload = jwt.verify(token, jwtKey, verifyOptions) as RefreshTokenPayload;\n\n if (payload.type !== 'refresh') {\n return { isValid: false };\n }\n\n const session = await this.provider.findBySessionId(payload.sessionId);\n if (!session) {\n return { isValid: false };\n }\n\n const now = new Date();\n if (new Date(session.expiresAt) <= now) {\n return { isValid: false };\n }\n\n // Absolute family expiry check\n if (session.absoluteExpiresAt && new Date(session.absoluteExpiresAt) <= now) {\n return { isValid: false };\n }\n\n // Only 'active' sessions are eligible to create access tokens.\n if (session.status !== 'active') {\n return { isValid: false };\n }\n\n if (session.userId !== payload.userId) {\n return { isValid: false };\n }\n\n return {\n isValid: true,\n userId: payload.userId,\n sessionId: payload.sessionId,\n };\n } catch (error: any) {\n if (error instanceof jwt.JsonWebTokenError) {\n return { isValid: false };\n }\n\n throw error;\n }\n }\n\n async invalidateRefreshToken(origin: string, userId: string, deviceId?: string): Promise<void> {\n await this.provider.deleteBy({ userId, origin, deviceId });\n }\n\n async generateAccessToken(\n refreshToken: string,\n origin: string\n ): Promise<{ token: string } | { error: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const validation = await this.validateRefreshToken(refreshToken, origin);\n\n if (!validation.isValid) {\n return { error: 'invalid_refresh_token' };\n }\n\n const payload: Omit<AccessTokenPayload, 'iat' | 'exp'> = {\n userId: String(validation.userId!),\n sessionId: validation.sessionId!,\n type: 'access',\n };\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n expiresIn: config.accessTokenLifespan,\n ...jwtSignOptions,\n });\n\n return { token };\n }\n\n async rotateRefreshToken(\n refreshToken: string,\n origin: string\n ): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(refreshToken, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as RefreshTokenPayload;\n\n if (!payload || payload.type !== 'refresh') {\n return { error: 'invalid_refresh_token' };\n }\n\n const current = await this.provider.findBySessionId(payload.sessionId);\n if (!current) {\n return { error: 'invalid_refresh_token' };\n }\n\n // If parent already has a child, return the same child token\n if (current.childId) {\n const child = await this.provider.findBySessionId(current.childId);\n\n if (child) {\n const childIat = Math.floor(new Date(child.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(child.expiresAt).getTime() / 1000);\n\n const childPayload: RefreshTokenPayload = {\n userId: child.userId,\n sessionId: child.sessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(childPayload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n let absoluteExpiresAt;\n if (child.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof child.absoluteExpiresAt === 'string'\n ? child.absoluteExpiresAt\n : child.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(0).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: child.sessionId,\n absoluteExpiresAt,\n type: child.type ?? 'refresh',\n };\n }\n }\n\n const now = Date.now();\n const tokenType = current.type ?? 'refresh';\n const idleLifespan =\n tokenType === 'refresh' ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n // Enforce idle window since creation of the current token\n if (current.createdAt && now - new Date(current.createdAt).getTime() > idleLifespan * 1000) {\n return { error: 'idle_window_elapsed' };\n }\n\n // Enforce max family window using absoluteExpiresAt\n const absolute = current.absoluteExpiresAt\n ? new Date(current.absoluteExpiresAt).getTime()\n : now;\n if (absolute <= now) {\n return { error: 'max_window_elapsed' };\n }\n\n // Create child token\n const childSessionId = this.generateSessionId();\n const childExpiresAt = new Date(now + idleLifespan * 1000);\n\n const childRecord = await this.provider.create({\n userId: current.userId,\n sessionId: childSessionId,\n ...(current.deviceId && { deviceId: current.deviceId }),\n origin: current.origin,\n childId: null,\n type: tokenType,\n status: 'active',\n expiresAt: childExpiresAt,\n absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute),\n });\n\n const childIat = Math.floor(new Date(childRecord.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(childRecord.expiresAt).getTime() / 1000);\n const payloadOut: RefreshTokenPayload = {\n userId: current.userId,\n sessionId: childSessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(payloadOut, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n await this.provider.updateBySessionId(current.sessionId, {\n status: 'rotated',\n childId: childSessionId,\n });\n\n let absoluteExpiresAt;\n if (childRecord.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof childRecord.absoluteExpiresAt === 'string'\n ? childRecord.absoluteExpiresAt\n : childRecord.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(absolute).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: childSessionId,\n absoluteExpiresAt,\n type: tokenType,\n };\n } catch {\n return { error: 'invalid_refresh_token' };\n }\n }\n\n /**\n * Returns true when a session exists and is not expired.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string, origin: string): Promise<boolean> {\n const session = await this.provider.findBySessionId(sessionId);\n if (!session) {\n return false;\n }\n\n if (session.origin !== origin) {\n return false;\n }\n\n if (new Date(session.expiresAt) <= new Date()) {\n // Clean up expired session eagerly\n await this.provider.deleteBySessionId(sessionId);\n\n return false;\n }\n\n return true;\n }\n}\n\nconst createDatabaseProvider = (db: Database, contentType: string): SessionProvider => {\n return new DatabaseSessionProvider(db, contentType);\n};\n\nconst createSessionManager = ({\n db,\n}: {\n db: Database;\n}): SessionManager & ((origin: string) => OriginSessionManager) => {\n const provider = createDatabaseProvider(db, 'admin::session');\n const sessionManager = new SessionManager(provider);\n\n // Add callable functionality\n const fluentApi = (origin: string): OriginSessionManager => {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n return new OriginSessionManager(sessionManager, origin);\n };\n\n // Attach only the public SessionManagerService API to the callable\n const api = fluentApi as unknown as any;\n api.generateSessionId = sessionManager.generateSessionId.bind(sessionManager);\n api.defineOrigin = sessionManager.defineOrigin.bind(sessionManager);\n api.hasOrigin = sessionManager.hasOrigin.bind(sessionManager);\n // Note: isSessionActive is origin-scoped and exposed on OriginSessionManager only\n\n // Forward the cleanupThreshold getter (used in tests)\n Object.defineProperty(api, 'cleanupThreshold', {\n get() {\n return sessionManager.cleanupThreshold;\n },\n enumerable: true,\n });\n\n return api as SessionManager & ((origin: string) => OriginSessionManager);\n};\n\nexport { createSessionManager, createDatabaseProvider };\n"],"names":["DatabaseSessionProvider","create","session","result","db","query","contentType","data","findBySessionId","sessionId","findOne","where","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","criteria","userId","origin","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","isSessionActive","SessionManager","defineOrigin","config","originConfigs","set","hasOrigin","has","getConfigForOrigin","originConfig","get","Error","getJwtKey","algorithm","operation","isAsymmetric","startsWith","privateKey","jwtOptions","publicKey","jwtSecret","generateSessionId","crypto","randomBytes","toString","maybeCleanupExpired","cleanupInvocationCounter","cleanupEveryCalls","provider","cleanupThreshold","DEFAULT_ALGORITHM","jwtKey","tokenType","type","isRefresh","idleLifespan","idleRefreshTokenLifespan","idleSessionLifespan","maxLifespan","maxRefreshTokenLifespan","maxSessionLifespan","now","expiresAt","record","childId","status","issuedAtSeconds","Math","floor","createdAt","getTime","expiresAtSeconds","payload","iat","exp","expiresIn","jwtSignOptions","jwt","sign","noTimestamp","toISOString","verify","algorithms","isValid","err","verifyOptions","error","JsonWebTokenError","validation","String","accessTokenLifespan","current","child","childIat","childExp","childPayload","childToken","absolute","childSessionId","childExpiresAt","childRecord","payloadOut","Map","createDatabaseProvider","createSessionManager","fluentApi","api","bind","Object","defineProperty","enumerable"],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.mjs","sources":["../../src/services/session-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport type { VerifyOptions, Algorithm } from 'jsonwebtoken';\nimport type { Database } from '@strapi/database';\nimport { DEFAULT_ALGORITHM } from '../constants';\n\nexport interface SessionProvider {\n create(session: SessionData): Promise<SessionData>;\n findBySessionId(sessionId: string): Promise<SessionData | null>;\n findByUser(criteria: {\n userId: string;\n origin: string;\n status?: SessionData['status'];\n }): Promise<SessionData[]>;\n updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void>;\n deleteBySessionId(sessionId: string): Promise<void>;\n deleteExpired(): Promise<void>;\n deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void>;\n}\n\nexport interface SessionData {\n id?: string;\n userId: string; // User ID stored as string (key-value store)\n sessionId: string;\n deviceId?: string; // Optional for origins that don't need device tracking\n origin: string;\n childId?: string | null;\n\n type?: 'refresh' | 'session';\n status?: 'active' | 'rotated' | 'revoked';\n // Free-form, origin-defined metadata (e.g. deviceName, loginAt). The session manager only\n // persists and returns this verbatim; it never interprets its contents.\n metadata?: Record<string, unknown> | null;\n expiresAt: Date;\n absoluteExpiresAt?: Date | null;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport interface RefreshTokenPayload {\n userId: string;\n sessionId: string;\n type: 'refresh';\n exp: number;\n iat: number;\n}\n\nexport interface AccessTokenPayload {\n userId: string;\n sessionId: string;\n type: 'access';\n exp: number;\n iat: number;\n}\n\nexport type TokenPayload = RefreshTokenPayload | AccessTokenPayload;\n\nexport interface ValidateRefreshTokenResult {\n isValid: boolean;\n userId?: string;\n sessionId?: string;\n error?:\n | 'invalid_token'\n | 'token_expired'\n | 'session_not_found'\n | 'session_expired'\n | 'wrong_token_type';\n}\n\nclass DatabaseSessionProvider implements SessionProvider {\n private db: Database;\n\n private contentType: string;\n\n constructor(db: Database, contentType: string) {\n this.db = db;\n this.contentType = contentType;\n }\n\n async create(session: SessionData): Promise<SessionData> {\n const result = await this.db.query(this.contentType).create({\n data: session,\n });\n return result as SessionData;\n }\n\n async findBySessionId(sessionId: string): Promise<SessionData | null> {\n const result = await this.db.query(this.contentType).findOne({\n where: { sessionId },\n });\n return result as SessionData | null;\n }\n\n async findByUser(criteria: {\n userId: string;\n origin: string;\n status?: SessionData['status'];\n }): Promise<SessionData[]> {\n const results = await this.db.query(this.contentType).findMany({\n where: {\n userId: criteria.userId,\n origin: criteria.origin,\n ...(criteria.status ? { status: criteria.status } : {}),\n },\n orderBy: { createdAt: 'DESC' },\n });\n return results as SessionData[];\n }\n\n async updateBySessionId(sessionId: string, data: Partial<SessionData>): Promise<void> {\n await this.db.query(this.contentType).update({ where: { sessionId }, data });\n }\n\n async deleteBySessionId(sessionId: string): Promise<void> {\n await this.db.query(this.contentType).delete({\n where: { sessionId },\n });\n }\n\n async deleteExpired(): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: { absoluteExpiresAt: { $lt: new Date() } },\n });\n }\n\n async deleteBy(criteria: { userId?: string; origin?: string; deviceId?: string }): Promise<void> {\n await this.db.query(this.contentType).deleteMany({\n where: {\n ...(criteria.userId ? { userId: criteria.userId } : {}),\n ...(criteria.origin ? { origin: criteria.origin } : {}),\n ...(criteria.deviceId ? { deviceId: criteria.deviceId } : {}),\n },\n });\n }\n}\n\nexport interface SessionManagerConfig {\n jwtSecret?: string;\n accessTokenLifespan: number;\n maxRefreshTokenLifespan: number;\n idleRefreshTokenLifespan: number;\n maxSessionLifespan: number;\n idleSessionLifespan: number;\n algorithm?: Algorithm;\n jwtOptions?: Record<string, unknown>;\n}\n\nclass OriginSessionManager {\n private sessionManager: SessionManager;\n\n private origin: string;\n\n constructor(sessionManager: SessionManager, origin: string) {\n this.sessionManager = sessionManager;\n this.origin = origin;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n return this.sessionManager.generateRefreshToken(userId, deviceId, this.origin, options);\n }\n\n async generateAccessToken(refreshToken: string): Promise<{ token: string } | { error: string }> {\n return this.sessionManager.generateAccessToken(refreshToken, this.origin);\n }\n\n async rotateRefreshToken(refreshToken: string): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n return this.sessionManager.rotateRefreshToken(refreshToken, this.origin);\n }\n\n validateAccessToken(\n token: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n return this.sessionManager.validateAccessToken(token, this.origin);\n }\n\n async validateRefreshToken(token: string): Promise<ValidateRefreshTokenResult> {\n return this.sessionManager.validateRefreshToken(token, this.origin);\n }\n\n async invalidateRefreshToken(userId: string, deviceId?: string): Promise<void> {\n return this.sessionManager.invalidateRefreshToken(this.origin, userId, deviceId);\n }\n\n /**\n * Lists the active sessions of a user for this origin. Rotated/expired records\n * are excluded so each live login family yields a single entry.\n */\n async listSessions(userId: string): Promise<SessionData[]> {\n return this.sessionManager.listSessions(this.origin, userId);\n }\n\n /**\n * Revokes a single session by id, but only if it belongs to the given user and origin.\n * Returns true when a matching session was found and deleted.\n */\n async revokeSessionById(userId: string, sessionId: string): Promise<boolean> {\n return this.sessionManager.revokeSessionById(this.origin, userId, sessionId);\n }\n\n /**\n * Returns true when a session exists and is not expired for this origin.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string): Promise<boolean> {\n return this.sessionManager.isSessionActive(sessionId, this.origin);\n }\n}\n\nclass SessionManager {\n private provider: SessionProvider;\n\n // Store origin-specific configurations\n private originConfigs: Map<string, SessionManagerConfig> = new Map();\n\n // Run expired cleanup only every N calls to avoid extra queries\n private cleanupInvocationCounter: number = 0;\n\n private readonly cleanupEveryCalls: number = 50;\n\n constructor(provider: SessionProvider) {\n this.provider = provider;\n }\n\n /**\n * Define configuration for a specific origin\n */\n defineOrigin(origin: string, config: SessionManagerConfig): void {\n this.originConfigs.set(origin, config);\n }\n\n /**\n * Check if an origin is defined\n */\n hasOrigin(origin: string): boolean {\n return this.originConfigs.has(origin);\n }\n\n /**\n * Get configuration for a specific origin, throw error if not defined\n */\n private getConfigForOrigin(origin: string): SessionManagerConfig {\n const originConfig = this.originConfigs.get(origin);\n if (originConfig) {\n return originConfig;\n }\n throw new Error(\n `SessionManager: Origin '${origin}' is not defined. Please define it using defineOrigin('${origin}', config).`\n );\n }\n\n /**\n * Get the appropriate JWT key based on the algorithm\n */\n private getJwtKey(\n config: SessionManagerConfig,\n algorithm: Algorithm,\n operation: 'sign' | 'verify'\n ): string {\n const isAsymmetric =\n algorithm.startsWith('RS') || algorithm.startsWith('ES') || algorithm.startsWith('PS');\n\n if (isAsymmetric) {\n // For asymmetric algorithms, check if user has provided proper key configuration\n if (operation === 'sign') {\n const privateKey = config.jwtOptions?.privateKey as string;\n if (privateKey) {\n return privateKey;\n }\n throw new Error(\n `SessionManager: Private key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.privateKey.`\n );\n } else {\n const publicKey = config.jwtOptions?.publicKey as string;\n if (publicKey) {\n return publicKey;\n }\n throw new Error(\n `SessionManager: Public key is required for asymmetric algorithm ${algorithm}. Please configure admin.auth.options.publicKey.`\n );\n }\n } else {\n if (!config.jwtSecret) {\n throw new Error(\n `SessionManager: Secret key is required for symmetric algorithm ${algorithm}`\n );\n }\n return config.jwtSecret;\n }\n }\n\n generateSessionId(): string {\n return crypto.randomBytes(16).toString('hex');\n }\n\n private async maybeCleanupExpired(): Promise<void> {\n this.cleanupInvocationCounter += 1;\n if (this.cleanupInvocationCounter >= this.cleanupEveryCalls) {\n this.cleanupInvocationCounter = 0;\n\n await this.provider.deleteExpired();\n }\n }\n\n /**\n * Get the cleanup every calls threshold\n */\n get cleanupThreshold(): number {\n return this.cleanupEveryCalls;\n }\n\n async generateRefreshToken(\n userId: string,\n deviceId: string | undefined,\n origin: string,\n options?: { type?: 'refresh' | 'session'; metadata?: Record<string, unknown> }\n ): Promise<{ token: string; sessionId: string; absoluteExpiresAt: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n await this.maybeCleanupExpired();\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n const sessionId = this.generateSessionId();\n const tokenType = options?.type ?? 'refresh';\n const isRefresh = tokenType === 'refresh';\n\n const idleLifespan = isRefresh ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n const maxLifespan = isRefresh ? config.maxRefreshTokenLifespan : config.maxSessionLifespan;\n\n const now = Date.now();\n const expiresAt = new Date(now + idleLifespan * 1000);\n const absoluteExpiresAt = new Date(now + maxLifespan * 1000);\n\n // Create the root record first so createdAt can be used for signing.\n const record = await this.provider.create({\n userId,\n sessionId,\n ...(deviceId && { deviceId }),\n origin,\n childId: null,\n type: tokenType,\n status: 'active',\n ...(options?.metadata ? { metadata: options.metadata } : {}),\n expiresAt,\n absoluteExpiresAt,\n });\n\n const issuedAtSeconds = Math.floor(new Date(record.createdAt ?? new Date()).getTime() / 1000);\n const expiresAtSeconds = Math.floor(new Date(record.expiresAt).getTime() / 1000);\n\n const payload: RefreshTokenPayload = {\n userId,\n sessionId,\n type: 'refresh',\n iat: issuedAtSeconds,\n exp: expiresAtSeconds,\n };\n\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n return {\n token,\n sessionId,\n absoluteExpiresAt: absoluteExpiresAt.toISOString(),\n };\n }\n\n validateAccessToken(\n token: string,\n origin: string\n ): { isValid: true; payload: AccessTokenPayload } | { isValid: false; payload: null } {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(token, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as TokenPayload;\n\n // Ensure this is an access token\n if (!payload || payload.type !== 'access') {\n return { isValid: false, payload: null };\n }\n\n return { isValid: true, payload };\n } catch (err) {\n return { isValid: false, payload: null };\n }\n }\n\n async validateRefreshToken(token: string, origin: string): Promise<ValidateRefreshTokenResult> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const verifyOptions: VerifyOptions = {\n algorithms: [algorithm],\n ...config.jwtOptions,\n };\n\n const payload = jwt.verify(token, jwtKey, verifyOptions) as RefreshTokenPayload;\n\n if (payload.type !== 'refresh') {\n return { isValid: false };\n }\n\n const session = await this.provider.findBySessionId(payload.sessionId);\n if (!session) {\n return { isValid: false };\n }\n\n const now = new Date();\n if (new Date(session.expiresAt) <= now) {\n return { isValid: false };\n }\n\n // Absolute family expiry check\n if (session.absoluteExpiresAt && new Date(session.absoluteExpiresAt) <= now) {\n return { isValid: false };\n }\n\n // Only 'active' sessions are eligible to create access tokens.\n if (session.status !== 'active') {\n return { isValid: false };\n }\n\n if (session.userId !== payload.userId) {\n return { isValid: false };\n }\n\n return {\n isValid: true,\n userId: payload.userId,\n sessionId: payload.sessionId,\n };\n } catch (error: any) {\n if (error instanceof jwt.JsonWebTokenError) {\n return { isValid: false };\n }\n\n throw error;\n }\n }\n\n async invalidateRefreshToken(origin: string, userId: string, deviceId?: string): Promise<void> {\n await this.provider.deleteBy({ userId, origin, deviceId });\n }\n\n async listSessions(origin: string, userId: string): Promise<SessionData[]> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n return this.provider.findByUser({ userId, origin, status: 'active' });\n }\n\n async revokeSessionById(origin: string, userId: string, sessionId: string): Promise<boolean> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const session = await this.provider.findBySessionId(sessionId);\n\n // Only allow revoking a session that belongs to the requesting user and origin.\n if (session?.userId !== userId || session?.origin !== origin) {\n return false;\n }\n\n await this.provider.deleteBySessionId(sessionId);\n return true;\n }\n\n async generateAccessToken(\n refreshToken: string,\n origin: string\n ): Promise<{ token: string } | { error: string }> {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n const validation = await this.validateRefreshToken(refreshToken, origin);\n\n if (!validation.isValid) {\n return { error: 'invalid_refresh_token' };\n }\n\n const payload: Omit<AccessTokenPayload, 'iat' | 'exp'> = {\n userId: String(validation.userId!),\n sessionId: validation.sessionId!,\n type: 'access',\n };\n\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'sign');\n // Filter out conflicting options that are already handled by the payload or used for key selection\n const jwtOptions = config.jwtOptions || {};\n const { expiresIn, privateKey, publicKey, ...jwtSignOptions } = jwtOptions;\n\n const token = jwt.sign(payload, jwtKey, {\n algorithm,\n expiresIn: config.accessTokenLifespan,\n ...jwtSignOptions,\n });\n\n return { token };\n }\n\n async rotateRefreshToken(\n refreshToken: string,\n origin: string\n ): Promise<\n | {\n token: string;\n sessionId: string;\n absoluteExpiresAt: string;\n type: 'refresh' | 'session';\n }\n | { error: string }\n > {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n\n try {\n const config = this.getConfigForOrigin(origin);\n const algorithm = config.algorithm || DEFAULT_ALGORITHM;\n const jwtKey = this.getJwtKey(config, algorithm, 'verify');\n const payload = jwt.verify(refreshToken, jwtKey, {\n algorithms: [algorithm],\n ...config.jwtOptions,\n }) as RefreshTokenPayload;\n\n if (!payload || payload.type !== 'refresh') {\n return { error: 'invalid_refresh_token' };\n }\n\n const current = await this.provider.findBySessionId(payload.sessionId);\n if (!current) {\n return { error: 'invalid_refresh_token' };\n }\n\n // If parent already has a child, return the same child token\n if (current.childId) {\n const child = await this.provider.findBySessionId(current.childId);\n\n if (child) {\n const childIat = Math.floor(new Date(child.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(child.expiresAt).getTime() / 1000);\n\n const childPayload: RefreshTokenPayload = {\n userId: child.userId,\n sessionId: child.sessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(childPayload, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n let absoluteExpiresAt;\n if (child.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof child.absoluteExpiresAt === 'string'\n ? child.absoluteExpiresAt\n : child.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(0).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: child.sessionId,\n absoluteExpiresAt,\n type: child.type ?? 'refresh',\n };\n }\n }\n\n const now = Date.now();\n const tokenType = current.type ?? 'refresh';\n const idleLifespan =\n tokenType === 'refresh' ? config.idleRefreshTokenLifespan : config.idleSessionLifespan;\n\n // Enforce idle window since creation of the current token\n if (current.createdAt && now - new Date(current.createdAt).getTime() > idleLifespan * 1000) {\n return { error: 'idle_window_elapsed' };\n }\n\n // Enforce max family window using absoluteExpiresAt\n const absolute = current.absoluteExpiresAt\n ? new Date(current.absoluteExpiresAt).getTime()\n : now;\n if (absolute <= now) {\n return { error: 'max_window_elapsed' };\n }\n\n // Create child token\n const childSessionId = this.generateSessionId();\n const childExpiresAt = new Date(now + idleLifespan * 1000);\n\n const childRecord = await this.provider.create({\n userId: current.userId,\n sessionId: childSessionId,\n ...(current.deviceId && { deviceId: current.deviceId }),\n origin: current.origin,\n childId: null,\n type: tokenType,\n status: 'active',\n // Preserve origin-defined metadata (e.g. deviceName, loginAt) across rotation so the\n // active record always reflects the original session details.\n ...(current.metadata ? { metadata: current.metadata } : {}),\n expiresAt: childExpiresAt,\n absoluteExpiresAt: current.absoluteExpiresAt ?? new Date(absolute),\n });\n\n const childIat = Math.floor(new Date(childRecord.createdAt ?? new Date()).getTime() / 1000);\n const childExp = Math.floor(new Date(childRecord.expiresAt).getTime() / 1000);\n const payloadOut: RefreshTokenPayload = {\n userId: current.userId,\n sessionId: childSessionId,\n type: 'refresh',\n iat: childIat,\n exp: childExp,\n };\n // Filter out conflicting options that are already handled by the payload\n const { expiresIn, ...jwtSignOptions } = config.jwtOptions || {};\n\n const childToken = jwt.sign(payloadOut, jwtKey, {\n algorithm,\n noTimestamp: true,\n ...jwtSignOptions,\n });\n\n await this.provider.updateBySessionId(current.sessionId, {\n status: 'rotated',\n childId: childSessionId,\n });\n\n let absoluteExpiresAt;\n if (childRecord.absoluteExpiresAt) {\n absoluteExpiresAt =\n typeof childRecord.absoluteExpiresAt === 'string'\n ? childRecord.absoluteExpiresAt\n : childRecord.absoluteExpiresAt.toISOString();\n } else {\n absoluteExpiresAt = new Date(absolute).toISOString();\n }\n\n return {\n token: childToken,\n sessionId: childSessionId,\n absoluteExpiresAt,\n type: tokenType,\n };\n } catch {\n return { error: 'invalid_refresh_token' };\n }\n }\n\n /**\n * Returns true when a session exists and is not expired.\n * If the session exists but is expired, it will be deleted as part of this check.\n */\n async isSessionActive(sessionId: string, origin: string): Promise<boolean> {\n const session = await this.provider.findBySessionId(sessionId);\n if (!session) {\n return false;\n }\n\n if (session.origin !== origin) {\n return false;\n }\n\n if (new Date(session.expiresAt) <= new Date()) {\n // Clean up expired session eagerly\n await this.provider.deleteBySessionId(sessionId);\n\n return false;\n }\n\n return true;\n }\n}\n\nconst createDatabaseProvider = (db: Database, contentType: string): SessionProvider => {\n return new DatabaseSessionProvider(db, contentType);\n};\n\nconst createSessionManager = ({\n db,\n}: {\n db: Database;\n}): SessionManager & ((origin: string) => OriginSessionManager) => {\n const provider = createDatabaseProvider(db, 'admin::session');\n const sessionManager = new SessionManager(provider);\n\n // Add callable functionality\n const fluentApi = (origin: string): OriginSessionManager => {\n if (!origin || typeof origin !== 'string') {\n throw new Error(\n 'SessionManager: Origin parameter is required and must be a non-empty string'\n );\n }\n return new OriginSessionManager(sessionManager, origin);\n };\n\n // Attach only the public SessionManagerService API to the callable\n const api = fluentApi as unknown as any;\n api.generateSessionId = sessionManager.generateSessionId.bind(sessionManager);\n api.defineOrigin = sessionManager.defineOrigin.bind(sessionManager);\n api.hasOrigin = sessionManager.hasOrigin.bind(sessionManager);\n // Note: isSessionActive is origin-scoped and exposed on OriginSessionManager only\n\n // Forward the cleanupThreshold getter (used in tests)\n Object.defineProperty(api, 'cleanupThreshold', {\n get() {\n return sessionManager.cleanupThreshold;\n },\n enumerable: true,\n });\n\n return api as SessionManager & ((origin: string) => OriginSessionManager);\n};\n\nexport { createSessionManager, createDatabaseProvider };\n"],"names":["DatabaseSessionProvider","create","session","result","db","query","contentType","data","findBySessionId","sessionId","findOne","where","findByUser","criteria","results","findMany","userId","origin","status","orderBy","createdAt","updateBySessionId","update","deleteBySessionId","delete","deleteExpired","deleteMany","absoluteExpiresAt","$lt","Date","deleteBy","deviceId","OriginSessionManager","generateRefreshToken","options","sessionManager","generateAccessToken","refreshToken","rotateRefreshToken","validateAccessToken","token","validateRefreshToken","invalidateRefreshToken","listSessions","revokeSessionById","isSessionActive","SessionManager","defineOrigin","config","originConfigs","set","hasOrigin","has","getConfigForOrigin","originConfig","get","Error","getJwtKey","algorithm","operation","isAsymmetric","startsWith","privateKey","jwtOptions","publicKey","jwtSecret","generateSessionId","crypto","randomBytes","toString","maybeCleanupExpired","cleanupInvocationCounter","cleanupEveryCalls","provider","cleanupThreshold","DEFAULT_ALGORITHM","jwtKey","tokenType","type","isRefresh","idleLifespan","idleRefreshTokenLifespan","idleSessionLifespan","maxLifespan","maxRefreshTokenLifespan","maxSessionLifespan","now","expiresAt","record","childId","metadata","issuedAtSeconds","Math","floor","getTime","expiresAtSeconds","payload","iat","exp","expiresIn","jwtSignOptions","jwt","sign","noTimestamp","toISOString","verify","algorithms","isValid","err","verifyOptions","error","JsonWebTokenError","validation","String","accessTokenLifespan","current","child","childIat","childExp","childPayload","childToken","absolute","childSessionId","childExpiresAt","childRecord","payloadOut","Map","createDatabaseProvider","createSessionManager","fluentApi","api","bind","Object","defineProperty","enumerable"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-store.d.ts","sourceRoot":"","sources":["../../src/services/webhook-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,QAAA,MAAM,YAAY,EAAE,KAwBnB,CAAC;AAEF,KAAK,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;AAqC5C,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,iBAAiB,IAAI,MAAM,EAAE,CAAC;IAC9B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACjD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACjD,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAClE,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CACpD;AAED,QAAA,MAAM,kBAAkB,WAAY;IAAE,EAAE,EAAE,QAAQ,CAAA;CAAE,KAAG,YAwDtD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"webhook-store.d.ts","sourceRoot":"","sources":["../../src/services/webhook-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C,QAAA,MAAM,YAAY,EAAE,KAwBnB,CAAC;AAEF,KAAK,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;AAqC5C,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,iBAAiB,IAAI,MAAM,EAAE,CAAC;IAC9B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACjD,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACjD,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAClE,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CACpD;AAED,QAAA,MAAM,kBAAkB,GAAI,QAAQ;IAAE,EAAE,EAAE,QAAQ,CAAA;CAAE,KAAG,YAwDtD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC"}