@portaidentity/server 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (742) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +33 -0
  4. package/dist/applications/cache.d.ts +64 -0
  5. package/dist/applications/cache.d.ts.map +1 -0
  6. package/dist/applications/cache.js +161 -0
  7. package/dist/applications/cache.js.map +1 -0
  8. package/dist/applications/errors.d.ts +25 -0
  9. package/dist/applications/errors.d.ts.map +1 -0
  10. package/dist/applications/errors.js +31 -0
  11. package/dist/applications/errors.js.map +1 -0
  12. package/dist/applications/index.d.ts +17 -0
  13. package/dist/applications/index.d.ts.map +1 -0
  14. package/dist/applications/index.js +19 -0
  15. package/dist/applications/index.js.map +1 -0
  16. package/dist/applications/repository.d.ts +184 -0
  17. package/dist/applications/repository.d.ts.map +1 -0
  18. package/dist/applications/repository.js +367 -0
  19. package/dist/applications/repository.js.map +1 -0
  20. package/dist/applications/service.d.ts +160 -0
  21. package/dist/applications/service.d.ts.map +1 -0
  22. package/dist/applications/service.js +388 -0
  23. package/dist/applications/service.js.map +1 -0
  24. package/dist/applications/slugs.d.ts +61 -0
  25. package/dist/applications/slugs.d.ts.map +1 -0
  26. package/dist/applications/slugs.js +115 -0
  27. package/dist/applications/slugs.js.map +1 -0
  28. package/dist/applications/types.d.ts +129 -0
  29. package/dist/applications/types.d.ts.map +1 -0
  30. package/dist/applications/types.js +62 -0
  31. package/dist/applications/types.js.map +1 -0
  32. package/dist/auth/csrf.d.ts +71 -0
  33. package/dist/auth/csrf.d.ts.map +1 -0
  34. package/dist/auth/csrf.js +112 -0
  35. package/dist/auth/csrf.js.map +1 -0
  36. package/dist/auth/email-renderer.d.ts +37 -0
  37. package/dist/auth/email-renderer.d.ts.map +1 -0
  38. package/dist/auth/email-renderer.js +116 -0
  39. package/dist/auth/email-renderer.js.map +1 -0
  40. package/dist/auth/email-service.d.ts +154 -0
  41. package/dist/auth/email-service.d.ts.map +1 -0
  42. package/dist/auth/email-service.js +415 -0
  43. package/dist/auth/email-service.js.map +1 -0
  44. package/dist/auth/email-transport.d.ts +65 -0
  45. package/dist/auth/email-transport.d.ts.map +1 -0
  46. package/dist/auth/email-transport.js +82 -0
  47. package/dist/auth/email-transport.js.map +1 -0
  48. package/dist/auth/i18n.d.ts +81 -0
  49. package/dist/auth/i18n.d.ts.map +1 -0
  50. package/dist/auth/i18n.js +395 -0
  51. package/dist/auth/i18n.js.map +1 -0
  52. package/dist/auth/index.d.ts +28 -0
  53. package/dist/auth/index.d.ts.map +1 -0
  54. package/dist/auth/index.js +31 -0
  55. package/dist/auth/index.js.map +1 -0
  56. package/dist/auth/interaction-authority.d.ts +39 -0
  57. package/dist/auth/interaction-authority.d.ts.map +1 -0
  58. package/dist/auth/interaction-authority.js +30 -0
  59. package/dist/auth/interaction-authority.js.map +1 -0
  60. package/dist/auth/magic-link-session.d.ts +81 -0
  61. package/dist/auth/magic-link-session.d.ts.map +1 -0
  62. package/dist/auth/magic-link-session.js +183 -0
  63. package/dist/auth/magic-link-session.js.map +1 -0
  64. package/dist/auth/rate-limiter.d.ts +143 -0
  65. package/dist/auth/rate-limiter.d.ts.map +1 -0
  66. package/dist/auth/rate-limiter.js +220 -0
  67. package/dist/auth/rate-limiter.js.map +1 -0
  68. package/dist/auth/recovery-crypto.d.ts +34 -0
  69. package/dist/auth/recovery-crypto.d.ts.map +1 -0
  70. package/dist/auth/recovery-crypto.js +103 -0
  71. package/dist/auth/recovery-crypto.js.map +1 -0
  72. package/dist/auth/recovery-job-processor.d.ts +24 -0
  73. package/dist/auth/recovery-job-processor.d.ts.map +1 -0
  74. package/dist/auth/recovery-job-processor.js +123 -0
  75. package/dist/auth/recovery-job-processor.js.map +1 -0
  76. package/dist/auth/recovery-job-repository.d.ts +219 -0
  77. package/dist/auth/recovery-job-repository.d.ts.map +1 -0
  78. package/dist/auth/recovery-job-repository.js +340 -0
  79. package/dist/auth/recovery-job-repository.js.map +1 -0
  80. package/dist/auth/recovery-service.d.ts +27 -0
  81. package/dist/auth/recovery-service.d.ts.map +1 -0
  82. package/dist/auth/recovery-service.js +53 -0
  83. package/dist/auth/recovery-service.js.map +1 -0
  84. package/dist/auth/recovery-worker.d.ts +158 -0
  85. package/dist/auth/recovery-worker.d.ts.map +1 -0
  86. package/dist/auth/recovery-worker.js +306 -0
  87. package/dist/auth/recovery-worker.js.map +1 -0
  88. package/dist/auth/template-engine.d.ts +134 -0
  89. package/dist/auth/template-engine.d.ts.map +1 -0
  90. package/dist/auth/template-engine.js +225 -0
  91. package/dist/auth/template-engine.js.map +1 -0
  92. package/dist/auth/token-repository.d.ts +238 -0
  93. package/dist/auth/token-repository.d.ts.map +1 -0
  94. package/dist/auth/token-repository.js +475 -0
  95. package/dist/auth/token-repository.js.map +1 -0
  96. package/dist/auth/tokens.d.ts +45 -0
  97. package/dist/auth/tokens.d.ts.map +1 -0
  98. package/dist/auth/tokens.js +51 -0
  99. package/dist/auth/tokens.js.map +1 -0
  100. package/dist/cli/bootstrap.d.ts +55 -0
  101. package/dist/cli/bootstrap.d.ts.map +1 -0
  102. package/dist/cli/bootstrap.js +90 -0
  103. package/dist/cli/bootstrap.js.map +1 -0
  104. package/dist/cli/commands/health.d.ts +20 -0
  105. package/dist/cli/commands/health.d.ts.map +1 -0
  106. package/dist/cli/commands/health.js +80 -0
  107. package/dist/cli/commands/health.js.map +1 -0
  108. package/dist/cli/commands/init.d.ts +48 -0
  109. package/dist/cli/commands/init.d.ts.map +1 -0
  110. package/dist/cli/commands/init.js +349 -0
  111. package/dist/cli/commands/init.js.map +1 -0
  112. package/dist/cli/commands/migrate.d.ts +19 -0
  113. package/dist/cli/commands/migrate.d.ts.map +1 -0
  114. package/dist/cli/commands/migrate.js +88 -0
  115. package/dist/cli/commands/migrate.js.map +1 -0
  116. package/dist/cli/commands/seed.d.ts +19 -0
  117. package/dist/cli/commands/seed.d.ts.map +1 -0
  118. package/dist/cli/commands/seed.js +71 -0
  119. package/dist/cli/commands/seed.js.map +1 -0
  120. package/dist/cli/commands/user-2fa.d.ts +29 -0
  121. package/dist/cli/commands/user-2fa.d.ts.map +1 -0
  122. package/dist/cli/commands/user-2fa.js +113 -0
  123. package/dist/cli/commands/user-2fa.js.map +1 -0
  124. package/dist/cli/error-handler.d.ts +31 -0
  125. package/dist/cli/error-handler.d.ts.map +1 -0
  126. package/dist/cli/error-handler.js +65 -0
  127. package/dist/cli/error-handler.js.map +1 -0
  128. package/dist/cli/index.d.ts +48 -0
  129. package/dist/cli/index.d.ts.map +1 -0
  130. package/dist/cli/index.js +99 -0
  131. package/dist/cli/index.js.map +1 -0
  132. package/dist/cli/output.d.ts +94 -0
  133. package/dist/cli/output.d.ts.map +1 -0
  134. package/dist/cli/output.js +124 -0
  135. package/dist/cli/output.js.map +1 -0
  136. package/dist/cli/prompt.d.ts +48 -0
  137. package/dist/cli/prompt.d.ts.map +1 -0
  138. package/dist/cli/prompt.js +96 -0
  139. package/dist/cli/prompt.js.map +1 -0
  140. package/dist/clients/cache.d.ts +63 -0
  141. package/dist/clients/cache.d.ts.map +1 -0
  142. package/dist/clients/cache.js +160 -0
  143. package/dist/clients/cache.js.map +1 -0
  144. package/dist/clients/crypto.d.ts +69 -0
  145. package/dist/clients/crypto.d.ts.map +1 -0
  146. package/dist/clients/crypto.js +83 -0
  147. package/dist/clients/crypto.js.map +1 -0
  148. package/dist/clients/errors.d.ts +27 -0
  149. package/dist/clients/errors.d.ts.map +1 -0
  150. package/dist/clients/errors.js +33 -0
  151. package/dist/clients/errors.js.map +1 -0
  152. package/dist/clients/index.d.ts +19 -0
  153. package/dist/clients/index.d.ts.map +1 -0
  154. package/dist/clients/index.js +23 -0
  155. package/dist/clients/index.js.map +1 -0
  156. package/dist/clients/repository.d.ts +161 -0
  157. package/dist/clients/repository.d.ts.map +1 -0
  158. package/dist/clients/repository.js +318 -0
  159. package/dist/clients/repository.js.map +1 -0
  160. package/dist/clients/resolve-login-methods.d.ts +74 -0
  161. package/dist/clients/resolve-login-methods.d.ts.map +1 -0
  162. package/dist/clients/resolve-login-methods.js +68 -0
  163. package/dist/clients/resolve-login-methods.js.map +1 -0
  164. package/dist/clients/secret-repository.d.ts +109 -0
  165. package/dist/clients/secret-repository.d.ts.map +1 -0
  166. package/dist/clients/secret-repository.js +166 -0
  167. package/dist/clients/secret-repository.js.map +1 -0
  168. package/dist/clients/secret-service.d.ts +87 -0
  169. package/dist/clients/secret-service.d.ts.map +1 -0
  170. package/dist/clients/secret-service.js +204 -0
  171. package/dist/clients/secret-service.js.map +1 -0
  172. package/dist/clients/service.d.ts +158 -0
  173. package/dist/clients/service.d.ts.map +1 -0
  174. package/dist/clients/service.js +523 -0
  175. package/dist/clients/service.js.map +1 -0
  176. package/dist/clients/types.d.ts +214 -0
  177. package/dist/clients/types.d.ts.map +1 -0
  178. package/dist/clients/types.js +77 -0
  179. package/dist/clients/types.js.map +1 -0
  180. package/dist/clients/validators.d.ts +87 -0
  181. package/dist/clients/validators.d.ts.map +1 -0
  182. package/dist/clients/validators.js +164 -0
  183. package/dist/clients/validators.js.map +1 -0
  184. package/dist/config/index.d.ts +23 -0
  185. package/dist/config/index.d.ts.map +1 -0
  186. package/dist/config/index.js +52 -0
  187. package/dist/config/index.js.map +1 -0
  188. package/dist/config/schema.d.ts +35 -0
  189. package/dist/config/schema.d.ts.map +1 -0
  190. package/dist/config/schema.js +167 -0
  191. package/dist/config/schema.js.map +1 -0
  192. package/dist/custom-claims/cache.d.ts +48 -0
  193. package/dist/custom-claims/cache.d.ts.map +1 -0
  194. package/dist/custom-claims/cache.js +122 -0
  195. package/dist/custom-claims/cache.js.map +1 -0
  196. package/dist/custom-claims/errors.d.ts +25 -0
  197. package/dist/custom-claims/errors.d.ts.map +1 -0
  198. package/dist/custom-claims/errors.js +31 -0
  199. package/dist/custom-claims/errors.js.map +1 -0
  200. package/dist/custom-claims/index.d.ts +14 -0
  201. package/dist/custom-claims/index.d.ts.map +1 -0
  202. package/dist/custom-claims/index.js +17 -0
  203. package/dist/custom-claims/index.js.map +1 -0
  204. package/dist/custom-claims/repository.d.ts +147 -0
  205. package/dist/custom-claims/repository.d.ts.map +1 -0
  206. package/dist/custom-claims/repository.js +338 -0
  207. package/dist/custom-claims/repository.js.map +1 -0
  208. package/dist/custom-claims/service.d.ts +129 -0
  209. package/dist/custom-claims/service.d.ts.map +1 -0
  210. package/dist/custom-claims/service.js +296 -0
  211. package/dist/custom-claims/service.js.map +1 -0
  212. package/dist/custom-claims/types.d.ts +132 -0
  213. package/dist/custom-claims/types.d.ts.map +1 -0
  214. package/dist/custom-claims/types.js +61 -0
  215. package/dist/custom-claims/types.js.map +1 -0
  216. package/dist/custom-claims/validators.d.ts +61 -0
  217. package/dist/custom-claims/validators.d.ts.map +1 -0
  218. package/dist/custom-claims/validators.js +136 -0
  219. package/dist/custom-claims/validators.js.map +1 -0
  220. package/dist/index.d.ts +14 -0
  221. package/dist/index.d.ts.map +1 -0
  222. package/dist/index.js +91 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/lib/admin-permissions.d.ts +147 -0
  225. package/dist/lib/admin-permissions.d.ts.map +1 -0
  226. package/dist/lib/admin-permissions.js +261 -0
  227. package/dist/lib/admin-permissions.js.map +1 -0
  228. package/dist/lib/audit-log.d.ts +45 -0
  229. package/dist/lib/audit-log.d.ts.map +1 -0
  230. package/dist/lib/audit-log.js +79 -0
  231. package/dist/lib/audit-log.js.map +1 -0
  232. package/dist/lib/branding-assets.d.ts +47 -0
  233. package/dist/lib/branding-assets.d.ts.map +1 -0
  234. package/dist/lib/branding-assets.js +93 -0
  235. package/dist/lib/branding-assets.js.map +1 -0
  236. package/dist/lib/bulk-operations.d.ts +54 -0
  237. package/dist/lib/bulk-operations.d.ts.map +1 -0
  238. package/dist/lib/bulk-operations.js +201 -0
  239. package/dist/lib/bulk-operations.js.map +1 -0
  240. package/dist/lib/cursor.d.ts +110 -0
  241. package/dist/lib/cursor.d.ts.map +1 -0
  242. package/dist/lib/cursor.js +115 -0
  243. package/dist/lib/cursor.js.map +1 -0
  244. package/dist/lib/data-export.d.ts +67 -0
  245. package/dist/lib/data-export.d.ts.map +1 -0
  246. package/dist/lib/data-export.js +272 -0
  247. package/dist/lib/data-export.js.map +1 -0
  248. package/dist/lib/data-import-plan.d.ts +50 -0
  249. package/dist/lib/data-import-plan.d.ts.map +1 -0
  250. package/dist/lib/data-import-plan.js +235 -0
  251. package/dist/lib/data-import-plan.js.map +1 -0
  252. package/dist/lib/data-import.d.ts +276 -0
  253. package/dist/lib/data-import.d.ts.map +1 -0
  254. package/dist/lib/data-import.js +1694 -0
  255. package/dist/lib/data-import.js.map +1 -0
  256. package/dist/lib/database.d.ts +22 -0
  257. package/dist/lib/database.d.ts.map +1 -0
  258. package/dist/lib/database.js +103 -0
  259. package/dist/lib/database.js.map +1 -0
  260. package/dist/lib/entity-history.d.ts +52 -0
  261. package/dist/lib/entity-history.d.ts.map +1 -0
  262. package/dist/lib/entity-history.js +121 -0
  263. package/dist/lib/entity-history.js.map +1 -0
  264. package/dist/lib/etag.d.ts +92 -0
  265. package/dist/lib/etag.d.ts.map +1 -0
  266. package/dist/lib/etag.js +155 -0
  267. package/dist/lib/etag.js.map +1 -0
  268. package/dist/lib/image-validator.d.ts +44 -0
  269. package/dist/lib/image-validator.d.ts.map +1 -0
  270. package/dist/lib/image-validator.js +204 -0
  271. package/dist/lib/image-validator.js.map +1 -0
  272. package/dist/lib/logger.d.ts +15 -0
  273. package/dist/lib/logger.d.ts.map +1 -0
  274. package/dist/lib/logger.js +84 -0
  275. package/dist/lib/logger.js.map +1 -0
  276. package/dist/lib/migrator.d.ts +14 -0
  277. package/dist/lib/migrator.d.ts.map +1 -0
  278. package/dist/lib/migrator.js +34 -0
  279. package/dist/lib/migrator.js.map +1 -0
  280. package/dist/lib/redis.d.ts +5 -0
  281. package/dist/lib/redis.d.ts.map +1 -0
  282. package/dist/lib/redis.js +29 -0
  283. package/dist/lib/redis.js.map +1 -0
  284. package/dist/lib/runtime-paths.d.ts +38 -0
  285. package/dist/lib/runtime-paths.d.ts.map +1 -0
  286. package/dist/lib/runtime-paths.js +50 -0
  287. package/dist/lib/runtime-paths.js.map +1 -0
  288. package/dist/lib/session-tracking.d.ts +81 -0
  289. package/dist/lib/session-tracking.d.ts.map +1 -0
  290. package/dist/lib/session-tracking.js +145 -0
  291. package/dist/lib/session-tracking.js.map +1 -0
  292. package/dist/lib/signing-key-crypto.d.ts +53 -0
  293. package/dist/lib/signing-key-crypto.d.ts.map +1 -0
  294. package/dist/lib/signing-key-crypto.js +108 -0
  295. package/dist/lib/signing-key-crypto.js.map +1 -0
  296. package/dist/lib/signing-keys.d.ts +141 -0
  297. package/dist/lib/signing-keys.d.ts.map +1 -0
  298. package/dist/lib/signing-keys.js +206 -0
  299. package/dist/lib/signing-keys.js.map +1 -0
  300. package/dist/lib/stats.d.ts +83 -0
  301. package/dist/lib/stats.d.ts.map +1 -0
  302. package/dist/lib/stats.js +187 -0
  303. package/dist/lib/stats.js.map +1 -0
  304. package/dist/lib/super-admin-protection.d.ts +69 -0
  305. package/dist/lib/super-admin-protection.d.ts.map +1 -0
  306. package/dist/lib/super-admin-protection.js +102 -0
  307. package/dist/lib/super-admin-protection.js.map +1 -0
  308. package/dist/lib/system-config.d.ts +79 -0
  309. package/dist/lib/system-config.d.ts.map +1 -0
  310. package/dist/lib/system-config.js +159 -0
  311. package/dist/lib/system-config.js.map +1 -0
  312. package/dist/middleware/admin-auth.d.ts +100 -0
  313. package/dist/middleware/admin-auth.d.ts.map +1 -0
  314. package/dist/middleware/admin-auth.js +241 -0
  315. package/dist/middleware/admin-auth.js.map +1 -0
  316. package/dist/middleware/admin-cors.d.ts +41 -0
  317. package/dist/middleware/admin-cors.d.ts.map +1 -0
  318. package/dist/middleware/admin-cors.js +83 -0
  319. package/dist/middleware/admin-cors.js.map +1 -0
  320. package/dist/middleware/admin-mutation-audit.d.ts +9 -0
  321. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -0
  322. package/dist/middleware/admin-mutation-audit.js +76 -0
  323. package/dist/middleware/admin-mutation-audit.js.map +1 -0
  324. package/dist/middleware/admin-rate-limiter.d.ts +56 -0
  325. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -0
  326. package/dist/middleware/admin-rate-limiter.js +97 -0
  327. package/dist/middleware/admin-rate-limiter.js.map +1 -0
  328. package/dist/middleware/client-secret-hash.d.ts +34 -0
  329. package/dist/middleware/client-secret-hash.d.ts.map +1 -0
  330. package/dist/middleware/client-secret-hash.js +74 -0
  331. package/dist/middleware/client-secret-hash.js.map +1 -0
  332. package/dist/middleware/error-handler.d.ts +3 -0
  333. package/dist/middleware/error-handler.d.ts.map +1 -0
  334. package/dist/middleware/error-handler.js +93 -0
  335. package/dist/middleware/error-handler.js.map +1 -0
  336. package/dist/middleware/health.d.ts +3 -0
  337. package/dist/middleware/health.d.ts.map +1 -0
  338. package/dist/middleware/health.js +35 -0
  339. package/dist/middleware/health.js.map +1 -0
  340. package/dist/middleware/metrics.d.ts +40 -0
  341. package/dist/middleware/metrics.d.ts.map +1 -0
  342. package/dist/middleware/metrics.js +75 -0
  343. package/dist/middleware/metrics.js.map +1 -0
  344. package/dist/middleware/oidc-client-tenant.d.ts +37 -0
  345. package/dist/middleware/oidc-client-tenant.d.ts.map +1 -0
  346. package/dist/middleware/oidc-client-tenant.js +156 -0
  347. package/dist/middleware/oidc-client-tenant.js.map +1 -0
  348. package/dist/middleware/oidc-cors.d.ts +33 -0
  349. package/dist/middleware/oidc-cors.d.ts.map +1 -0
  350. package/dist/middleware/oidc-cors.js +68 -0
  351. package/dist/middleware/oidc-cors.js.map +1 -0
  352. package/dist/middleware/oidc-preflight-cors.d.ts +54 -0
  353. package/dist/middleware/oidc-preflight-cors.d.ts.map +1 -0
  354. package/dist/middleware/oidc-preflight-cors.js +267 -0
  355. package/dist/middleware/oidc-preflight-cors.js.map +1 -0
  356. package/dist/middleware/prompt-login-reset.d.ts +103 -0
  357. package/dist/middleware/prompt-login-reset.d.ts.map +1 -0
  358. package/dist/middleware/prompt-login-reset.js +204 -0
  359. package/dist/middleware/prompt-login-reset.js.map +1 -0
  360. package/dist/middleware/ready.d.ts +23 -0
  361. package/dist/middleware/ready.d.ts.map +1 -0
  362. package/dist/middleware/ready.js +60 -0
  363. package/dist/middleware/ready.js.map +1 -0
  364. package/dist/middleware/request-logger.d.ts +27 -0
  365. package/dist/middleware/request-logger.d.ts.map +1 -0
  366. package/dist/middleware/request-logger.js +46 -0
  367. package/dist/middleware/request-logger.js.map +1 -0
  368. package/dist/middleware/require-permission.d.ts +28 -0
  369. package/dist/middleware/require-permission.d.ts.map +1 -0
  370. package/dist/middleware/require-permission.js +63 -0
  371. package/dist/middleware/require-permission.js.map +1 -0
  372. package/dist/middleware/require-user-organization.d.ts +18 -0
  373. package/dist/middleware/require-user-organization.d.ts.map +1 -0
  374. package/dist/middleware/require-user-organization.js +53 -0
  375. package/dist/middleware/require-user-organization.js.map +1 -0
  376. package/dist/middleware/root-page.d.ts +62 -0
  377. package/dist/middleware/root-page.d.ts.map +1 -0
  378. package/dist/middleware/root-page.js +134 -0
  379. package/dist/middleware/root-page.js.map +1 -0
  380. package/dist/middleware/security-headers.d.ts +98 -0
  381. package/dist/middleware/security-headers.d.ts.map +1 -0
  382. package/dist/middleware/security-headers.js +159 -0
  383. package/dist/middleware/security-headers.js.map +1 -0
  384. package/dist/middleware/tenant-resolver.d.ts +37 -0
  385. package/dist/middleware/tenant-resolver.d.ts.map +1 -0
  386. package/dist/middleware/tenant-resolver.js +71 -0
  387. package/dist/middleware/tenant-resolver.js.map +1 -0
  388. package/dist/middleware/token-rate-limiter.d.ts +89 -0
  389. package/dist/middleware/token-rate-limiter.d.ts.map +1 -0
  390. package/dist/middleware/token-rate-limiter.js +189 -0
  391. package/dist/middleware/token-rate-limiter.js.map +1 -0
  392. package/dist/oidc/account-finder.d.ts +52 -0
  393. package/dist/oidc/account-finder.d.ts.map +1 -0
  394. package/dist/oidc/account-finder.js +134 -0
  395. package/dist/oidc/account-finder.js.map +1 -0
  396. package/dist/oidc/adapter-factory.d.ts +90 -0
  397. package/dist/oidc/adapter-factory.d.ts.map +1 -0
  398. package/dist/oidc/adapter-factory.js +165 -0
  399. package/dist/oidc/adapter-factory.js.map +1 -0
  400. package/dist/oidc/configuration.d.ts +155 -0
  401. package/dist/oidc/configuration.d.ts.map +1 -0
  402. package/dist/oidc/configuration.js +531 -0
  403. package/dist/oidc/configuration.js.map +1 -0
  404. package/dist/oidc/postgres-adapter.d.ts +159 -0
  405. package/dist/oidc/postgres-adapter.d.ts.map +1 -0
  406. package/dist/oidc/postgres-adapter.js +222 -0
  407. package/dist/oidc/postgres-adapter.js.map +1 -0
  408. package/dist/oidc/protocol-security-observer.d.ts +38 -0
  409. package/dist/oidc/protocol-security-observer.d.ts.map +1 -0
  410. package/dist/oidc/protocol-security-observer.js +93 -0
  411. package/dist/oidc/protocol-security-observer.js.map +1 -0
  412. package/dist/oidc/provider.d.ts +37 -0
  413. package/dist/oidc/provider.d.ts.map +1 -0
  414. package/dist/oidc/provider.js +71 -0
  415. package/dist/oidc/provider.js.map +1 -0
  416. package/dist/oidc/redis-adapter.d.ts +140 -0
  417. package/dist/oidc/redis-adapter.d.ts.map +1 -0
  418. package/dist/oidc/redis-adapter.js +344 -0
  419. package/dist/oidc/redis-adapter.js.map +1 -0
  420. package/dist/organizations/cache.d.ts +60 -0
  421. package/dist/organizations/cache.d.ts.map +1 -0
  422. package/dist/organizations/cache.js +157 -0
  423. package/dist/organizations/cache.js.map +1 -0
  424. package/dist/organizations/errors.d.ts +25 -0
  425. package/dist/organizations/errors.d.ts.map +1 -0
  426. package/dist/organizations/errors.js +31 -0
  427. package/dist/organizations/errors.js.map +1 -0
  428. package/dist/organizations/index.d.ts +15 -0
  429. package/dist/organizations/index.d.ts.map +1 -0
  430. package/dist/organizations/index.js +15 -0
  431. package/dist/organizations/index.js.map +1 -0
  432. package/dist/organizations/repository.d.ts +183 -0
  433. package/dist/organizations/repository.d.ts.map +1 -0
  434. package/dist/organizations/repository.js +354 -0
  435. package/dist/organizations/repository.js.map +1 -0
  436. package/dist/organizations/service.d.ts +168 -0
  437. package/dist/organizations/service.d.ts.map +1 -0
  438. package/dist/organizations/service.js +511 -0
  439. package/dist/organizations/service.js.map +1 -0
  440. package/dist/organizations/slugs.d.ts +57 -0
  441. package/dist/organizations/slugs.d.ts.map +1 -0
  442. package/dist/organizations/slugs.js +130 -0
  443. package/dist/organizations/slugs.js.map +1 -0
  444. package/dist/organizations/types.d.ts +146 -0
  445. package/dist/organizations/types.d.ts.map +1 -0
  446. package/dist/organizations/types.js +49 -0
  447. package/dist/organizations/types.js.map +1 -0
  448. package/dist/rbac/cache.d.ts +110 -0
  449. package/dist/rbac/cache.d.ts.map +1 -0
  450. package/dist/rbac/cache.js +271 -0
  451. package/dist/rbac/cache.js.map +1 -0
  452. package/dist/rbac/errors.d.ts +34 -0
  453. package/dist/rbac/errors.d.ts.map +1 -0
  454. package/dist/rbac/errors.js +43 -0
  455. package/dist/rbac/errors.js.map +1 -0
  456. package/dist/rbac/index.d.ts +17 -0
  457. package/dist/rbac/index.d.ts.map +1 -0
  458. package/dist/rbac/index.js +21 -0
  459. package/dist/rbac/index.js.map +1 -0
  460. package/dist/rbac/mapping-repository.d.ts +121 -0
  461. package/dist/rbac/mapping-repository.d.ts.map +1 -0
  462. package/dist/rbac/mapping-repository.js +224 -0
  463. package/dist/rbac/mapping-repository.js.map +1 -0
  464. package/dist/rbac/permission-repository.d.ts +100 -0
  465. package/dist/rbac/permission-repository.d.ts.map +1 -0
  466. package/dist/rbac/permission-repository.js +190 -0
  467. package/dist/rbac/permission-repository.js.map +1 -0
  468. package/dist/rbac/permission-service.d.ts +85 -0
  469. package/dist/rbac/permission-service.d.ts.map +1 -0
  470. package/dist/rbac/permission-service.js +179 -0
  471. package/dist/rbac/permission-service.js.map +1 -0
  472. package/dist/rbac/role-repository.d.ts +104 -0
  473. package/dist/rbac/role-repository.d.ts.map +1 -0
  474. package/dist/rbac/role-repository.js +202 -0
  475. package/dist/rbac/role-repository.js.map +1 -0
  476. package/dist/rbac/role-service.d.ts +111 -0
  477. package/dist/rbac/role-service.d.ts.map +1 -0
  478. package/dist/rbac/role-service.js +256 -0
  479. package/dist/rbac/role-service.js.map +1 -0
  480. package/dist/rbac/slugs.d.ts +116 -0
  481. package/dist/rbac/slugs.d.ts.map +1 -0
  482. package/dist/rbac/slugs.js +178 -0
  483. package/dist/rbac/slugs.js.map +1 -0
  484. package/dist/rbac/types.d.ts +187 -0
  485. package/dist/rbac/types.d.ts.map +1 -0
  486. package/dist/rbac/types.js +75 -0
  487. package/dist/rbac/types.js.map +1 -0
  488. package/dist/rbac/user-role-service.d.ts +101 -0
  489. package/dist/rbac/user-role-service.d.ts.map +1 -0
  490. package/dist/rbac/user-role-service.js +166 -0
  491. package/dist/rbac/user-role-service.js.map +1 -0
  492. package/dist/routes/applications.d.ts +40 -0
  493. package/dist/routes/applications.d.ts.map +1 -0
  494. package/dist/routes/applications.js +284 -0
  495. package/dist/routes/applications.js.map +1 -0
  496. package/dist/routes/audit.d.ts +31 -0
  497. package/dist/routes/audit.d.ts.map +1 -0
  498. package/dist/routes/audit.js +140 -0
  499. package/dist/routes/audit.js.map +1 -0
  500. package/dist/routes/branding.d.ts +17 -0
  501. package/dist/routes/branding.d.ts.map +1 -0
  502. package/dist/routes/branding.js +104 -0
  503. package/dist/routes/branding.js.map +1 -0
  504. package/dist/routes/bulk.d.ts +37 -0
  505. package/dist/routes/bulk.d.ts.map +1 -0
  506. package/dist/routes/bulk.js +94 -0
  507. package/dist/routes/bulk.js.map +1 -0
  508. package/dist/routes/clients.d.ts +44 -0
  509. package/dist/routes/clients.d.ts.map +1 -0
  510. package/dist/routes/clients.js +353 -0
  511. package/dist/routes/clients.js.map +1 -0
  512. package/dist/routes/config.d.ts +35 -0
  513. package/dist/routes/config.d.ts.map +1 -0
  514. package/dist/routes/config.js +115 -0
  515. package/dist/routes/config.js.map +1 -0
  516. package/dist/routes/custom-claims.d.ts +38 -0
  517. package/dist/routes/custom-claims.d.ts.map +1 -0
  518. package/dist/routes/custom-claims.js +208 -0
  519. package/dist/routes/custom-claims.js.map +1 -0
  520. package/dist/routes/exports.d.ts +21 -0
  521. package/dist/routes/exports.d.ts.map +1 -0
  522. package/dist/routes/exports.js +98 -0
  523. package/dist/routes/exports.js.map +1 -0
  524. package/dist/routes/imports.d.ts +18 -0
  525. package/dist/routes/imports.d.ts.map +1 -0
  526. package/dist/routes/imports.js +72 -0
  527. package/dist/routes/imports.js.map +1 -0
  528. package/dist/routes/interactions.d.ts +111 -0
  529. package/dist/routes/interactions.d.ts.map +1 -0
  530. package/dist/routes/interactions.js +1074 -0
  531. package/dist/routes/interactions.js.map +1 -0
  532. package/dist/routes/invitation.d.ts +31 -0
  533. package/dist/routes/invitation.d.ts.map +1 -0
  534. package/dist/routes/invitation.js +342 -0
  535. package/dist/routes/invitation.js.map +1 -0
  536. package/dist/routes/keys.d.ts +28 -0
  537. package/dist/routes/keys.d.ts.map +1 -0
  538. package/dist/routes/keys.js +91 -0
  539. package/dist/routes/keys.js.map +1 -0
  540. package/dist/routes/magic-link.d.ts +43 -0
  541. package/dist/routes/magic-link.d.ts.map +1 -0
  542. package/dist/routes/magic-link.js +264 -0
  543. package/dist/routes/magic-link.js.map +1 -0
  544. package/dist/routes/organizations.d.ts +38 -0
  545. package/dist/routes/organizations.d.ts.map +1 -0
  546. package/dist/routes/organizations.js +347 -0
  547. package/dist/routes/organizations.js.map +1 -0
  548. package/dist/routes/password-reset.d.ts +65 -0
  549. package/dist/routes/password-reset.d.ts.map +1 -0
  550. package/dist/routes/password-reset.js +493 -0
  551. package/dist/routes/password-reset.js.map +1 -0
  552. package/dist/routes/permissions.d.ts +33 -0
  553. package/dist/routes/permissions.d.ts.map +1 -0
  554. package/dist/routes/permissions.js +166 -0
  555. package/dist/routes/permissions.js.map +1 -0
  556. package/dist/routes/roles.d.ts +37 -0
  557. package/dist/routes/roles.d.ts.map +1 -0
  558. package/dist/routes/roles.js +222 -0
  559. package/dist/routes/roles.js.map +1 -0
  560. package/dist/routes/sessions.d.ts +37 -0
  561. package/dist/routes/sessions.d.ts.map +1 -0
  562. package/dist/routes/sessions.js +121 -0
  563. package/dist/routes/sessions.js.map +1 -0
  564. package/dist/routes/stats.d.ts +28 -0
  565. package/dist/routes/stats.d.ts.map +1 -0
  566. package/dist/routes/stats.js +65 -0
  567. package/dist/routes/stats.js.map +1 -0
  568. package/dist/routes/two-factor-admin.d.ts +54 -0
  569. package/dist/routes/two-factor-admin.d.ts.map +1 -0
  570. package/dist/routes/two-factor-admin.js +344 -0
  571. package/dist/routes/two-factor-admin.js.map +1 -0
  572. package/dist/routes/two-factor.d.ts +31 -0
  573. package/dist/routes/two-factor.d.ts.map +1 -0
  574. package/dist/routes/two-factor.js +595 -0
  575. package/dist/routes/two-factor.js.map +1 -0
  576. package/dist/routes/user-roles.d.ts +33 -0
  577. package/dist/routes/user-roles.d.ts.map +1 -0
  578. package/dist/routes/user-roles.js +129 -0
  579. package/dist/routes/user-roles.js.map +1 -0
  580. package/dist/routes/users.d.ts +61 -0
  581. package/dist/routes/users.d.ts.map +1 -0
  582. package/dist/routes/users.js +868 -0
  583. package/dist/routes/users.js.map +1 -0
  584. package/dist/security/decision-context.d.ts +52 -0
  585. package/dist/security/decision-context.d.ts.map +1 -0
  586. package/dist/security/decision-context.js +150 -0
  587. package/dist/security/decision-context.js.map +1 -0
  588. package/dist/security/decision-event.d.ts +128 -0
  589. package/dist/security/decision-event.d.ts.map +1 -0
  590. package/dist/security/decision-event.js +225 -0
  591. package/dist/security/decision-event.js.map +1 -0
  592. package/dist/security/transport-decision.d.ts +6 -0
  593. package/dist/security/transport-decision.d.ts.map +1 -0
  594. package/dist/security/transport-decision.js +37 -0
  595. package/dist/security/transport-decision.js.map +1 -0
  596. package/dist/server.d.ts +50 -0
  597. package/dist/server.d.ts.map +1 -0
  598. package/dist/server.js +491 -0
  599. package/dist/server.js.map +1 -0
  600. package/dist/two-factor/cache.d.ts +47 -0
  601. package/dist/two-factor/cache.d.ts.map +1 -0
  602. package/dist/two-factor/cache.js +122 -0
  603. package/dist/two-factor/cache.js.map +1 -0
  604. package/dist/two-factor/crypto.d.ts +41 -0
  605. package/dist/two-factor/crypto.d.ts.map +1 -0
  606. package/dist/two-factor/crypto.js +94 -0
  607. package/dist/two-factor/crypto.js.map +1 -0
  608. package/dist/two-factor/errors.d.ts +82 -0
  609. package/dist/two-factor/errors.d.ts.map +1 -0
  610. package/dist/two-factor/errors.js +112 -0
  611. package/dist/two-factor/errors.js.map +1 -0
  612. package/dist/two-factor/index.d.ts +18 -0
  613. package/dist/two-factor/index.d.ts.map +1 -0
  614. package/dist/two-factor/index.js +25 -0
  615. package/dist/two-factor/index.js.map +1 -0
  616. package/dist/two-factor/otp.d.ts +43 -0
  617. package/dist/two-factor/otp.d.ts.map +1 -0
  618. package/dist/two-factor/otp.js +57 -0
  619. package/dist/two-factor/otp.js.map +1 -0
  620. package/dist/two-factor/recovery.d.ts +45 -0
  621. package/dist/two-factor/recovery.d.ts.map +1 -0
  622. package/dist/two-factor/recovery.js +104 -0
  623. package/dist/two-factor/recovery.js.map +1 -0
  624. package/dist/two-factor/repository.d.ts +156 -0
  625. package/dist/two-factor/repository.d.ts.map +1 -0
  626. package/dist/two-factor/repository.js +251 -0
  627. package/dist/two-factor/repository.js.map +1 -0
  628. package/dist/two-factor/service.d.ts +232 -0
  629. package/dist/two-factor/service.d.ts.map +1 -0
  630. package/dist/two-factor/service.js +599 -0
  631. package/dist/two-factor/service.js.map +1 -0
  632. package/dist/two-factor/totp.d.ts +57 -0
  633. package/dist/two-factor/totp.d.ts.map +1 -0
  634. package/dist/two-factor/totp.js +96 -0
  635. package/dist/two-factor/totp.js.map +1 -0
  636. package/dist/two-factor/types.d.ts +152 -0
  637. package/dist/two-factor/types.d.ts.map +1 -0
  638. package/dist/two-factor/types.js +64 -0
  639. package/dist/two-factor/types.js.map +1 -0
  640. package/dist/users/cache.d.ts +49 -0
  641. package/dist/users/cache.d.ts.map +1 -0
  642. package/dist/users/cache.js +140 -0
  643. package/dist/users/cache.js.map +1 -0
  644. package/dist/users/claims.d.ts +67 -0
  645. package/dist/users/claims.d.ts.map +1 -0
  646. package/dist/users/claims.js +104 -0
  647. package/dist/users/claims.js.map +1 -0
  648. package/dist/users/errors.d.ts +25 -0
  649. package/dist/users/errors.d.ts.map +1 -0
  650. package/dist/users/errors.js +31 -0
  651. package/dist/users/errors.js.map +1 -0
  652. package/dist/users/gdpr.d.ts +110 -0
  653. package/dist/users/gdpr.d.ts.map +1 -0
  654. package/dist/users/gdpr.js +211 -0
  655. package/dist/users/gdpr.js.map +1 -0
  656. package/dist/users/index.d.ts +20 -0
  657. package/dist/users/index.d.ts.map +1 -0
  658. package/dist/users/index.js +19 -0
  659. package/dist/users/index.js.map +1 -0
  660. package/dist/users/password.d.ts +85 -0
  661. package/dist/users/password.d.ts.map +1 -0
  662. package/dist/users/password.js +138 -0
  663. package/dist/users/password.js.map +1 -0
  664. package/dist/users/repository.d.ts +263 -0
  665. package/dist/users/repository.d.ts.map +1 -0
  666. package/dist/users/repository.js +499 -0
  667. package/dist/users/repository.js.map +1 -0
  668. package/dist/users/service.d.ts +299 -0
  669. package/dist/users/service.d.ts.map +1 -0
  670. package/dist/users/service.js +698 -0
  671. package/dist/users/service.js.map +1 -0
  672. package/dist/users/types.d.ts +220 -0
  673. package/dist/users/types.d.ts.map +1 -0
  674. package/dist/users/types.js +77 -0
  675. package/dist/users/types.js.map +1 -0
  676. package/locales/default/en/common.json +10 -0
  677. package/locales/default/en/consent.json +13 -0
  678. package/locales/default/en/emails.json +17 -0
  679. package/locales/default/en/errors.json +21 -0
  680. package/locales/default/en/forgot-password.json +11 -0
  681. package/locales/default/en/invitation.json +18 -0
  682. package/locales/default/en/login.json +17 -0
  683. package/locales/default/en/logout.json +9 -0
  684. package/locales/default/en/magic-link.json +12 -0
  685. package/locales/default/en/reset-password.json +16 -0
  686. package/locales/default/en/two-factor.json +29 -0
  687. package/migrations/.gitkeep +0 -0
  688. package/migrations/001_extensions.sql +22 -0
  689. package/migrations/002_organizations.sql +43 -0
  690. package/migrations/003_applications.sql +50 -0
  691. package/migrations/004_clients.sql +74 -0
  692. package/migrations/005_users.sql +119 -0
  693. package/migrations/006_roles_permissions.sql +80 -0
  694. package/migrations/007_custom_claims.sql +55 -0
  695. package/migrations/008_config.sql +51 -0
  696. package/migrations/009_audit_log.sql +31 -0
  697. package/migrations/010_oidc_adapter.sql +34 -0
  698. package/migrations/011_seed.sql +53 -0
  699. package/migrations/012_two_factor.sql +88 -0
  700. package/migrations/013_client_secret_sha256.sql +22 -0
  701. package/migrations/014_login_methods.sql +34 -0
  702. package/migrations/015_signing_key_encryption.sql +20 -0
  703. package/migrations/016_failed_login_count.sql +27 -0
  704. package/migrations/017_audit_retention.sql +11 -0
  705. package/migrations/018_admin_api_enhancements.sql +78 -0
  706. package/migrations/019_invitation_details.sql +27 -0
  707. package/migrations/020_two_factor_admin_permission.sql +108 -0
  708. package/migrations/021_auth_recovery_jobs.sql +74 -0
  709. package/migrations/022_recovery_artifact_ownership.sql +25 -0
  710. package/migrations/023_magic_link_authority.sql +39 -0
  711. package/package.json +106 -0
  712. package/templates/default/emails/invitation.hbs +39 -0
  713. package/templates/default/emails/invitation.txt.hbs +18 -0
  714. package/templates/default/emails/magic-link.hbs +30 -0
  715. package/templates/default/emails/magic-link.txt.hbs +11 -0
  716. package/templates/default/emails/otp-code.hbs +31 -0
  717. package/templates/default/emails/otp-code.txt.hbs +15 -0
  718. package/templates/default/emails/password-changed.hbs +24 -0
  719. package/templates/default/emails/password-changed.txt.hbs +7 -0
  720. package/templates/default/emails/password-reset.hbs +30 -0
  721. package/templates/default/emails/password-reset.txt.hbs +11 -0
  722. package/templates/default/emails/welcome.hbs +25 -0
  723. package/templates/default/emails/welcome.txt.hbs +9 -0
  724. package/templates/default/layouts/main.hbs +49 -0
  725. package/templates/default/pages/accept-invite.hbs +25 -0
  726. package/templates/default/pages/consent.hbs +27 -0
  727. package/templates/default/pages/error.hbs +15 -0
  728. package/templates/default/pages/forgot-password.hbs +21 -0
  729. package/templates/default/pages/invite-expired.hbs +6 -0
  730. package/templates/default/pages/invite-success.hbs +9 -0
  731. package/templates/default/pages/login.hbs +108 -0
  732. package/templates/default/pages/logout-success.hbs +5 -0
  733. package/templates/default/pages/logout.hbs +24 -0
  734. package/templates/default/pages/magic-link-sent.hbs +10 -0
  735. package/templates/default/pages/magic-link-success.hbs +17 -0
  736. package/templates/default/pages/reset-password.hbs +20 -0
  737. package/templates/default/pages/reset-success.hbs +9 -0
  738. package/templates/default/pages/two-factor-setup.hbs +65 -0
  739. package/templates/default/pages/two-factor-verify.hbs +77 -0
  740. package/templates/default/partials/flash-messages.hbs +10 -0
  741. package/templates/default/partials/footer.hbs +4 -0
  742. package/templates/default/partials/header.hbs +8 -0
