@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,35 @@
1
+ import { z } from 'zod';
2
+ export declare const configSchema: z.ZodObject<{
3
+ nodeEnv: z.ZodDefault<z.ZodEnum<{
4
+ development: "development";
5
+ production: "production";
6
+ test: "test";
7
+ }>>;
8
+ port: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
9
+ host: z.ZodDefault<z.ZodString>;
10
+ databaseUrl: z.ZodString;
11
+ redisUrl: z.ZodString;
12
+ issuerBaseUrl: z.ZodString;
13
+ cookieKeys: z.ZodArray<z.ZodString>;
14
+ smtp: z.ZodObject<{
15
+ host: z.ZodString;
16
+ port: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
17
+ user: z.ZodOptional<z.ZodString>;
18
+ pass: z.ZodOptional<z.ZodString>;
19
+ from: z.ZodString;
20
+ }, z.core.$strip>;
21
+ logLevel: z.ZodDefault<z.ZodEnum<{
22
+ debug: "debug";
23
+ error: "error";
24
+ fatal: "fatal";
25
+ info: "info";
26
+ warn: "warn";
27
+ }>>;
28
+ trustProxy: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>, z.ZodTransform<boolean, string | boolean>>;
29
+ twoFactorEncryptionKey: z.ZodOptional<z.ZodString>;
30
+ signingKeyEncryptionKey: z.ZodString;
31
+ adminCorsOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
32
+ metricsEnabled: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>, z.ZodTransform<boolean, string | boolean>>;
33
+ }, z.core.$strip>;
34
+ export type AppConfig = z.infer<typeof configSchema>;
35
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgFxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkGvB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { z } from 'zod';
2
+ // ---------------------------------------------------------------------------
3
+ // Base schema — structural validation (types, formats, defaults).
4
+ // The superRefine below adds production-specific safety checks.
5
+ // ---------------------------------------------------------------------------
6
+ const baseSchema = z.object({
7
+ nodeEnv: z.enum(['development', 'test', 'production']).default('development'),
8
+ port: z.coerce.number().int().positive().default(3000),
9
+ host: z.string().default('0.0.0.0'),
10
+ databaseUrl: z.string().min(1, 'DATABASE_URL is required'),
11
+ redisUrl: z.string().min(1, 'REDIS_URL is required'),
12
+ issuerBaseUrl: z.string().url('ISSUER_BASE_URL must be a valid URL'),
13
+ // Cookie signing keys for OIDC sessions — array of secrets for key rotation.
14
+ // First key is used for signing; subsequent keys are used for verification only.
15
+ cookieKeys: z.array(z.string().min(16)).min(1, 'At least one COOKIE_KEY is required'),
16
+ smtp: z.object({
17
+ host: z.string().min(1, 'SMTP_HOST is required'),
18
+ port: z.coerce.number().default(587),
19
+ user: z.string().optional(),
20
+ pass: z.string().optional(),
21
+ from: z.string().min(1, 'SMTP_FROM is required'),
22
+ }),
23
+ logLevel: z.enum(['debug', 'info', 'warn', 'error', 'fatal']).default('info'),
24
+ // AES-256-GCM encryption key for TOTP secrets — must be exactly 32 hex bytes (64 chars).
25
+ // Optional in dev/test (a default is used); required in production for security.
26
+ // Trust proxy headers (X-Forwarded-Proto, X-Forwarded-For, etc.).
27
+ // Default: true — all dev/test/prod environments run behind a TLS-terminating
28
+ // reverse proxy (nginx in dev via docker-compose, nginx/Traefik/LB in prod).
29
+ // Koa reads X-Forwarded-Proto when app.proxy=true, making ctx.secure accurate.
30
+ trustProxy: z
31
+ .union([z.boolean(), z.string()])
32
+ .default(true)
33
+ .transform((val) => (typeof val === 'string' ? val === 'true' || val === '1' : val)),
34
+ twoFactorEncryptionKey: z
35
+ .string()
36
+ .length(64, 'TWO_FACTOR_ENCRYPTION_KEY must be 64 hex characters (32 bytes)')
37
+ .regex(/^[0-9a-f]+$/i, 'TWO_FACTOR_ENCRYPTION_KEY must be hex-encoded')
38
+ .optional(),
39
+ // AES-256-GCM encryption key for signing key private keys at rest.
40
+ // Must be exactly 32 hex bytes (64 characters). Always required —
41
+ // Porta will not start without it.
42
+ signingKeyEncryptionKey: z
43
+ .string()
44
+ .length(64, 'SIGNING_KEY_ENCRYPTION_KEY must be 64 hex characters (32 bytes)')
45
+ .regex(/^[0-9a-f]+$/i, 'SIGNING_KEY_ENCRYPTION_KEY must be hex-encoded'),
46
+ // Allowed origins for the admin API CORS policy.
47
+ // Empty array (default) = deny all cross-origin requests.
48
+ // Only needed when a web admin dashboard runs on a different origin.
49
+ adminCorsOrigins: z.array(z.string().url()).default([]),
50
+ // Prometheus metrics endpoint — default OFF.
51
+ // When true, GET /metrics exposes process and HTTP request counters
52
+ // in Prometheus text format. Operators must restrict access via network
53
+ // policy or reverse proxy since the endpoint is unauthenticated.
54
+ metricsEnabled: z
55
+ .union([z.boolean(), z.string()])
56
+ .default(false)
57
+ .transform((val) => (typeof val === 'string' ? val === 'true' || val === '1' : val)),
58
+ });
59
+ // ---------------------------------------------------------------------------
60
+ // Production safety rules — superRefine that only fires in production.
61
+ // Rejects well-known dev placeholders and insecure defaults so that
62
+ // deploying with .env.example values is impossible.
63
+ //
64
+ // Escape hatch: PORTA_SKIP_PROD_SAFETY=true skips these checks (incident
65
+ // response only — the config loader logs an ERROR when the hatch is used).
66
+ // ---------------------------------------------------------------------------
67
+ /** Placeholder pattern matching "change-me", "change_me", "changeme" etc. */
68
+ const PLACEHOLDER_RE = /change[-_]?me/i;
69
+ /** The .env.example 2FA placeholder — 0123456789abcdef repeated 4×. */
70
+ const TWO_FACTOR_DEV_PLACEHOLDER = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
71
+ /** The .env.example signing-key placeholder — fedcba…3210 repeated 4×. */
72
+ const SIGNING_KEY_DEV_PLACEHOLDER = 'fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210';
73
+ export const configSchema = baseSchema.superRefine((data, ctx) => {
74
+ // Only enforce in production
75
+ if (data.nodeEnv !== 'production')
76
+ return;
77
+ // Escape hatch for incident response — caller logs a loud error
78
+ if (process.env.PORTA_SKIP_PROD_SAFETY === 'true')
79
+ return;
80
+ // ── R1 + R2: Cookie key strength ──────────────────────────────────
81
+ data.cookieKeys.forEach((key, i) => {
82
+ if (PLACEHOLDER_RE.test(key)) {
83
+ ctx.addIssue({
84
+ code: 'custom',
85
+ path: ['cookieKeys', i],
86
+ message: 'COOKIE_KEYS contains a dev placeholder ("change-me" pattern); ' +
87
+ 'generate with `openssl rand -base64 32`',
88
+ });
89
+ }
90
+ if (key.length < 32) {
91
+ ctx.addIssue({
92
+ code: 'custom',
93
+ path: ['cookieKeys', i],
94
+ message: `COOKIE_KEYS[${i}] is shorter than 32 chars; production requires >= 32 chars of entropy`,
95
+ });
96
+ }
97
+ });
98
+ // ── R3 + R4: 2FA encryption key ──────────────────────────────────
99
+ // Any org that ever enables 2FA needs this key to decrypt existing
100
+ // TOTP secrets, so it is unconditionally required in production.
101
+ const tfe = data.twoFactorEncryptionKey;
102
+ if (!tfe) {
103
+ ctx.addIssue({
104
+ code: 'custom',
105
+ path: ['twoFactorEncryptionKey'],
106
+ message: 'TWO_FACTOR_ENCRYPTION_KEY is required in production',
107
+ });
108
+ }
109
+ else if (tfe === TWO_FACTOR_DEV_PLACEHOLDER) {
110
+ ctx.addIssue({
111
+ code: 'custom',
112
+ path: ['twoFactorEncryptionKey'],
113
+ message: 'TWO_FACTOR_ENCRYPTION_KEY still set to the dev placeholder',
114
+ });
115
+ }
116
+ // ── R5: Signing key encryption key placeholder ────────────────────
117
+ if (data.signingKeyEncryptionKey === SIGNING_KEY_DEV_PLACEHOLDER) {
118
+ ctx.addIssue({
119
+ code: 'custom',
120
+ path: ['signingKeyEncryptionKey'],
121
+ message: 'SIGNING_KEY_ENCRYPTION_KEY still set to the dev placeholder',
122
+ });
123
+ }
124
+ // ── R6: Database dev password ─────────────────────────────────────
125
+ if (/:porta_dev@/.test(data.databaseUrl)) {
126
+ ctx.addIssue({
127
+ code: 'custom',
128
+ path: ['databaseUrl'],
129
+ message: 'DATABASE_URL still contains the dev password "porta_dev"',
130
+ });
131
+ }
132
+ // ── R7: Issuer must use HTTPS in production (unless localhost) ────
133
+ if (/^http:\/\//.test(data.issuerBaseUrl)) {
134
+ try {
135
+ const url = new URL(data.issuerBaseUrl);
136
+ const localHosts = ['localhost', '127.0.0.1', '::1'];
137
+ if (!localHosts.includes(url.hostname)) {
138
+ ctx.addIssue({
139
+ code: 'custom',
140
+ path: ['issuerBaseUrl'],
141
+ message: 'ISSUER_BASE_URL must use HTTPS in production',
142
+ });
143
+ }
144
+ }
145
+ catch {
146
+ // URL parse failure — already caught by the .url() validator above
147
+ }
148
+ }
149
+ // ── R8: Log level too verbose ─────────────────────────────────────
150
+ if (data.logLevel === 'debug') {
151
+ ctx.addIssue({
152
+ code: 'custom',
153
+ path: ['logLevel'],
154
+ message: `LOG_LEVEL=${data.logLevel} is too verbose for production; use info, warn, or error`,
155
+ });
156
+ }
157
+ // ── R9: SMTP pointing at dev inbox ────────────────────────────────
158
+ const smtpHost = data.smtp.host;
159
+ if (smtpHost === 'localhost' || /^127\./.test(smtpHost)) {
160
+ ctx.addIssue({
161
+ code: 'custom',
162
+ path: ['smtp', 'host'],
163
+ message: 'SMTP_HOST points at a dev inbox (MailHog); configure a real SMTP relay for production',
164
+ });
165
+ }
166
+ });
167
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Custom claims cache — Redis-backed fast lookup layer.
3
+ *
4
+ * Caches claim definitions per application to reduce database queries
5
+ * during admin views and list operations. Claim values are NOT cached
6
+ * because they have high cardinality (per-user × per-claim) and the
7
+ * DB query with JOIN is already efficient for the token issuance path.
8
+ *
9
+ * Key format: `claims:defs:{applicationId}`
10
+ * TTL: 5 minutes (balance between freshness and performance)
11
+ *
12
+ * All Redis errors are caught and logged — cache failures never propagate
13
+ * to callers. The system gracefully degrades to direct database lookups
14
+ * when Redis is unavailable.
15
+ *
16
+ * Invalidation triggers:
17
+ * - Definition created/updated/deleted → invalidateDefinitionsCache()
18
+ */
19
+ import type { CustomClaimDefinition } from './types.js';
20
+ /**
21
+ * Get cached claim definitions for an application.
22
+ *
23
+ * Returns null on cache miss, invalid JSON, or Redis error.
24
+ * Callers should fall back to the database on null.
25
+ *
26
+ * @param applicationId - Application UUID
27
+ * @returns Cached definitions array or null on miss
28
+ */
29
+ export declare function getCachedDefinitions(applicationId: string): Promise<CustomClaimDefinition[] | null>;
30
+ /**
31
+ * Cache claim definitions for an application.
32
+ *
33
+ * Stores the definitions array as JSON with a 5-minute TTL.
34
+ * Date fields are serialized to ISO 8601 strings automatically.
35
+ *
36
+ * @param applicationId - Application UUID
37
+ * @param definitions - Array of definitions to cache
38
+ */
39
+ export declare function setCachedDefinitions(applicationId: string, definitions: CustomClaimDefinition[]): Promise<void>;
40
+ /**
41
+ * Invalidate cached claim definitions for an application.
42
+ *
43
+ * Should be called after any definition create, update, or delete.
44
+ *
45
+ * @param applicationId - Application UUID
46
+ */
47
+ export declare function invalidateDefinitionsCache(applicationId: string): Promise<void>;
48
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/custom-claims/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgBxD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,CAWzC;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,qBAAqB,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrF"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Custom claims cache — Redis-backed fast lookup layer.
3
+ *
4
+ * Caches claim definitions per application to reduce database queries
5
+ * during admin views and list operations. Claim values are NOT cached
6
+ * because they have high cardinality (per-user × per-claim) and the
7
+ * DB query with JOIN is already efficient for the token issuance path.
8
+ *
9
+ * Key format: `claims:defs:{applicationId}`
10
+ * TTL: 5 minutes (balance between freshness and performance)
11
+ *
12
+ * All Redis errors are caught and logged — cache failures never propagate
13
+ * to callers. The system gracefully degrades to direct database lookups
14
+ * when Redis is unavailable.
15
+ *
16
+ * Invalidation triggers:
17
+ * - Definition created/updated/deleted → invalidateDefinitionsCache()
18
+ */
19
+ import { getRedis } from '../lib/redis.js';
20
+ import { logger } from '../lib/logger.js';
21
+ import { afterDatabaseCommit } from '../lib/database.js';
22
+ // ---------------------------------------------------------------------------
23
+ // Constants
24
+ // ---------------------------------------------------------------------------
25
+ /** Cache TTL in seconds (5 minutes) */
26
+ const CACHE_TTL = 300;
27
+ /** Key prefix for claim definitions by application ID */
28
+ const DEFINITIONS_PREFIX = 'claims:defs:';
29
+ // ---------------------------------------------------------------------------
30
+ // Get / Set / Invalidate
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * Get cached claim definitions for an application.
34
+ *
35
+ * Returns null on cache miss, invalid JSON, or Redis error.
36
+ * Callers should fall back to the database on null.
37
+ *
38
+ * @param applicationId - Application UUID
39
+ * @returns Cached definitions array or null on miss
40
+ */
41
+ export async function getCachedDefinitions(applicationId) {
42
+ try {
43
+ const redis = getRedis();
44
+ const data = await redis.get(`${DEFINITIONS_PREFIX}${applicationId}`);
45
+ if (!data)
46
+ return null;
47
+ return deserializeDefinitions(data);
48
+ }
49
+ catch {
50
+ // Graceful degradation — log and return null so caller falls back to DB
51
+ logger.warn({ event: 'claim-cache-read-failed' }, 'Claim cache read failed');
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Cache claim definitions for an application.
57
+ *
58
+ * Stores the definitions array as JSON with a 5-minute TTL.
59
+ * Date fields are serialized to ISO 8601 strings automatically.
60
+ *
61
+ * @param applicationId - Application UUID
62
+ * @param definitions - Array of definitions to cache
63
+ */
64
+ export async function setCachedDefinitions(applicationId, definitions) {
65
+ await afterDatabaseCommit(async () => {
66
+ try {
67
+ const redis = getRedis();
68
+ await redis.set(`${DEFINITIONS_PREFIX}${applicationId}`, JSON.stringify(definitions), 'EX', CACHE_TTL);
69
+ }
70
+ catch {
71
+ // Graceful degradation — cache write failure is non-fatal
72
+ logger.warn({ event: 'claim-cache-write-failed' }, 'Claim cache write failed');
73
+ }
74
+ });
75
+ }
76
+ /**
77
+ * Invalidate cached claim definitions for an application.
78
+ *
79
+ * Should be called after any definition create, update, or delete.
80
+ *
81
+ * @param applicationId - Application UUID
82
+ */
83
+ export async function invalidateDefinitionsCache(applicationId) {
84
+ await afterDatabaseCommit(async () => {
85
+ try {
86
+ const redis = getRedis();
87
+ await redis.del(`${DEFINITIONS_PREFIX}${applicationId}`);
88
+ }
89
+ catch {
90
+ // Graceful degradation — cache invalidation failure is non-fatal
91
+ logger.warn({ event: 'claim-cache-invalidation-failed' }, 'Claim cache invalidation failed');
92
+ }
93
+ });
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Serialization helpers
97
+ // ---------------------------------------------------------------------------
98
+ /**
99
+ * Deserialize a JSON string from Redis into a CustomClaimDefinition array.
100
+ *
101
+ * Converts ISO 8601 date strings back to Date objects for the
102
+ * createdAt and updatedAt fields on each definition.
103
+ *
104
+ * @param data - JSON string from Redis
105
+ * @returns Array of definition objects with proper Date instances, or null if parse fails
106
+ */
107
+ function deserializeDefinitions(data) {
108
+ try {
109
+ const parsed = JSON.parse(data);
110
+ // Restore Date objects from ISO string serialization
111
+ for (const def of parsed) {
112
+ def.createdAt = new Date(def.createdAt);
113
+ def.updatedAt = new Date(def.updatedAt);
114
+ }
115
+ return parsed;
116
+ }
117
+ catch {
118
+ logger.warn('Failed to parse cached claim definitions JSON');
119
+ return null;
120
+ }
121
+ }
122
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/custom-claims/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Custom claims domain error types.
3
+ *
4
+ * Custom error classes for claim-specific business rule violations.
5
+ * API routes map these to appropriate HTTP status codes:
6
+ * - ClaimNotFoundError → 404
7
+ * - ClaimValidationError → 400
8
+ */
9
+ /**
10
+ * Thrown when a claim definition or value cannot be found.
11
+ * Maps to HTTP 404 in route handlers.
12
+ */
13
+ export declare class ClaimNotFoundError extends Error {
14
+ constructor(identifier: string);
15
+ }
16
+ /**
17
+ * Thrown when custom claim validation fails.
18
+ * Examples: reserved claim name, invalid claim name format, duplicate
19
+ * name within application, value type mismatch.
20
+ * Maps to HTTP 400 in route handlers.
21
+ */
22
+ export declare class ClaimValidationError extends Error {
23
+ constructor(message: string);
24
+ }
25
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/custom-claims/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,UAAU,EAAE,MAAM,EAG7B;CACF;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Custom claims domain error types.
3
+ *
4
+ * Custom error classes for claim-specific business rule violations.
5
+ * API routes map these to appropriate HTTP status codes:
6
+ * - ClaimNotFoundError → 404
7
+ * - ClaimValidationError → 400
8
+ */
9
+ /**
10
+ * Thrown when a claim definition or value cannot be found.
11
+ * Maps to HTTP 404 in route handlers.
12
+ */
13
+ export class ClaimNotFoundError extends Error {
14
+ constructor(identifier) {
15
+ super(`Custom claim not found: ${identifier}`);
16
+ this.name = 'ClaimNotFoundError';
17
+ }
18
+ }
19
+ /**
20
+ * Thrown when custom claim validation fails.
21
+ * Examples: reserved claim name, invalid claim name format, duplicate
22
+ * name within application, value type mismatch.
23
+ * Maps to HTTP 400 in route handlers.
24
+ */
25
+ export class ClaimValidationError extends Error {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = 'ClaimValidationError';
29
+ }
30
+ }
31
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/custom-claims/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,UAAkB;QAC5B,KAAK,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Custom claims module — public API barrel export.
3
+ *
4
+ * Re-exports the types, error classes, validators, and service
5
+ * functions that other modules need. Internal implementation details
6
+ * (repository, cache) are NOT exported — they are consumed only by
7
+ * the service layer.
8
+ */
9
+ export type { ClaimType, TokenType, CustomClaimDefinition, CustomClaimValue, CreateClaimDefinitionInput, UpdateClaimDefinitionInput, CustomClaimWithValue, } from './types.js';
10
+ export { mapRowToDefinition, mapRowToValue, } from './types.js';
11
+ export { ClaimNotFoundError, ClaimValidationError } from './errors.js';
12
+ export { RESERVED_CLAIM_NAMES, isReservedClaimName, validateClaimName, validateClaimValue, } from './validators.js';
13
+ export { createDefinition, updateDefinition, deleteDefinition, findDefinitionById, listDefinitions, setValue, getValue, deleteValue, getValuesForUser, buildCustomClaims, } from './service.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/custom-claims/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,SAAS,EACT,SAAS,EACT,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGvE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Custom claims module — public API barrel export.
3
+ *
4
+ * Re-exports the types, error classes, validators, and service
5
+ * functions that other modules need. Internal implementation details
6
+ * (repository, cache) are NOT exported — they are consumed only by
7
+ * the service layer.
8
+ */
9
+ // Row mappers
10
+ export { mapRowToDefinition, mapRowToValue, } from './types.js';
11
+ // Errors
12
+ export { ClaimNotFoundError, ClaimValidationError } from './errors.js';
13
+ // Validators
14
+ export { RESERVED_CLAIM_NAMES, isReservedClaimName, validateClaimName, validateClaimValue, } from './validators.js';
15
+ // Service (public API)
16
+ export { createDefinition, updateDefinition, deleteDefinition, findDefinitionById, listDefinitions, setValue, getValue, deleteValue, getValuesForUser, buildCustomClaims, } from './service.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/custom-claims/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,cAAc;AACd,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEvE,aAAa;AACb,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Custom claims repository — PostgreSQL data access layer.
3
+ *
4
+ * Provides CRUD operations for the `custom_claim_definitions` and
5
+ * `custom_claim_values` tables using parameterized queries. Each function
6
+ * acquires the pool via `getPool()` and returns mapped objects via the
7
+ * type mapping functions.
8
+ *
9
+ * Definitions are scoped to an application with a unique (application_id,
10
+ * claim_name) constraint. Values are per-user with a unique (user_id,
11
+ * claim_id) constraint — upsert semantics via ON CONFLICT.
12
+ *
13
+ * Key patterns:
14
+ * - Dynamic UPDATE for partial definition updates
15
+ * - Upsert for claim values (INSERT ... ON CONFLICT DO UPDATE)
16
+ * - Joined query for resolving user claim values with definitions
17
+ *
18
+ * Database tables: custom_claim_definitions, custom_claim_values
19
+ * (see migration 007_custom_claims.sql)
20
+ */
21
+ import type { CustomClaimDefinition, CreateClaimDefinitionInput, UpdateClaimDefinitionInput, CustomClaimValue, CustomClaimWithValue } from './types.js';
22
+ /**
23
+ * Insert a new claim definition into the database.
24
+ *
25
+ * Uses RETURNING * to get the full row back in a single round trip.
26
+ * The (application_id, claim_name) pair must be unique (enforced by DB).
27
+ * Token inclusion flags use DB defaults when not provided.
28
+ *
29
+ * @param input - Definition data to insert
30
+ * @returns The newly created definition
31
+ * @throws If (application_id, claim_name) already exists (unique constraint)
32
+ */
33
+ export declare function insertDefinition(input: CreateClaimDefinitionInput): Promise<CustomClaimDefinition>;
34
+ /**
35
+ * Find a claim definition by its UUID.
36
+ *
37
+ * @param id - Definition UUID
38
+ * @returns Definition or null if not found
39
+ */
40
+ export declare function findDefinitionById(id: string): Promise<CustomClaimDefinition | null>;
41
+ /**
42
+ * Find a claim definition by application ID and claim name.
43
+ *
44
+ * Used for duplicate checking and name-based lookups.
45
+ *
46
+ * @param applicationId - Application UUID
47
+ * @param claimName - Claim name (unique within application)
48
+ * @returns Definition or null if not found
49
+ */
50
+ export declare function findDefinitionByName(applicationId: string, claimName: string): Promise<CustomClaimDefinition | null>;
51
+ /**
52
+ * Update a claim definition's fields using a dynamic SET clause.
53
+ *
54
+ * Only explicitly provided fields (not undefined) are included in the
55
+ * UPDATE statement. This allows partial updates without overwriting
56
+ * fields that weren't specified. Null is a valid value for description
57
+ * (clears it).
58
+ *
59
+ * @param id - Definition UUID
60
+ * @param input - Fields to update (only non-undefined fields are applied)
61
+ * @returns Updated definition
62
+ * @throws Error if definition not found or no fields provided
63
+ */
64
+ export declare function updateDefinition(id: string, input: UpdateClaimDefinitionInput): Promise<CustomClaimDefinition>;
65
+ /**
66
+ * Delete a claim definition by ID.
67
+ *
68
+ * CASCADE constraint automatically removes all associated claim values.
69
+ *
70
+ * @param id - Definition UUID
71
+ * @returns true if deleted, false if not found
72
+ */
73
+ export declare function deleteDefinition(id: string): Promise<boolean>;
74
+ /**
75
+ * List all claim definitions for an application, ordered by claim name.
76
+ *
77
+ * Returns a simple array (no pagination) since applications typically
78
+ * have a manageable number of custom claims.
79
+ *
80
+ * @param applicationId - Application UUID
81
+ * @returns Array of definitions for the application
82
+ */
83
+ export declare function listDefinitionsByApplication(applicationId: string): Promise<CustomClaimDefinition[]>;
84
+ /**
85
+ * Check if a claim name already exists for a given application.
86
+ *
87
+ * Used for uniqueness validation before insert. The optional excludeId
88
+ * parameter allows excluding a specific definition (for future use if
89
+ * name updates are ever supported).
90
+ *
91
+ * @param applicationId - Application UUID
92
+ * @param claimName - Claim name to check
93
+ * @param excludeId - Optional definition ID to exclude from the check
94
+ * @returns true if the claim name already exists
95
+ */
96
+ export declare function claimNameExists(applicationId: string, claimName: string, excludeId?: string): Promise<boolean>;
97
+ /**
98
+ * Set (upsert) a claim value for a user.
99
+ *
100
+ * Uses INSERT ... ON CONFLICT (user_id, claim_id) DO UPDATE to handle
101
+ * both initial value setting and subsequent updates in a single query.
102
+ * The value is stored as JSONB.
103
+ *
104
+ * @param userId - User UUID
105
+ * @param claimId - Definition UUID
106
+ * @param value - The claim value (must match definition's claim_type)
107
+ * @returns The upserted claim value
108
+ */
109
+ export declare function upsertValue(userId: string, claimId: string, value: unknown): Promise<CustomClaimValue>;
110
+ /**
111
+ * Get a claim value for a user and claim definition.
112
+ *
113
+ * @param userId - User UUID
114
+ * @param claimId - Definition UUID
115
+ * @returns Claim value or null if not set
116
+ */
117
+ export declare function findValue(userId: string, claimId: string): Promise<CustomClaimValue | null>;
118
+ /**
119
+ * Delete a claim value for a user and claim definition.
120
+ *
121
+ * @param userId - User UUID
122
+ * @param claimId - Definition UUID
123
+ * @returns true if deleted, false if not found
124
+ */
125
+ export declare function deleteValue(userId: string, claimId: string): Promise<boolean>;
126
+ /**
127
+ * Get all claim values for a user, joined with definitions.
128
+ *
129
+ * Returns values across all applications. Used for admin views.
130
+ *
131
+ * @param userId - User UUID
132
+ * @returns Array of definition+value pairs
133
+ */
134
+ export declare function getValuesForUser(userId: string): Promise<CustomClaimWithValue[]>;
135
+ /**
136
+ * Get all claim values for a user within a specific application.
137
+ *
138
+ * This is the token claims hot path — scoped to the client's application.
139
+ * Returns joined definition+value pairs so the caller can filter by
140
+ * token type inclusion flags.
141
+ *
142
+ * @param userId - User UUID
143
+ * @param applicationId - Application UUID
144
+ * @returns Array of definition+value pairs for the application
145
+ */
146
+ export declare function getValuesForUserByApp(userId: string, applicationId: string): Promise<CustomClaimWithValue[]>;
147
+ //# sourceMappingURL=repository.d.ts.map