@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,158 @@
1
+ /**
2
+ * Bounded lifecycle owner for durable account-recovery jobs.
3
+ *
4
+ * The worker has a single claim loop, processes one claimed batch sequentially, and never permits
5
+ * overlapping polls. Repository ownership checks fence every transition. Product-specific token
6
+ * and mail work is injected through a processor so the scheduler can be tested without coupling
7
+ * its concurrency rules to route or template implementation.
8
+ */
9
+ import { type BeginRecoveryJobAttemptInput, type ClaimRecoveryJobsInput, type ClaimedRecoveryJob, type FinishRecoveryJobInput, type RecoveryJob, type RetryRecoveryJobInput } from './recovery-job-repository.js';
10
+ /** Poll interval used when no enqueue wake-up arrives. */
11
+ export declare const RECOVERY_WORKER_POLL_MILLISECONDS = 1000;
12
+ /** Lease age after which another worker may recover a crashed claim. */
13
+ export declare const RECOVERY_WORKER_LEASE_MILLISECONDS = 300000;
14
+ /** Maximum graceful-shutdown wait for the active worker cycle. */
15
+ export declare const RECOVERY_WORKER_SHUTDOWN_MILLISECONDS = 30000;
16
+ /** Four delays between the five permitted processing attempts. */
17
+ export declare const RECOVERY_WORKER_RETRY_DELAYS_MILLISECONDS: readonly [1000, 10000, 60000, 300000];
18
+ /** Closed privacy-safe worker failure reasons. */
19
+ export declare const RECOVERY_WORKER_FAILURE_REASONS: readonly ['database_unavailable', 'smtp_unavailable', 'smtp_outcome_unknown', 'invalid_protected_input', 'template_unavailable', 'lease_exhausted', 'processing_failed'];
20
+ /** Privacy-safe reason accepted by recovery retry and terminal transitions. */
21
+ export type RecoveryWorkerFailureReason = (typeof RECOVERY_WORKER_FAILURE_REASONS)[number];
22
+ /** Durable transitions required by the worker scheduler. */
23
+ export interface RecoveryWorkerRepository {
24
+ /** Atomically claim one bounded available or expired-lease batch. */
25
+ claimAvailable(input: ClaimRecoveryJobsInput): Promise<readonly ClaimedRecoveryJob[]>;
26
+ /** Charge one attempt immediately before account-specific processing begins. */
27
+ beginAttempt(input: BeginRecoveryJobAttemptInput): Promise<RecoveryJob | null>;
28
+ /** Return an owned transient failure to the queue. */
29
+ scheduleRetry(input: RetryRecoveryJobInput): Promise<boolean>;
30
+ /** Complete an owned claim. */
31
+ markCompleted(input: FinishRecoveryJobInput): Promise<boolean>;
32
+ /** Terminally close an owned claim. */
33
+ markTerminalFailure(input: FinishRecoveryJobInput): Promise<boolean>;
34
+ }
35
+ /** Result returned by account-specific recovery processing. */
36
+ export type RecoveryJobProcessingResult = 'completed' | 'no_op';
37
+ /** Product-specific processor invoked only after a durable claim succeeds. */
38
+ export interface RecoveryJobProcessor {
39
+ /**
40
+ * Process one claimed job.
41
+ *
42
+ * @param job - Owner-fenced durable claim.
43
+ * @returns Whether the job produced an intended effect or completed as a private no-op.
44
+ */
45
+ process(job: ClaimedRecoveryJob): Promise<RecoveryJobProcessingResult>;
46
+ }
47
+ /** Clock/timer boundary used for deterministic worker tests. */
48
+ export interface RecoveryWorkerClock {
49
+ /** Read the repository clock. */
50
+ now(): Date;
51
+ /** Schedule a callback after a bounded delay. */
52
+ setTimeout(callback: () => void, milliseconds: number): ReturnType<typeof setTimeout>;
53
+ /** Cancel a previously scheduled callback. */
54
+ clearTimeout(timer: ReturnType<typeof setTimeout>): void;
55
+ }
56
+ /** Privacy-safe lifecycle event exposed to owned test and metrics observers. */
57
+ export interface RecoveryWorkerEvent {
58
+ /** Closed event category. */
59
+ readonly event: 'claimed' | 'completed' | 'no_op' | 'retry_scheduled' | 'lease_reclaimed' | 'terminal_failure' | 'shutdown_started' | 'shutdown_settled' | 'shutdown_timeout';
60
+ /** Job identity for an in-process observer; the default logger never emits it. */
61
+ readonly jobId?: string;
62
+ /** Processing attempt when applicable. */
63
+ readonly attempt?: number;
64
+ /** Retry delay when applicable. */
65
+ readonly delayMilliseconds?: number;
66
+ /** Closed failure reason when applicable. */
67
+ readonly reason?: RecoveryWorkerFailureReason;
68
+ }
69
+ /** Optional observer for metrics and implementation tests. */
70
+ export type RecoveryWorkerObserver = (event: RecoveryWorkerEvent) => void;
71
+ /** Construction dependencies for a recovery worker. */
72
+ export interface RecoveryWorkerOptions {
73
+ /** Durable repository used for every ownership transition. */
74
+ readonly repository: RecoveryWorkerRepository;
75
+ /** Account-specific processor. */
76
+ readonly processor: RecoveryJobProcessor;
77
+ /** Stable worker-process UUID; defaults to a fresh UUID. */
78
+ readonly workerId?: string;
79
+ /** Deterministic clock/timer boundary. */
80
+ readonly clock?: RecoveryWorkerClock;
81
+ /** Optional in-process event observer. */
82
+ readonly observer?: RecoveryWorkerObserver;
83
+ }
84
+ /** Typed processing failure with a closed public reason and retry policy. */
85
+ export declare class RecoveryJobProcessingError extends Error {
86
+ /** Closed privacy-safe reason. */
87
+ readonly reason: RecoveryWorkerFailureReason;
88
+ /** Whether another bounded attempt may succeed. */
89
+ readonly retryable: boolean;
90
+ /**
91
+ * Create a worker-visible processing failure.
92
+ *
93
+ * @param reason - Closed privacy-safe failure reason.
94
+ * @param retryable - Whether the job may be rescheduled below the attempt limit.
95
+ */
96
+ constructor(reason: RecoveryWorkerFailureReason, retryable: boolean);
97
+ }
98
+ /**
99
+ * Create a bounded recovery worker.
100
+ *
101
+ * @param options - Repository, processor, and optional deterministic boundaries.
102
+ * @returns Stopped worker ready for explicit lifecycle ownership.
103
+ */
104
+ export declare function createRecoveryWorker(options: RecoveryWorkerOptions): RecoveryWorker;
105
+ /** Single-flight scheduler for durable recovery work. */
106
+ export declare class RecoveryWorker {
107
+ /** Durable transition repository. */
108
+ protected readonly repository: RecoveryWorkerRepository;
109
+ /** Account-specific processing boundary. */
110
+ protected readonly processor: RecoveryJobProcessor;
111
+ /** Stable owner identity persisted with every claim. */
112
+ protected readonly workerId: string;
113
+ /** Clock and timer owner. */
114
+ protected readonly clock: RecoveryWorkerClock;
115
+ /** Optional metrics/test observer. */
116
+ protected readonly observer?: RecoveryWorkerObserver;
117
+ /** Whether the worker accepts polls and enqueue wake-ups. */
118
+ protected running: boolean;
119
+ /** Scheduled next poll, if any. */
120
+ protected timer: ReturnType<typeof setTimeout> | null;
121
+ /** Current single-flight claim/process cycle. */
122
+ protected activeCycle: Promise<void> | null;
123
+ /** Wake-up received while a cycle was already active. */
124
+ protected wakePending: boolean;
125
+ /**
126
+ * Create a stopped worker.
127
+ *
128
+ * @param options - Required and optional lifecycle boundaries.
129
+ */
130
+ constructor(options: RecoveryWorkerOptions);
131
+ /** Start polling immediately. Repeated calls are idempotent. */
132
+ start(): void;
133
+ /** Wake the worker after a successful enqueue without creating an overlapping cycle. */
134
+ wake(): void;
135
+ /**
136
+ * Stop claiming and wait a bounded time for the active cycle.
137
+ *
138
+ * @returns True when active work settled before the shutdown deadline.
139
+ */
140
+ stop(): Promise<boolean>;
141
+ /** Schedule the next single-flight cycle. */
142
+ protected schedule(milliseconds: number): void;
143
+ /** Cancel the owned next-poll timer. */
144
+ protected clearScheduledPoll(): void;
145
+ /** Begin one cycle or record a pending wake when another cycle owns execution. */
146
+ protected beginCycle(): void;
147
+ /** Claim and process one bounded batch. */
148
+ protected runCycle(): Promise<void>;
149
+ /** Process one claim and finish, retry, or terminally close it. */
150
+ protected processClaim(job: ClaimedRecoveryJob): Promise<void>;
151
+ /** Reschedule an owned transient failure with its exact attempt delay. */
152
+ protected retry(job: ClaimedRecoveryJob, reason: RecoveryWorkerFailureReason): Promise<void>;
153
+ /** Terminally close an owned claim without exposing raw failure data. */
154
+ protected finishTerminal(job: ClaimedRecoveryJob, reason: RecoveryWorkerFailureReason): Promise<void>;
155
+ /** Notify the optional in-process observer without letting it break processing. */
156
+ protected emit(event: RecoveryWorkerEvent): void;
157
+ }
158
+ //# sourceMappingURL=recovery-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-worker.d.ts","sourceRoot":"","sources":["../../src/auth/recovery-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Bounded lifecycle owner for durable account-recovery jobs.
3
+ *
4
+ * The worker has a single claim loop, processes one claimed batch sequentially, and never permits
5
+ * overlapping polls. Repository ownership checks fence every transition. Product-specific token
6
+ * and mail work is injected through a processor so the scheduler can be tested without coupling
7
+ * its concurrency rules to route or template implementation.
8
+ */
9
+ import { randomUUID } from 'node:crypto';
10
+ import { logger } from '../lib/logger.js';
11
+ import { RECOVERY_JOB_ATTEMPT_LIMIT, RECOVERY_JOB_CLAIM_LIMIT, } from './recovery-job-repository.js';
12
+ /** Poll interval used when no enqueue wake-up arrives. */
13
+ export const RECOVERY_WORKER_POLL_MILLISECONDS = 1_000;
14
+ /** Lease age after which another worker may recover a crashed claim. */
15
+ export const RECOVERY_WORKER_LEASE_MILLISECONDS = 300_000;
16
+ /** Maximum graceful-shutdown wait for the active worker cycle. */
17
+ export const RECOVERY_WORKER_SHUTDOWN_MILLISECONDS = 30_000;
18
+ /** Four delays between the five permitted processing attempts. */
19
+ export const RECOVERY_WORKER_RETRY_DELAYS_MILLISECONDS = [1_000, 10_000, 60_000, 300_000];
20
+ /** Closed privacy-safe worker failure reasons. */
21
+ export const RECOVERY_WORKER_FAILURE_REASONS = [
22
+ 'database_unavailable',
23
+ 'smtp_unavailable',
24
+ 'smtp_outcome_unknown',
25
+ 'invalid_protected_input',
26
+ 'template_unavailable',
27
+ 'lease_exhausted',
28
+ 'processing_failed',
29
+ ];
30
+ /** Typed processing failure with a closed public reason and retry policy. */
31
+ export class RecoveryJobProcessingError extends Error {
32
+ /** Closed privacy-safe reason. */
33
+ reason;
34
+ /** Whether another bounded attempt may succeed. */
35
+ retryable;
36
+ /**
37
+ * Create a worker-visible processing failure.
38
+ *
39
+ * @param reason - Closed privacy-safe failure reason.
40
+ * @param retryable - Whether the job may be rescheduled below the attempt limit.
41
+ */
42
+ constructor(reason, retryable) {
43
+ super(reason);
44
+ this.name = 'RecoveryJobProcessingError';
45
+ this.reason = reason;
46
+ this.retryable = retryable;
47
+ }
48
+ }
49
+ const systemClock = {
50
+ now: () => new Date(),
51
+ setTimeout: (callback, milliseconds) => setTimeout(callback, milliseconds),
52
+ clearTimeout: (timer) => clearTimeout(timer),
53
+ };
54
+ /**
55
+ * Create a bounded recovery worker.
56
+ *
57
+ * @param options - Repository, processor, and optional deterministic boundaries.
58
+ * @returns Stopped worker ready for explicit lifecycle ownership.
59
+ */
60
+ export function createRecoveryWorker(options) {
61
+ return new RecoveryWorker(options);
62
+ }
63
+ /** Single-flight scheduler for durable recovery work. */
64
+ export class RecoveryWorker {
65
+ /** Durable transition repository. */
66
+ repository;
67
+ /** Account-specific processing boundary. */
68
+ processor;
69
+ /** Stable owner identity persisted with every claim. */
70
+ workerId;
71
+ /** Clock and timer owner. */
72
+ clock;
73
+ /** Optional metrics/test observer. */
74
+ observer;
75
+ /** Whether the worker accepts polls and enqueue wake-ups. */
76
+ running = false;
77
+ /** Scheduled next poll, if any. */
78
+ timer = null;
79
+ /** Current single-flight claim/process cycle. */
80
+ activeCycle = null;
81
+ /** Wake-up received while a cycle was already active. */
82
+ wakePending = false;
83
+ /**
84
+ * Create a stopped worker.
85
+ *
86
+ * @param options - Required and optional lifecycle boundaries.
87
+ */
88
+ constructor(options) {
89
+ this.repository = options.repository;
90
+ this.processor = options.processor;
91
+ this.workerId = options.workerId ?? randomUUID();
92
+ this.clock = options.clock ?? systemClock;
93
+ this.observer = options.observer;
94
+ }
95
+ /** Start polling immediately. Repeated calls are idempotent. */
96
+ start() {
97
+ if (this.running)
98
+ return;
99
+ this.running = true;
100
+ this.schedule(0);
101
+ }
102
+ /** Wake the worker after a successful enqueue without creating an overlapping cycle. */
103
+ wake() {
104
+ if (!this.running)
105
+ return;
106
+ if (this.activeCycle) {
107
+ this.wakePending = true;
108
+ return;
109
+ }
110
+ this.schedule(0);
111
+ }
112
+ /**
113
+ * Stop claiming and wait a bounded time for the active cycle.
114
+ *
115
+ * @returns True when active work settled before the shutdown deadline.
116
+ */
117
+ async stop() {
118
+ if (!this.running && !this.activeCycle)
119
+ return true;
120
+ this.running = false;
121
+ this.wakePending = false;
122
+ this.clearScheduledPoll();
123
+ this.emit({ event: 'shutdown_started' });
124
+ const active = this.activeCycle;
125
+ if (!active) {
126
+ this.emit({ event: 'shutdown_settled' });
127
+ return true;
128
+ }
129
+ let timeout = null;
130
+ const settled = await Promise.race([
131
+ active.then(() => true),
132
+ new Promise((resolve) => {
133
+ timeout = this.clock.setTimeout(() => resolve(false), RECOVERY_WORKER_SHUTDOWN_MILLISECONDS);
134
+ }),
135
+ ]);
136
+ if (timeout)
137
+ this.clock.clearTimeout(timeout);
138
+ this.emit({ event: settled ? 'shutdown_settled' : 'shutdown_timeout' });
139
+ return settled;
140
+ }
141
+ /** Schedule the next single-flight cycle. */
142
+ schedule(milliseconds) {
143
+ if (!this.running)
144
+ return;
145
+ this.clearScheduledPoll();
146
+ this.timer = this.clock.setTimeout(() => {
147
+ this.timer = null;
148
+ this.beginCycle();
149
+ }, milliseconds);
150
+ }
151
+ /** Cancel the owned next-poll timer. */
152
+ clearScheduledPoll() {
153
+ if (!this.timer)
154
+ return;
155
+ this.clock.clearTimeout(this.timer);
156
+ this.timer = null;
157
+ }
158
+ /** Begin one cycle or record a pending wake when another cycle owns execution. */
159
+ beginCycle() {
160
+ if (!this.running)
161
+ return;
162
+ if (this.activeCycle) {
163
+ this.wakePending = true;
164
+ return;
165
+ }
166
+ const cycle = this.runCycle();
167
+ this.activeCycle = cycle;
168
+ void cycle
169
+ .catch(() => {
170
+ logger.error({ event: 'recovery_worker_cycle_failed' }, 'Recovery worker cycle failed');
171
+ })
172
+ .finally(() => {
173
+ if (this.activeCycle === cycle)
174
+ this.activeCycle = null;
175
+ if (!this.running)
176
+ return;
177
+ const runImmediately = this.wakePending;
178
+ this.wakePending = false;
179
+ this.schedule(runImmediately ? 0 : RECOVERY_WORKER_POLL_MILLISECONDS);
180
+ });
181
+ }
182
+ /** Claim and process one bounded batch. */
183
+ async runCycle() {
184
+ const now = this.clock.now();
185
+ const jobs = await this.repository.claimAvailable({
186
+ workerId: this.workerId,
187
+ now,
188
+ leaseExpiredBefore: new Date(now.getTime() - RECOVERY_WORKER_LEASE_MILLISECONDS),
189
+ limit: RECOVERY_JOB_CLAIM_LIMIT,
190
+ });
191
+ for (const job of jobs) {
192
+ if (job.claimDisposition === 'lease_exhausted') {
193
+ this.emit({ event: 'claimed', jobId: job.id, attempt: job.attemptCount });
194
+ await this.finishTerminal(job, 'lease_exhausted');
195
+ continue;
196
+ }
197
+ const started = await this.repository.beginAttempt({
198
+ jobId: job.id,
199
+ workerId: this.workerId,
200
+ now: this.clock.now(),
201
+ });
202
+ if (!started) {
203
+ logger.warn({ event: 'recovery_worker_claim_lost' }, 'Recovery worker claim was lost');
204
+ continue;
205
+ }
206
+ const startedClaim = {
207
+ ...started,
208
+ claimDisposition: job.claimDisposition,
209
+ };
210
+ this.emit({ event: 'claimed', jobId: startedClaim.id, attempt: startedClaim.attemptCount });
211
+ if (startedClaim.claimDisposition === 'lease_reclaimed') {
212
+ this.emit({
213
+ event: 'lease_reclaimed',
214
+ jobId: startedClaim.id,
215
+ attempt: startedClaim.attemptCount,
216
+ });
217
+ }
218
+ await this.processClaim(startedClaim);
219
+ }
220
+ if (jobs.length === RECOVERY_JOB_CLAIM_LIMIT)
221
+ this.wakePending = true;
222
+ }
223
+ /** Process one claim and finish, retry, or terminally close it. */
224
+ async processClaim(job) {
225
+ try {
226
+ const result = await this.processor.process(job);
227
+ const completed = await this.repository.markCompleted({
228
+ jobId: job.id,
229
+ workerId: this.workerId,
230
+ now: this.clock.now(),
231
+ });
232
+ if (!completed) {
233
+ logger.warn({ event: 'recovery_worker_claim_lost' }, 'Recovery worker claim was lost');
234
+ return;
235
+ }
236
+ this.emit({
237
+ event: result === 'no_op' ? 'no_op' : 'completed',
238
+ jobId: job.id,
239
+ attempt: job.attemptCount,
240
+ });
241
+ }
242
+ catch (error) {
243
+ const failure = error instanceof RecoveryJobProcessingError
244
+ ? error
245
+ : new RecoveryJobProcessingError('processing_failed', true);
246
+ if (failure.retryable && job.attemptCount < RECOVERY_JOB_ATTEMPT_LIMIT) {
247
+ await this.retry(job, failure.reason);
248
+ return;
249
+ }
250
+ await this.finishTerminal(job, failure.reason);
251
+ }
252
+ }
253
+ /** Reschedule an owned transient failure with its exact attempt delay. */
254
+ async retry(job, reason) {
255
+ const delay = RECOVERY_WORKER_RETRY_DELAYS_MILLISECONDS[job.attemptCount - 1];
256
+ if (delay === undefined) {
257
+ await this.finishTerminal(job, reason);
258
+ return;
259
+ }
260
+ const now = this.clock.now();
261
+ const scheduled = await this.repository.scheduleRetry({
262
+ jobId: job.id,
263
+ workerId: this.workerId,
264
+ availableAt: new Date(now.getTime() + delay),
265
+ reason,
266
+ now,
267
+ });
268
+ if (!scheduled) {
269
+ logger.warn({ event: 'recovery_worker_claim_lost' }, 'Recovery worker claim was lost');
270
+ return;
271
+ }
272
+ this.emit({
273
+ event: 'retry_scheduled',
274
+ jobId: job.id,
275
+ attempt: job.attemptCount,
276
+ delayMilliseconds: delay,
277
+ reason,
278
+ });
279
+ }
280
+ /** Terminally close an owned claim without exposing raw failure data. */
281
+ async finishTerminal(job, reason) {
282
+ const finished = await this.repository.markTerminalFailure({
283
+ jobId: job.id,
284
+ workerId: this.workerId,
285
+ now: this.clock.now(),
286
+ reason,
287
+ });
288
+ if (!finished) {
289
+ logger.warn({ event: 'recovery_worker_claim_lost' }, 'Recovery worker claim was lost');
290
+ return;
291
+ }
292
+ this.emit({ event: 'terminal_failure', jobId: job.id, attempt: job.attemptCount, reason });
293
+ }
294
+ /** Notify the optional in-process observer without letting it break processing. */
295
+ emit(event) {
296
+ if (!this.observer)
297
+ return;
298
+ try {
299
+ this.observer(event);
300
+ }
301
+ catch {
302
+ logger.warn({ event: 'recovery_worker_observer_failed' }, 'Recovery worker observer failed');
303
+ }
304
+ }
305
+ }
306
+ //# sourceMappingURL=recovery-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-worker.js","sourceRoot":"","sources":["../../src/auth/recovery-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,GAOzB,MAAM,8BAA8B,CAAC;AAEtC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iCAAiC,GAAG,KAAK,CAAC;AAEvD,wEAAwE;AACxE,MAAM,CAAC,MAAM,kCAAkC,GAAG,OAAO,CAAC;AAE1D,kEAAkE;AAClE,MAAM,CAAC,MAAM,qCAAqC,GAAG,MAAM,CAAC;AAE5D,kEAAkE;AAClE,MAAM,CAAC,MAAM,yCAAyC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAEnG,kDAAkD;AAClD,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,sBAAsB;IACtB,kBAAkB;IAClB,sBAAsB;IACtB,yBAAyB;IACzB,sBAAsB;IACtB,iBAAiB;IACjB,mBAAmB;CACX,CAAC;AAmFX,6EAA6E;AAC7E,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,kCAAkC;IAClB,MAAM,CAA8B;IAEpD,mDAAmD;IACnC,SAAS,CAAU;IAEnC;;;;;OAKG;IACH,YAAmB,MAAmC,EAAE,SAAkB;QACxE,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,WAAW,GAAwB;IACvC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC;IAC1E,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC;CAC7C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IACjE,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,yDAAyD;AACzD,MAAM,OAAO,cAAc;IACzB,qCAAqC;IAClB,UAAU,CAA2B;IAExD,4CAA4C;IACzB,SAAS,CAAuB;IAEnD,wDAAwD;IACrC,QAAQ,CAAS;IAEpC,6BAA6B;IACV,KAAK,CAAsB;IAE9C,sCAAsC;IACnB,QAAQ,CAA0B;IAErD,6DAA6D;IACnD,OAAO,GAAG,KAAK,CAAC;IAE1B,mCAAmC;IACzB,KAAK,GAAyC,IAAI,CAAC;IAE7D,iDAAiD;IACvC,WAAW,GAAyB,IAAI,CAAC;IAEnD,yDAAyD;IAC/C,WAAW,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,YAAmB,OAA8B;QAC/C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,UAAU,EAAE,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,gEAAgE;IACzD,KAAK;QACV,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED,wFAAwF;IACjF,IAAI;QACT,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,IAAI;QACf,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QACpD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,GAAyC,IAAI,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACvB,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gBAC/B,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAC7B,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,qCAAqC,CACtC,CAAC;YACJ,CAAC,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,OAAO;YAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACxE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,6CAA6C;IACnC,QAAQ,CAAC,YAAoB;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE;YACtC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC,EAAE,YAAY,CAAC,CAAC;IACnB,CAAC;IAED,wCAAwC;IAC9B,kBAAkB;QAC1B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QACxB,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,kFAAkF;IACxE,UAAU;QAClB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,KAAK,KAAK;aACP,KAAK,CAAC,GAAG,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,8BAA8B,CAAC,CAAC;QAC1F,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK;gBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAO;YAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC;YACxC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACP,CAAC;IAED,2CAA2C;IACjC,KAAK,CAAC,QAAQ;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;YAChD,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG;YACH,kBAAkB,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,kCAAkC,CAAC;YAChF,KAAK,EAAE,wBAAwB;SAChC,CAAC,CAAC;QAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,gBAAgB,KAAK,iBAAiB,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC1E,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;gBAClD,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBACjD,KAAK,EAAE,GAAG,CAAC,EAAE;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,gCAAgC,CAAC,CAAC;gBACvF,SAAS;YACX,CAAC;YACD,MAAM,YAAY,GAAuB;gBACvC,GAAG,OAAO;gBACV,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;aACvC,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;YAC5F,IAAI,YAAY,CAAC,gBAAgB,KAAK,iBAAiB,EAAE,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC;oBACR,KAAK,EAAE,iBAAiB;oBACxB,KAAK,EAAE,YAAY,CAAC,EAAE;oBACtB,OAAO,EAAE,YAAY,CAAC,YAAY;iBACnC,CAAC,CAAC;YACL,CAAC;YACD,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,wBAAwB;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACxE,CAAC;IAED,mEAAmE;IACzD,KAAK,CAAC,YAAY,CAAC,GAAuB;QAClD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;gBACpD,KAAK,EAAE,GAAG,CAAC,EAAE;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,gCAAgC,CAAC,CAAC;gBACvF,OAAO;YACT,CAAC;YACD,IAAI,CAAC,IAAI,CAAC;gBACR,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;gBACjD,KAAK,EAAE,GAAG,CAAC,EAAE;gBACb,OAAO,EAAE,GAAG,CAAC,YAAY;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GACX,KAAK,YAAY,0BAA0B;gBACzC,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,0BAA0B,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;YAChE,IAAI,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,YAAY,GAAG,0BAA0B,EAAE,CAAC;gBACvE,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACtC,OAAO;YACT,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,0EAA0E;IAChE,KAAK,CAAC,KAAK,CACnB,GAAuB,EACvB,MAAmC;QAEnC,MAAM,KAAK,GAAG,yCAAyC,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QAC9E,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YACpD,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC;YAC5C,MAAM;YACN,GAAG;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,gCAAgC,CAAC,CAAC;YACvF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC;YACR,KAAK,EAAE,iBAAiB;YACxB,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,OAAO,EAAE,GAAG,CAAC,YAAY;YACzB,iBAAiB,EAAE,KAAK;YACxB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IAC/D,KAAK,CAAC,cAAc,CAC5B,GAAuB,EACvB,MAAmC;QAEnC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;YACzD,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACrB,MAAM;SACP,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,gCAAgC,CAAC,CAAC;YACvF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,mFAAmF;IACzE,IAAI,CAAC,KAA0B;QACvC,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC3B,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,EAAE,iCAAiC,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Handlebars-based page template engine for auth workflow pages.
3
+ *
4
+ * Renders server-side HTML pages using a layout + page template pattern.
5
+ * Supports per-organization template overrides:
6
+ * 1. Try: templates/{orgSlug}/pages/{pageName}.hbs
7
+ * 2. Fall back: templates/default/pages/{pageName}.hbs
8
+ *
9
+ * The engine pre-registers partials (header, footer, flash-messages) and
10
+ * compiles the base layout at startup. Page templates are compiled on
11
+ * demand and injected into the layout's {{{body}}} placeholder.
12
+ *
13
+ * @example
14
+ * await initTemplateEngine();
15
+ * const html = await renderPage('login', {
16
+ * branding: { logoUrl: null, faviconUrl: null, primaryColor: '#3B82F6', companyName: 'Acme', customCss: null },
17
+ * locale: 'en',
18
+ * t: translationFn,
19
+ * csrfToken: 'abc123',
20
+ * orgSlug: 'acme-corp',
21
+ * });
22
+ */
23
+ import type { LoginMethod } from '../clients/types.js';
24
+ /**
25
+ * Context passed to every page template and layout.
26
+ *
27
+ * Contains branding, i18n, CSRF, flash messages, and page-specific data.
28
+ * The `t` function is the i18n translation function (used by the {{t}} helper).
29
+ */
30
+ export interface TemplateContext {
31
+ /** Organization branding for visual customization */
32
+ branding: {
33
+ logoUrl: string | null;
34
+ faviconUrl: string | null;
35
+ /** CSS primary color (default: '#3B82F6') */
36
+ primaryColor: string;
37
+ /** Company name displayed in header/footer */
38
+ companyName: string;
39
+ /** Optional custom CSS injected into layout <head> */
40
+ customCss: string | null;
41
+ };
42
+ /** Current locale for the page (e.g., 'en') */
43
+ locale: string;
44
+ /** Translation function (injected into Handlebars context for {{t}} helper) */
45
+ t: (key: string, options?: Record<string, unknown>) => string;
46
+ /** OIDC interaction details (present when in an OIDC flow) */
47
+ interaction?: {
48
+ uid: string;
49
+ prompt: string;
50
+ params: Record<string, unknown>;
51
+ client: {
52
+ clientName: string;
53
+ };
54
+ };
55
+ /** Flash messages for success/error/info feedback */
56
+ flash?: {
57
+ success?: string;
58
+ error?: string;
59
+ info?: string;
60
+ };
61
+ /** CSRF token for form protection */
62
+ csrfToken: string;
63
+ /** Organization slug for route building and template overrides */
64
+ orgSlug: string;
65
+ /**
66
+ * Whether to render the password login form on the login page.
67
+ *
68
+ * Derived from `resolveLoginMethods(org, client)` — true when 'password'
69
+ * is in the effective login methods. Only set on login-page renders.
70
+ */
71
+ showPassword?: boolean;
72
+ /**
73
+ * Whether to render the magic-link button on the login page.
74
+ *
75
+ * Derived from `resolveLoginMethods(org, client)` — true when 'magic_link'
76
+ * is in the effective login methods. Only set on login-page renders.
77
+ */
78
+ showMagicLink?: boolean;
79
+ /**
80
+ * Whether to render the "or" divider between password + magic-link forms.
81
+ *
82
+ * True only when BOTH methods are enabled; the divider is omitted for
83
+ * single-method configurations to avoid an awkward one-sided divider.
84
+ */
85
+ showDivider?: boolean;
86
+ /**
87
+ * Effective login methods resolved for the current client/org.
88
+ *
89
+ * Included for template debugging and future extensibility (e.g., showing
90
+ * a method-specific header or help text). Not currently rendered in the
91
+ * default template.
92
+ */
93
+ loginMethods?: LoginMethod[];
94
+ /**
95
+ * Pre-filled email hint from the OIDC `login_hint` authorization parameter.
96
+ *
97
+ * Sanitized (trimmed + length-capped at RFC 5321 max of 320 chars) by the
98
+ * interaction handler. Templates inject this into `value="..."` of email
99
+ * inputs; Handlebars HTML-escapes by default so XSS via `login_hint` is
100
+ * blocked at the template boundary.
101
+ */
102
+ emailHint?: string;
103
+ /** Page-specific data (varies by page) */
104
+ [key: string]: unknown;
105
+ }
106
+ /**
107
+ * Initialize the Handlebars template engine.
108
+ *
109
+ * Registers all default partials (header, footer, flash-messages),
110
+ * registers custom helpers (eq, ifCond), and compiles the base layout.
111
+ * Must be called once at application startup before renderPage is used.
112
+ *
113
+ * @throws Error if layout template or required partials cannot be loaded
114
+ */
115
+ export declare function initTemplateEngine(): Promise<void>;
116
+ /**
117
+ * Render a page template with layout, branding, and i18n.
118
+ *
119
+ * Template resolution order:
120
+ * 1. templates/{orgSlug}/pages/{pageName}.hbs (org override)
121
+ * 2. templates/default/pages/{pageName}.hbs (default)
122
+ *
123
+ * The page content is rendered first, then injected into the base layout's
124
+ * {{{body}}} placeholder. Both the page and layout receive the full context,
125
+ * so they can access branding, i18n, CSRF, and page-specific data.
126
+ *
127
+ * @param pageName - Page template name (e.g., 'login', 'consent', 'error')
128
+ * @param context - Template context with branding, i18n, CSRF, flash, and page data
129
+ * @returns Rendered HTML string (complete page with layout)
130
+ * @throws Error if the template engine hasn't been initialized
131
+ * @throws Error if the page template cannot be found
132
+ */
133
+ export declare function renderPage(pageName: string, context: TemplateContext): Promise<string>;
134
+ //# sourceMappingURL=template-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../../src/auth/template-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBvD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,6CAA6C;QAC7C,YAAY,EAAE,MAAM,CAAC;QACrB,8CAA8C;QAC9C,WAAW,EAAE,MAAM,CAAC;QACpB,sDAAsD;QACtD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IAEF,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IAEf,+EAA+E;IAC/E,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;IAE9D,8DAA8D;IAC9D,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,EAAE;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC;KAChC,CAAC;IAEF,qDAAqD;IACrD,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IAEF,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAElB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAE7B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,0CAA0C;IAC1C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgBD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAexD;AA4FD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAsDjB"}