@@ -0,0 +1,475 @@
1
+ /**
2
+ * Token repository — PostgreSQL CRUD for all three token tables.
3
+ *
4
+ * Password-reset and invitation tokens use shared allowlisted helpers. Magic-link issuance and
5
+ * consumption use dedicated authority-aware transactions so callers cannot omit tenant, live
6
+ * client, or interaction validation.
7
+ *
8
+ * Token lifecycle:
9
+ * 1. insertToken() → store hash + expiry for a user
10
+ * 2. findValidToken() → look up unused, non-expired token by hash
11
+ * 3. markTokenUsed() → set used_at = NOW() after successful verification
12
+ * 4. invalidateUserTokens() → expire all active tokens for a user (when new token issued)
13
+ * 5. deleteExpiredTokens() → cleanup old rows (housekeeping)
14
+ */
15
+ import { getPool } from '../lib/database.js';
16
+ import { logger } from '../lib/logger.js';
17
+ // ---------------------------------------------------------------------------
18
+ // Allowlist validation
19
+ // ---------------------------------------------------------------------------
20
+ /** Set of valid token table names for runtime validation */
21
+ const VALID_TABLES = new Set([
22
+ 'magic_link_tokens',
23
+ 'password_reset_tokens',
24
+ 'invitation_tokens',
25
+ ]);
26
+ /**
27
+ * Validate that the table name is in the allowlist.
28
+ * Throws immediately on invalid names — this is a programming error, not a user error.
29
+ *
30
+ * @param table - Table name to validate
31
+ * @throws Error if table name is not in the allowlist
32
+ */
33
+ function assertValidTable(table) {
34
+ if (!VALID_TABLES.has(table)) {
35
+ throw new Error(`Invalid token table: "${table}". Must be one of: ${[...VALID_TABLES].join(', ')}`);
36
+ }
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Row mapping
40
+ // ---------------------------------------------------------------------------
41
+ /**
42
+ * Map a snake_case database row to a camelCase TokenRecord.
43
+ *
44
+ * @param row - Raw database row
45
+ * @returns Mapped TokenRecord with camelCase properties
46
+ */
47
+ function mapRowToToken(row) {
48
+ return {
49
+ id: row.id,
50
+ userId: row.user_id,
51
+ tokenHash: row.token_hash,
52
+ expiresAt: row.expires_at,
53
+ usedAt: row.used_at,
54
+ createdAt: row.created_at,
55
+ };
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // CRUD operations
59
+ // ---------------------------------------------------------------------------
60
+ /**
61
+ * Insert a new token into the specified table.
62
+ *
63
+ * @param table - Target token table (magic_link_tokens | password_reset_tokens | invitation_tokens)
64
+ * @param userId - UUID of the user this token belongs to
65
+ * @param tokenHash - SHA-256 hex hash of the plaintext token
66
+ * @param expiresAt - When this token expires
67
+ */
68
+ export async function insertToken(table, userId, tokenHash, expiresAt) {
69
+ assertValidTable(table);
70
+ const pool = getPool();
71
+ await pool.query(`INSERT INTO ${table} (user_id, token_hash, expires_at)
72
+ VALUES ($1, $2, $3)`, [userId, tokenHash, expiresAt]);
73
+ logger.debug({ table, userId }, 'Token inserted');
74
+ }
75
+ /**
76
+ * Create or observe the single token artifact owned by a recovery job.
77
+ *
78
+ * A transaction locks the user row as the shared serialization authority, reuses an existing job
79
+ * artifact, or invalidates an older artifact and inserts exactly one new row. A retry from an older
80
+ * job cannot replace authority created by any newer job, even after that authority is consumed or
81
+ * expires. SQL identifiers come exclusively from the closed table union.
82
+ *
83
+ * @param input - Recovery-job token authority and deterministic token facts.
84
+ */
85
+ export async function ensureRecoveryJobToken(input) {
86
+ assertValidTable(input.table);
87
+ const pool = getPool();
88
+ const client = await pool.connect();
89
+ try {
90
+ await client.query('BEGIN');
91
+ const lockedUser = await client.query('SELECT id FROM users WHERE id = $1 FOR UPDATE', [
92
+ input.userId,
93
+ ]);
94
+ if (lockedUser.rowCount !== 1) {
95
+ throw new Error('Recovery artifact user disappeared before issuance');
96
+ }
97
+ const jobOrder = await client.query('SELECT created_at FROM auth_recovery_jobs WHERE id = $1', [input.recoveryJobId]);
98
+ const currentJob = jobOrder.rows[0];
99
+ if (!currentJob) {
100
+ throw new Error('Recovery job disappeared before artifact issuance');
101
+ }
102
+ if (input.table === 'magic_link_tokens') {
103
+ const clientMatches = input.interactionUid === null && input.clientId === null
104
+ ? true
105
+ : input.interactionUid !== null &&
106
+ input.clientId !== null &&
107
+ (await lockActiveClientAuthority(client, input.clientId, input.organizationId));
108
+ if (!clientMatches) {
109
+ await client.query('COMMIT');
110
+ return 'superseded';
111
+ }
112
+ }
113
+ const existing = await client.query(`SELECT used_at IS NULL AND expires_at > NOW() AS active
114
+ FROM ${input.table}
115
+ WHERE recovery_job_id = $1`, [input.recoveryJobId]);
116
+ if (existing.rows[0]) {
117
+ await client.query('COMMIT');
118
+ return existing.rows[0].active ? 'active' : 'superseded';
119
+ }
120
+ const newestArtifact = await client.query(`SELECT token.recovery_job_id, job.created_at
121
+ FROM ${input.table} AS token
122
+ JOIN auth_recovery_jobs AS job ON job.id = token.recovery_job_id
123
+ WHERE token.user_id = $1
124
+ AND token.recovery_job_id IS NOT NULL
125
+ ORDER BY job.created_at DESC, job.id DESC
126
+ LIMIT 1`, [input.userId]);
127
+ const newest = newestArtifact.rows[0];
128
+ const currentCreatedAt = currentJob.created_at.getTime();
129
+ const newerArtifactExists = newest !== undefined &&
130
+ (newest.created_at.getTime() > currentCreatedAt ||
131
+ (newest.created_at.getTime() === currentCreatedAt &&
132
+ newest.recovery_job_id > input.recoveryJobId));
133
+ if (newerArtifactExists) {
134
+ await client.query('COMMIT');
135
+ return 'superseded';
136
+ }
137
+ await client.query(`UPDATE ${input.table}
138
+ SET used_at = NOW()
139
+ WHERE user_id = $1 AND used_at IS NULL AND expires_at > NOW()`, [input.userId]);
140
+ if (input.table === 'magic_link_tokens') {
141
+ await client.query(`INSERT INTO magic_link_tokens
142
+ (user_id, token_hash, expires_at, recovery_job_id, organization_id, interaction_uid)
143
+ VALUES ($1, $2, $3, $4, $5, $6)`, [
144
+ input.userId,
145
+ input.tokenHash,
146
+ input.expiresAt,
147
+ input.recoveryJobId,
148
+ input.organizationId,
149
+ input.interactionUid,
150
+ ]);
151
+ }
152
+ else {
153
+ await client.query(`INSERT INTO password_reset_tokens (user_id, token_hash, expires_at, recovery_job_id)
154
+ VALUES ($1, $2, $3, $4)`, [input.userId, input.tokenHash, input.expiresAt, input.recoveryJobId]);
155
+ }
156
+ await client.query('COMMIT');
157
+ return 'active';
158
+ }
159
+ catch (error) {
160
+ await client.query('ROLLBACK');
161
+ throw error;
162
+ }
163
+ finally {
164
+ client.release();
165
+ }
166
+ }
167
+ /**
168
+ * Lock and validate the current client tenant inside an artifact transaction.
169
+ *
170
+ * Client ownership is checked in the same transaction that inserts or consumes the artifact so a
171
+ * concurrent revocation cannot pass an earlier route-only check and then gain authority.
172
+ *
173
+ * @param client - Active PostgreSQL transaction.
174
+ * @param clientId - Public OIDC client identifier resolved from the live interaction.
175
+ * @param organizationId - Tenant which must currently own the active client.
176
+ * @returns True only when one current active client row is locked.
177
+ */
178
+ async function lockActiveClientAuthority(client, clientId, organizationId) {
179
+ const result = await client.query(`SELECT id
180
+ FROM clients
181
+ WHERE client_id = $1
182
+ AND organization_id = $2
183
+ AND status = 'active'
184
+ FOR SHARE`, [clientId, organizationId]);
185
+ return result.rowCount === 1;
186
+ }
187
+ /**
188
+ * Find a valid (unused, not expired) token by its hash.
189
+ *
190
+ * Checks both `used_at IS NULL` and `expires_at > NOW()` in a single query
191
+ * for efficiency. Returns null if no matching valid token exists.
192
+ *
193
+ * @param table - Target token table
194
+ * @param tokenHash - SHA-256 hex hash to look up
195
+ * @returns The token record if valid, or null if not found/expired/used
196
+ */
197
+ export async function findValidToken(table, tokenHash) {
198
+ assertValidTable(table);
199
+ const pool = getPool();
200
+ const result = await pool.query(`SELECT id, user_id, token_hash, expires_at, used_at, created_at
201
+ FROM ${table}
202
+ WHERE token_hash = $1
203
+ AND used_at IS NULL
204
+ AND expires_at > NOW()`, [tokenHash]);
205
+ if (result.rows.length === 0) {
206
+ return null;
207
+ }
208
+ return mapRowToToken(result.rows[0]);
209
+ }
210
+ /**
211
+ * Find a valid token only when its user belongs to the resolved organization.
212
+ *
213
+ * Tenant binding is enforced in the lookup itself so a valid token presented under another
214
+ * tenant is indistinguishable from an invalid token and cannot reach account mutation.
215
+ *
216
+ * @param table - Target token table.
217
+ * @param tokenHash - SHA-256 token digest.
218
+ * @param organizationId - Tenant authority resolved from the public route.
219
+ * @returns The valid tenant-owned token, or null.
220
+ */
221
+ export async function findValidTokenForOrganization(table, tokenHash, organizationId) {
222
+ assertValidTable(table);
223
+ const pool = getPool();
224
+ const result = await pool.query(`SELECT token.id, token.user_id, token.token_hash,
225
+ token.expires_at, token.used_at, token.created_at
226
+ FROM ${table} AS token
227
+ JOIN users AS account ON account.id = token.user_id
228
+ WHERE token.token_hash = $1
229
+ AND account.organization_id = $2
230
+ AND token.used_at IS NULL
231
+ AND token.expires_at > NOW()`, [tokenHash, organizationId]);
232
+ return result.rows[0] ? mapRowToToken(result.rows[0]) : null;
233
+ }
234
+ /**
235
+ * Lock one valid magic-link artifact together with its tenant-owned user.
236
+ *
237
+ * Legacy rows without persisted organization authority do not match. The caller must keep the
238
+ * supplied client transaction open while validating interaction authority and applying all
239
+ * successful state changes.
240
+ *
241
+ * @param client - Active PostgreSQL transaction client.
242
+ * @param tokenHash - SHA-256 digest of the presented artifact.
243
+ * @param organizationId - Organization resolved from the public route.
244
+ * @returns The locked authority record, or null for every invalid authority state.
245
+ */
246
+ export async function findAndLockMagicLinkToken(client, tokenHash, organizationId) {
247
+ const result = await client.query(`SELECT token.id, token.user_id, token.token_hash, token.expires_at, token.used_at,
248
+ token.created_at, token.organization_id, token.interaction_uid,
249
+ account.status AS account_status
250
+ FROM magic_link_tokens AS token
251
+ JOIN users AS account
252
+ ON account.id = token.user_id
253
+ AND account.organization_id = token.organization_id
254
+ WHERE token.token_hash = $1
255
+ AND token.organization_id = $2
256
+ AND token.authority_bound = TRUE
257
+ AND token.used_at IS NULL
258
+ AND token.expires_at > NOW()
259
+ FOR UPDATE OF token, account`, [tokenHash, organizationId]);
260
+ const row = result.rows[0];
261
+ if (!row)
262
+ return null;
263
+ return {
264
+ ...mapRowToToken(row),
265
+ organizationId: row.organization_id,
266
+ interactionUid: row.interaction_uid,
267
+ accountStatus: row.account_status,
268
+ };
269
+ }
270
+ /**
271
+ * Conditionally consume a previously locked magic-link artifact.
272
+ *
273
+ * The predicates are repeated at mutation time so expiry or accidental prior consumption cannot
274
+ * be converted into a successful use. The caller must roll back when this function returns false.
275
+ *
276
+ * @param client - Active PostgreSQL transaction client that owns the artifact lock.
277
+ * @param tokenId - UUID of the locked magic-link artifact.
278
+ * @returns True only when exactly one still-valid row was consumed.
279
+ */
280
+ export async function consumeLockedMagicLinkToken(client, tokenId) {
281
+ const result = await client.query(`UPDATE magic_link_tokens
282
+ SET used_at = NOW()
283
+ WHERE id = $1
284
+ AND used_at IS NULL
285
+ AND expires_at > NOW()
286
+ RETURNING id`, [tokenId]);
287
+ return result.rowCount === 1;
288
+ }
289
+ /**
290
+ * Validate all durable authority and apply one magic-link login in a single transaction.
291
+ *
292
+ * The artifact and account rows remain locked from lookup through consumption, account update,
293
+ * and audit insertion. Every authority mismatch rolls back before mutation, including a missing,
294
+ * changed, or unexpectedly supplied interaction identifier. Cache and Redis continuation work
295
+ * deliberately happen after this durable transaction because they are separate stores.
296
+ *
297
+ * @param input - Route tenant, presented interaction, artifact digest, and safe request metadata.
298
+ * @returns The committed account authority, or null for every public rejection condition.
299
+ */
300
+ export async function consumeAuthorizedMagicLink(input) {
301
+ const client = await getPool().connect();
302
+ try {
303
+ await client.query('BEGIN');
304
+ const clientMatches = input.interactionUid === null && input.clientId === null
305
+ ? true
306
+ : input.interactionUid !== null &&
307
+ input.clientId !== null &&
308
+ (await lockActiveClientAuthority(client, input.clientId, input.organizationId));
309
+ if (!clientMatches) {
310
+ await client.query('ROLLBACK');
311
+ return null;
312
+ }
313
+ const token = await findAndLockMagicLinkToken(client, input.tokenHash, input.organizationId);
314
+ const authorityMatches = token !== null &&
315
+ token.accountStatus === 'active' &&
316
+ token.interactionUid === input.interactionUid;
317
+ if (!authorityMatches) {
318
+ await client.query('ROLLBACK');
319
+ return null;
320
+ }
321
+ const consumed = await consumeLockedMagicLinkToken(client, token.id);
322
+ if (!consumed) {
323
+ await client.query('ROLLBACK');
324
+ return null;
325
+ }
326
+ const accountUpdate = await client.query(`UPDATE users
327
+ SET email_verified = TRUE,
328
+ last_login_at = NOW(),
329
+ login_count = login_count + 1,
330
+ failed_login_count = 0,
331
+ last_failed_login_at = NULL
332
+ WHERE id = $1
333
+ AND organization_id = $2
334
+ AND status = 'active'
335
+ RETURNING id`, [token.userId, input.organizationId]);
336
+ if (accountUpdate.rowCount !== 1) {
337
+ await client.query('ROLLBACK');
338
+ return null;
339
+ }
340
+ await client.query(`INSERT INTO audit_log (
341
+ organization_id, user_id, event_type, event_category, description,
342
+ metadata, ip_address
343
+ )
344
+ VALUES ($1, $2, $3, $4, $5, $6, $7)`, [
345
+ input.organizationId,
346
+ token.userId,
347
+ 'user.login.magic_link',
348
+ 'authentication',
349
+ 'Magic link login successful',
350
+ '{}',
351
+ input.ipAddress ?? null,
352
+ ]);
353
+ await client.query('COMMIT');
354
+ return { userId: token.userId, interactionUid: token.interactionUid };
355
+ }
356
+ catch (error) {
357
+ await client.query('ROLLBACK');
358
+ throw error;
359
+ }
360
+ finally {
361
+ client.release();
362
+ }
363
+ }
364
+ /**
365
+ * Mark a token as used by setting used_at = NOW().
366
+ *
367
+ * Called after successful token verification to prevent reuse.
368
+ * This is a single-use pattern — once marked, the token cannot be found by findValidToken.
369
+ *
370
+ * @param table - Target token table
371
+ * @param tokenId - UUID of the token row to mark
372
+ */
373
+ export async function markTokenUsed(table, tokenId) {
374
+ assertValidTable(table);
375
+ const pool = getPool();
376
+ await pool.query(`UPDATE ${table} SET used_at = NOW() WHERE id = $1`, [tokenId]);
377
+ logger.debug({ table, tokenId }, 'Token marked as used');
378
+ }
379
+ /**
380
+ * Delete expired or used tokens older than a given cutoff date.
381
+ *
382
+ * Housekeeping function to prevent token tables from growing indefinitely.
383
+ * Removes tokens where expires_at < cutoff OR (used_at IS NOT NULL AND used_at < cutoff).
384
+ *
385
+ * @param table - Target token table
386
+ * @param olderThan - Cutoff date — tokens expired/used before this are deleted
387
+ * @returns Number of rows deleted
388
+ */
389
+ export async function deleteExpiredTokens(table, olderThan) {
390
+ assertValidTable(table);
391
+ const pool = getPool();
392
+ const result = await pool.query(`DELETE FROM ${table}
393
+ WHERE expires_at < $1
394
+ OR (used_at IS NOT NULL AND used_at < $1)`, [olderThan]);
395
+ const count = result.rowCount ?? 0;
396
+ if (count > 0) {
397
+ logger.info({ table, count, olderThan: olderThan.toISOString() }, 'Expired tokens cleaned up');
398
+ }
399
+ return count;
400
+ }
401
+ /**
402
+ * Invalidate all unused tokens for a user in a table.
403
+ *
404
+ * Sets used_at = NOW() on all active (unused, non-expired) tokens.
405
+ * Called when a new token is issued to ensure only the latest token is valid.
406
+ * This prevents token accumulation and confusion from multiple active tokens.
407
+ *
408
+ * @param table - Target token table
409
+ * @param userId - UUID of the user whose tokens should be invalidated
410
+ */
411
+ export async function invalidateUserTokens(table, userId) {
412
+ assertValidTable(table);
413
+ const pool = getPool();
414
+ const result = await pool.query(`UPDATE ${table}
415
+ SET used_at = NOW()
416
+ WHERE user_id = $1
417
+ AND used_at IS NULL`, [userId]);
418
+ const count = result.rowCount ?? 0;
419
+ if (count > 0) {
420
+ logger.debug({ table, userId, count }, 'User tokens invalidated');
421
+ }
422
+ }
423
+ // ---------------------------------------------------------------------------
424
+ // Invitation-specific operations
425
+ // ---------------------------------------------------------------------------
426
+ /**
427
+ * Insert an invitation token with optional details and inviter metadata.
428
+ *
429
+ * Unlike the generic insertToken(), this stores additional JSONB details
430
+ * (pre-assigned roles, claims, personal message) and tracks who sent the invite.
431
+ *
432
+ * @param userId - UUID of the invited user
433
+ * @param tokenHash - SHA-256 hex hash of the plaintext token
434
+ * @param expiresAt - When this invitation expires
435
+ * @param details - Optional JSONB details (roles, claims, personalMessage, inviterName)
436
+ * @param invitedBy - Optional UUID of the admin who created this invitation
437
+ */
438
+ export async function insertInvitationToken(userId, tokenHash, expiresAt, details, invitedBy) {
439
+ const pool = getPool();
440
+ await pool.query(`INSERT INTO invitation_tokens (user_id, token_hash, expires_at, details, invited_by)
441
+ VALUES ($1, $2, $3, $4, $5)`, [userId, tokenHash, expiresAt, details ? JSON.stringify(details) : null, invitedBy ?? null]);
442
+ logger.debug({ userId, hasDetails: !!details }, 'Invitation token inserted');
443
+ }
444
+ /**
445
+ * Find a valid invitation token with its details metadata.
446
+ *
447
+ * Returns the full InvitationTokenRecord including the details JSONB
448
+ * column, which stores pre-assignment metadata for roles, claims, etc.
449
+ *
450
+ * @param tokenHash - SHA-256 hex hash to look up
451
+ * @returns The invitation token record with details, or null if not found/expired/used
452
+ */
453
+ export async function findValidInvitationToken(tokenHash) {
454
+ const pool = getPool();
455
+ const result = await pool.query(`SELECT id, user_id, token_hash, expires_at, used_at, created_at, details, invited_by
456
+ FROM invitation_tokens
457
+ WHERE token_hash = $1
458
+ AND used_at IS NULL
459
+ AND expires_at > NOW()`, [tokenHash]);
460
+ if (result.rows.length === 0) {
461
+ return null;
462
+ }
463
+ const row = result.rows[0];
464
+ return {
465
+ id: row.id,
466
+ userId: row.user_id,
467
+ tokenHash: row.token_hash,
468
+ expiresAt: row.expires_at,
469
+ usedAt: row.used_at,
470
+ createdAt: row.created_at,
471
+ details: row.details,
472
+ invitedBy: row.invited_by,
473
+ };
474
+ }
475
+ //# sourceMappingURL=token-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-repository.js","sourceRoot":"","sources":["../../src/auth/token-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Token generation and hashing utilities.
3
+ *
4
+ * Used by all token-based auth flows: magic links, password resets, and invitations.
5
+ * Tokens are generated as cryptographically secure random bytes, then hashed with
6
+ * SHA-256 for storage. The plaintext goes in the email/URL; only the hash is stored
7
+ * in the database — so a DB breach never leaks usable tokens.
8
+ *
9
+ * @example
10
+ * const { plaintext, hash } = generateToken();
11
+ * // plaintext → email link
12
+ * // hash → INSERT INTO magic_link_tokens (token_hash, ...)
13
+ *
14
+ * // Later, when verifying:
15
+ * const lookupHash = hashToken(plaintextFromUrl);
16
+ * // SELECT ... WHERE token_hash = lookupHash
17
+ */
18
+ /** Result of generating a new token — plaintext for the URL, hash for the DB */
19
+ export interface GeneratedToken {
20
+ /** Base64url-encoded plaintext — included in the email/URL sent to the user */
21
+ plaintext: string;
22
+ /** SHA-256 hex digest — stored in the database for lookup */
23
+ hash: string;
24
+ }
25
+ /**
26
+ * Generate a cryptographically secure token.
27
+ *
28
+ * Returns both the plaintext (for the email/URL) and the SHA-256 hash (for DB storage).
29
+ * Uses 32 bytes of randomness (256 bits) which provides ample collision resistance
30
+ * and brute-force protection.
31
+ *
32
+ * @returns Object with `plaintext` (base64url) and `hash` (hex SHA-256)
33
+ */
34
+ export declare function generateToken(): GeneratedToken;
35
+ /**
36
+ * Hash a plaintext token for database lookup.
37
+ *
38
+ * Used during verification — the user provides the plaintext via URL, we hash it
39
+ * and look up the matching row in the token table.
40
+ *
41
+ * @param plaintext - The base64url token string from the URL
42
+ * @returns SHA-256 hex digest for database lookup
43
+ */
44
+ export declare function hashToken(plaintext: string): string;
45
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAI9C;AAMD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Token generation and hashing utilities.
3
+ *
4
+ * Used by all token-based auth flows: magic links, password resets, and invitations.
5
+ * Tokens are generated as cryptographically secure random bytes, then hashed with
6
+ * SHA-256 for storage. The plaintext goes in the email/URL; only the hash is stored
7
+ * in the database — so a DB breach never leaks usable tokens.
8
+ *
9
+ * @example
10
+ * const { plaintext, hash } = generateToken();
11
+ * // plaintext → email link
12
+ * // hash → INSERT INTO magic_link_tokens (token_hash, ...)
13
+ *
14
+ * // Later, when verifying:
15
+ * const lookupHash = hashToken(plaintextFromUrl);
16
+ * // SELECT ... WHERE token_hash = lookupHash
17
+ */
18
+ import crypto from 'node:crypto';
19
+ // ---------------------------------------------------------------------------
20
+ // Token generation
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Generate a cryptographically secure token.
24
+ *
25
+ * Returns both the plaintext (for the email/URL) and the SHA-256 hash (for DB storage).
26
+ * Uses 32 bytes of randomness (256 bits) which provides ample collision resistance
27
+ * and brute-force protection.
28
+ *
29
+ * @returns Object with `plaintext` (base64url) and `hash` (hex SHA-256)
30
+ */
31
+ export function generateToken() {
32
+ const plaintext = crypto.randomBytes(32).toString('base64url');
33
+ const hash = crypto.createHash('sha256').update(plaintext).digest('hex');
34
+ return { plaintext, hash };
35
+ }
36
+ // ---------------------------------------------------------------------------
37
+ // Token hashing
38
+ // ---------------------------------------------------------------------------
39
+ /**
40
+ * Hash a plaintext token for database lookup.
41
+ *
42
+ * Used during verification — the user provides the plaintext via URL, we hash it
43
+ * and look up the matching row in the token table.
44
+ *
45
+ * @param plaintext - The base64url token string from the URL
46
+ * @returns SHA-256 hex digest for database lookup
47
+ */
48
+ export function hashToken(plaintext) {
49
+ return crypto.createHash('sha256').update(plaintext).digest('hex');
50
+ }
51
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAcjC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * CLI bootstrap — direct-DB execution mode for infrastructure commands.
3
+ *
4
+ * Provides `withBootstrap()` for commands that need direct database/Redis
5
+ * access (init, migrate, seed, health --direct, user 2fa --direct).
6
+ *
7
+ * These commands run before or without the HTTP server, so they connect
8
+ * directly to PostgreSQL + Redis. The HTTP-based admin commands have been
9
+ * extracted to the standalone `@portaidentity/cli` package.
10
+ *
11
+ * Uses dynamic imports so that the config module (which validates env vars
12
+ * at load time) isn't triggered until bootstrap() is called. This allows
13
+ * CLI flag overrides (--database-url, --redis-url) to set process.env
14
+ * BEFORE config parses, making the overrides effective.
15
+ *
16
+ * @module cli/bootstrap
17
+ */
18
+ import 'dotenv/config';
19
+ import type { GlobalOptions } from './index.js';
20
+ /**
21
+ * Bootstrap the CLI environment: load dotenv, connect DB + Redis.
22
+ *
23
+ * CLI flags (--database-url, --redis-url) override env vars if provided.
24
+ * The overrides are applied to process.env BEFORE the config module loads,
25
+ * so they propagate through to connectDatabase() and connectRedis().
26
+ *
27
+ * @param argv - Parsed CLI global options from yargs
28
+ */
29
+ export declare function bootstrap(argv: GlobalOptions): Promise<void>;
30
+ /**
31
+ * Clean shutdown: disconnect Redis then DB.
32
+ *
33
+ * Redis is disconnected first because some operations may flush
34
+ * cache entries to the database during shutdown.
35
+ */
36
+ export declare function shutdown(): Promise<void>;
37
+ /**
38
+ * Convenience wrapper: bootstrap → run command → shutdown.
39
+ *
40
+ * Ensures cleanup happens even if the command throws an error.
41
+ * This is the recommended way for command handlers to use bootstrap:
42
+ *
43
+ * ```typescript
44
+ * await withBootstrap(argv, async () => {
45
+ * const orgs = await listOrganizations(pool);
46
+ * printTable(headers, rows);
47
+ * });
48
+ * ```
49
+ *
50
+ * @param argv - Parsed CLI global options from yargs
51
+ * @param fn - The command handler function to execute
52
+ * @returns The return value of the command handler
53
+ */
54
+ export declare function withBootstrap<T>(argv: GlobalOptions, fn: () => Promise<T>): Promise<T>;
55
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/cli/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BlE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAOZ"}