@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,318 @@
1
+ /**
2
+ * Client repository — PostgreSQL data access layer.
3
+ *
4
+ * Provides CRUD operations for the `clients` table using parameterized
5
+ * queries. Each function acquires the pool via `getPool()` and returns
6
+ * mapped Client objects.
7
+ *
8
+ * Key patterns:
9
+ * - Dynamic UPDATE query builder for partial updates
10
+ * - Paginated listing with org/app/status/search filters
11
+ * - Whitelisted sort columns to prevent SQL injection
12
+ * - All rows mapped through `mapRowToClient()`
13
+ * - Array columns (TEXT[]) handled natively by pg driver
14
+ */
15
+ import { getPool } from '../lib/database.js';
16
+ import { mapRowToClient } from './types.js';
17
+ import { decodeCursor, buildCursorResult } from '../lib/cursor.js';
18
+ /**
19
+ * Insert a new client into the database.
20
+ *
21
+ * Uses RETURNING * to get the full row back in a single round trip.
22
+ * The client_id (OIDC identifier) must be unique (enforced by DB constraint).
23
+ *
24
+ * Builds the column list dynamically so `login_methods` can be omitted —
25
+ * letting the DB `DEFAULT NULL` fire for callers that don't know about the
26
+ * column. When explicitly set (even to `null`), the value is included.
27
+ *
28
+ * @param data - Client data to insert
29
+ * @returns The newly created client
30
+ * @throws If client_id already exists (unique constraint violation)
31
+ */
32
+ export async function insertClient(data) {
33
+ const pool = getPool();
34
+ const columns = [
35
+ 'organization_id',
36
+ 'application_id',
37
+ 'client_id',
38
+ 'client_name',
39
+ 'client_type',
40
+ 'application_type',
41
+ 'redirect_uris',
42
+ 'post_logout_redirect_uris',
43
+ 'grant_types',
44
+ 'response_types',
45
+ 'scope',
46
+ 'token_endpoint_auth_method',
47
+ 'allowed_origins',
48
+ 'require_pkce',
49
+ ];
50
+ const values = [
51
+ data.organizationId,
52
+ data.applicationId,
53
+ data.clientId,
54
+ data.clientName,
55
+ data.clientType,
56
+ data.applicationType,
57
+ data.redirectUris,
58
+ data.postLogoutRedirectUris,
59
+ data.grantTypes,
60
+ data.responseTypes,
61
+ data.scope,
62
+ data.tokenEndpointAuthMethod,
63
+ data.allowedOrigins,
64
+ data.requirePkce,
65
+ ];
66
+ // Include login_methods only when the caller passed the key (including
67
+ // explicit null). Omission → DB default (NULL) fires naturally.
68
+ if (Object.prototype.hasOwnProperty.call(data, 'loginMethods')) {
69
+ columns.push('login_methods');
70
+ values.push(data.loginMethods ?? null);
71
+ }
72
+ const placeholders = values.map((_, i) => `$${i + 1}`).join(', ');
73
+ const sql = `INSERT INTO clients (${columns.join(', ')}) VALUES (${placeholders}) RETURNING *`;
74
+ const result = await pool.query(sql, values);
75
+ return mapRowToClient(result.rows[0]);
76
+ }
77
+ // ===========================================================================
78
+ // Find
79
+ // ===========================================================================
80
+ /**
81
+ * Find a client by its internal UUID.
82
+ *
83
+ * @param id - Client internal UUID
84
+ * @returns Client or null if not found
85
+ */
86
+ export async function findClientById(id) {
87
+ const pool = getPool();
88
+ const result = await pool.query('SELECT * FROM clients WHERE id = $1', [id]);
89
+ if (result.rows.length === 0)
90
+ return null;
91
+ return mapRowToClient(result.rows[0]);
92
+ }
93
+ /**
94
+ * Find a client by its OIDC client_id (public identifier).
95
+ *
96
+ * @param clientId - OIDC client_id
97
+ * @returns Client or null if not found
98
+ */
99
+ export async function findClientByClientId(clientId) {
100
+ const pool = getPool();
101
+ const result = await pool.query('SELECT * FROM clients WHERE client_id = $1', [clientId]);
102
+ if (result.rows.length === 0)
103
+ return null;
104
+ return mapRowToClient(result.rows[0]);
105
+ }
106
+ /**
107
+ * Mapping from UpdateClientData keys to database column names.
108
+ * Used by the dynamic query builder to construct SET clauses.
109
+ */
110
+ const CLIENT_FIELD_TO_COLUMN = {
111
+ clientName: 'client_name',
112
+ redirectUris: 'redirect_uris',
113
+ postLogoutRedirectUris: 'post_logout_redirect_uris',
114
+ grantTypes: 'grant_types',
115
+ responseTypes: 'response_types',
116
+ scope: 'scope',
117
+ tokenEndpointAuthMethod: 'token_endpoint_auth_method',
118
+ allowedOrigins: 'allowed_origins',
119
+ requirePkce: 'require_pkce',
120
+ status: 'status',
121
+ loginMethods: 'login_methods',
122
+ };
123
+ /**
124
+ * Update a client's fields using a dynamic SET clause.
125
+ *
126
+ * Only explicitly provided fields are included in the UPDATE statement,
127
+ * enabling partial updates. The `updated_at` column is handled by the DB
128
+ * trigger.
129
+ *
130
+ * Null-aware logic for `loginMethods`:
131
+ * - `undefined` → column omitted from SET (existing value preserved)
132
+ * - `null` → SET login_methods = NULL (clears the per-client override)
133
+ * - array → SET login_methods = <array>
134
+ *
135
+ * To distinguish these three cases, the iteration checks `hasOwnProperty`
136
+ * on the input — `undefined` keys are treated as absent, while `null` and
137
+ * arrays are both persisted.
138
+ *
139
+ * @param id - Client internal UUID
140
+ * @param data - Fields to update
141
+ * @returns Updated client
142
+ * @throws Error if client not found or no fields provided
143
+ */
144
+ export async function updateClient(id, data) {
145
+ const pool = getPool();
146
+ // Build dynamic SET clause from provided fields
147
+ const setClauses = [];
148
+ const values = [id]; // $1 is always the ID
149
+ let paramIndex = 2;
150
+ for (const [field, column] of Object.entries(CLIENT_FIELD_TO_COLUMN)) {
151
+ // For non-nullable fields, presence check via `!== undefined` works.
152
+ // For nullable fields (loginMethods), we need to persist explicit null
153
+ // too — so use hasOwnProperty to include all keys the caller passed.
154
+ const hasKey = Object.prototype.hasOwnProperty.call(data, field);
155
+ const value = data[field];
156
+ if (hasKey && value !== undefined) {
157
+ setClauses.push(`${column} = $${paramIndex}`);
158
+ values.push(value);
159
+ paramIndex++;
160
+ }
161
+ }
162
+ if (setClauses.length === 0) {
163
+ throw new Error('No fields to update');
164
+ }
165
+ const sql = `UPDATE clients SET ${setClauses.join(', ')} WHERE id = $1 RETURNING *`;
166
+ const result = await pool.query(sql, values);
167
+ if (result.rows.length === 0) {
168
+ throw new Error('Client not found');
169
+ }
170
+ return mapRowToClient(result.rows[0]);
171
+ }
172
+ // ===========================================================================
173
+ // List
174
+ // ===========================================================================
175
+ /**
176
+ * Allowed sort columns — whitelisted to prevent SQL injection.
177
+ */
178
+ const ALLOWED_SORT_COLUMNS = {
179
+ client_name: 'client_name',
180
+ created_at: 'created_at',
181
+ };
182
+ /**
183
+ * List clients with pagination, filters, and sorting.
184
+ *
185
+ * Supports filtering by organization, application, status, and search text.
186
+ * Executes two queries: COUNT for total, then data with LIMIT/OFFSET.
187
+ *
188
+ * @param options - Pagination, filter, and sort options
189
+ * @returns Paginated result with clients and metadata
190
+ */
191
+ export async function listClients(options) {
192
+ const pool = getPool();
193
+ const { page, pageSize, organizationId, applicationId, status, search, sortBy, sortOrder } = options;
194
+ // Build WHERE conditions
195
+ const conditions = [];
196
+ const params = [];
197
+ let paramIndex = 1;
198
+ if (organizationId) {
199
+ conditions.push(`organization_id = $${paramIndex}`);
200
+ params.push(organizationId);
201
+ paramIndex++;
202
+ }
203
+ if (applicationId) {
204
+ conditions.push(`application_id = $${paramIndex}`);
205
+ params.push(applicationId);
206
+ paramIndex++;
207
+ }
208
+ if (status) {
209
+ conditions.push(`status = $${paramIndex}`);
210
+ params.push(status);
211
+ paramIndex++;
212
+ }
213
+ if (search) {
214
+ conditions.push(`client_name ILIKE $${paramIndex}`);
215
+ params.push(`%${search}%`);
216
+ paramIndex++;
217
+ }
218
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
219
+ // Whitelist sort column and direction
220
+ const sortColumn = ALLOWED_SORT_COLUMNS[sortBy ?? 'created_at'] ?? 'created_at';
221
+ const direction = sortOrder === 'asc' ? 'ASC' : 'DESC';
222
+ // Count total matching rows
223
+ const countResult = await pool.query(`SELECT COUNT(*) as count FROM clients ${whereClause}`, params);
224
+ const total = parseInt(countResult.rows[0].count, 10);
225
+ // Fetch paginated data
226
+ const offset = (page - 1) * pageSize;
227
+ const dataResult = await pool.query(`SELECT * FROM clients ${whereClause} ORDER BY ${sortColumn} ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [...params, pageSize, offset]);
228
+ return {
229
+ data: dataResult.rows.map(mapRowToClient),
230
+ total,
231
+ page,
232
+ pageSize,
233
+ totalPages: Math.ceil(total / pageSize),
234
+ };
235
+ }
236
+ /**
237
+ * List clients with cursor-based keyset pagination.
238
+ *
239
+ * @param options - Cursor pagination, filter, and sort options
240
+ * @returns Cursor-paginated result with clients
241
+ */
242
+ export async function listClientsCursor(options) {
243
+ const pool = getPool();
244
+ const limit = Math.min(Math.max(1, options.limit ?? 25), 100);
245
+ const sortColumn = ALLOWED_SORT_COLUMNS[options.sortBy ?? 'created_at'] ?? 'created_at';
246
+ const direction = options.sortOrder === 'asc' ? 'ASC' : 'DESC';
247
+ const comparator = direction === 'ASC' ? '>' : '<';
248
+ const conditions = [];
249
+ const params = [];
250
+ let paramIndex = 1;
251
+ if (options.cursor) {
252
+ const decoded = decodeCursor(options.cursor);
253
+ if (decoded) {
254
+ if (decoded.s === null) {
255
+ conditions.push(`(${sortColumn} IS NOT NULL OR (${sortColumn} IS NULL AND id ${comparator} $${paramIndex}))`);
256
+ params.push(decoded.i);
257
+ paramIndex++;
258
+ }
259
+ else {
260
+ conditions.push(`(${sortColumn}, id) ${comparator} ($${paramIndex}, $${paramIndex + 1})`);
261
+ params.push(decoded.s, decoded.i);
262
+ paramIndex += 2;
263
+ }
264
+ }
265
+ }
266
+ if (options.organizationId) {
267
+ conditions.push(`organization_id = $${paramIndex}`);
268
+ params.push(options.organizationId);
269
+ paramIndex++;
270
+ }
271
+ if (options.applicationId) {
272
+ conditions.push(`application_id = $${paramIndex}`);
273
+ params.push(options.applicationId);
274
+ paramIndex++;
275
+ }
276
+ if (options.status) {
277
+ conditions.push(`status = $${paramIndex}`);
278
+ params.push(options.status);
279
+ paramIndex++;
280
+ }
281
+ if (options.search) {
282
+ conditions.push(`client_name ILIKE $${paramIndex}`);
283
+ params.push(`%${options.search}%`);
284
+ paramIndex++;
285
+ }
286
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
287
+ const sql = `SELECT * FROM clients ${whereClause} ORDER BY ${sortColumn} ${direction}, id ${direction} LIMIT $${paramIndex}`;
288
+ params.push(limit + 1);
289
+ const result = await pool.query(sql, params);
290
+ const rows = result.rows.map(mapRowToClient);
291
+ return buildCursorResult(rows, limit, (c) => sortColumn === 'client_name' ? c.clientName : c.createdAt.toISOString(), (c) => c.id);
292
+ }
293
+ // ===========================================================================
294
+ // Count helpers
295
+ // ===========================================================================
296
+ /**
297
+ * Count clients for an organization.
298
+ *
299
+ * @param organizationId - Organization UUID
300
+ * @returns Number of clients
301
+ */
302
+ export async function countClientsByOrg(organizationId) {
303
+ const pool = getPool();
304
+ const result = await pool.query('SELECT COUNT(*) as count FROM clients WHERE organization_id = $1', [organizationId]);
305
+ return parseInt(result.rows[0].count, 10);
306
+ }
307
+ /**
308
+ * Count clients for an application.
309
+ *
310
+ * @param applicationId - Application UUID
311
+ * @returns Number of clients
312
+ */
313
+ export async function countClientsByApp(applicationId) {
314
+ const pool = getPool();
315
+ const result = await pool.query('SELECT COUNT(*) as count FROM clients WHERE application_id = $1', [applicationId]);
316
+ return parseInt(result.rows[0].count, 10);
317
+ }
318
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/clients/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Login method resolution helper.
3
+ *
4
+ * Computes the effective login methods for a client by applying the
5
+ * inheritance rule: if `client.loginMethods` is `null` (or, defensively,
6
+ * an empty array), fall back to the organization's `defaultLoginMethods`.
7
+ * Otherwise, use the client's explicit override.
8
+ *
9
+ * This is the single source of truth for "which login methods apply
10
+ * here?" and is consumed by:
11
+ * - the login interaction handler (to drive template rendering)
12
+ * - the POST /login and POST /magic-link handlers (to enforce)
13
+ * - the admin API + CLI (to display the resolved value)
14
+ *
15
+ * Both functions are pure — no I/O, no side effects, deterministic. They
16
+ * live next to {@link ../clients/types.ts | LoginMethod} so consumers can
17
+ * import the type and helpers from a single barrel.
18
+ */
19
+ import type { Organization } from '../organizations/types.js';
20
+ import type { LoginMethod } from './types.js';
21
+ /**
22
+ * Minimal client shape consumed by {@link resolveLoginMethods}.
23
+ *
24
+ * Defined inline (instead of `Pick<Client, 'loginMethods'>`) so this
25
+ * helper compiles cleanly *before* the `Client` model gains the
26
+ * `loginMethods` field in Phase 4 of the implementation plan. Once the
27
+ * field is added, this shape stays a valid structural subtype of
28
+ * `Client`, so call sites continue to compile without changes.
29
+ */
30
+ export interface LoginMethodsClientView {
31
+ /**
32
+ * Per-client override:
33
+ * - `null` → inherit org defaults
34
+ * - non-empty array → use these methods exclusively
35
+ * - empty array → defensively treated as inherit (service layer
36
+ * rejects this on write, but the resolver stays safe on read)
37
+ */
38
+ loginMethods: LoginMethod[] | null;
39
+ }
40
+ /**
41
+ * Resolve the effective login methods for a client.
42
+ *
43
+ * Inheritance rule:
44
+ * - If the client has explicit methods set (non-null **and** non-empty),
45
+ * return those (the override).
46
+ * - Otherwise, return the organization's `defaultLoginMethods`.
47
+ *
48
+ * The empty-array branch is defensive: the data layer should never
49
+ * persist an empty `loginMethods` array (the service layer rejects it),
50
+ * but treating `[]` the same as `null` keeps the resolver safe in the
51
+ * face of unexpected upstream data.
52
+ *
53
+ * @param org - Organization owning the client (only `defaultLoginMethods` is read)
54
+ * @param client - Client — either with its own `loginMethods` or `null` to inherit
55
+ * @returns The effective array of login methods that apply to this client
56
+ */
57
+ export declare function resolveLoginMethods(org: Pick<Organization, 'defaultLoginMethods'>, client: LoginMethodsClientView): LoginMethod[];
58
+ /**
59
+ * Normalize a list of login-method inputs by deduplicating while
60
+ * preserving first-occurrence order.
61
+ *
62
+ * Duplicate values (e.g., `['password', 'password', 'magic_link']`) are
63
+ * collapsed to the first occurrence, yielding `['password', 'magic_link']`.
64
+ *
65
+ * Used by the service layer during create/update to sanitize incoming
66
+ * arrays before persisting. An empty input returns an empty array — the
67
+ * caller (typically the service validator) is responsible for rejecting
68
+ * empty inputs when they are invalid.
69
+ *
70
+ * @param methods - Raw input array (may contain duplicates)
71
+ * @returns De-duplicated array preserving first-occurrence order
72
+ */
73
+ export declare function normalizeLoginMethods(methods: LoginMethod[]): LoginMethod[];
74
+ //# sourceMappingURL=resolve-login-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-login-methods.d.ts","sourceRoot":"","sources":["../../src/clients/resolve-login-methods.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,qBAAqB,CAAC,EAC9C,MAAM,EAAE,sBAAsB,GAC7B,WAAW,EAAE,CAKf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAU3E"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Login method resolution helper.
3
+ *
4
+ * Computes the effective login methods for a client by applying the
5
+ * inheritance rule: if `client.loginMethods` is `null` (or, defensively,
6
+ * an empty array), fall back to the organization's `defaultLoginMethods`.
7
+ * Otherwise, use the client's explicit override.
8
+ *
9
+ * This is the single source of truth for "which login methods apply
10
+ * here?" and is consumed by:
11
+ * - the login interaction handler (to drive template rendering)
12
+ * - the POST /login and POST /magic-link handlers (to enforce)
13
+ * - the admin API + CLI (to display the resolved value)
14
+ *
15
+ * Both functions are pure — no I/O, no side effects, deterministic. They
16
+ * live next to {@link ../clients/types.ts | LoginMethod} so consumers can
17
+ * import the type and helpers from a single barrel.
18
+ */
19
+ /**
20
+ * Resolve the effective login methods for a client.
21
+ *
22
+ * Inheritance rule:
23
+ * - If the client has explicit methods set (non-null **and** non-empty),
24
+ * return those (the override).
25
+ * - Otherwise, return the organization's `defaultLoginMethods`.
26
+ *
27
+ * The empty-array branch is defensive: the data layer should never
28
+ * persist an empty `loginMethods` array (the service layer rejects it),
29
+ * but treating `[]` the same as `null` keeps the resolver safe in the
30
+ * face of unexpected upstream data.
31
+ *
32
+ * @param org - Organization owning the client (only `defaultLoginMethods` is read)
33
+ * @param client - Client — either with its own `loginMethods` or `null` to inherit
34
+ * @returns The effective array of login methods that apply to this client
35
+ */
36
+ export function resolveLoginMethods(org, client) {
37
+ if (client.loginMethods !== null && client.loginMethods.length > 0) {
38
+ return client.loginMethods;
39
+ }
40
+ return org.defaultLoginMethods;
41
+ }
42
+ /**
43
+ * Normalize a list of login-method inputs by deduplicating while
44
+ * preserving first-occurrence order.
45
+ *
46
+ * Duplicate values (e.g., `['password', 'password', 'magic_link']`) are
47
+ * collapsed to the first occurrence, yielding `['password', 'magic_link']`.
48
+ *
49
+ * Used by the service layer during create/update to sanitize incoming
50
+ * arrays before persisting. An empty input returns an empty array — the
51
+ * caller (typically the service validator) is responsible for rejecting
52
+ * empty inputs when they are invalid.
53
+ *
54
+ * @param methods - Raw input array (may contain duplicates)
55
+ * @returns De-duplicated array preserving first-occurrence order
56
+ */
57
+ export function normalizeLoginMethods(methods) {
58
+ const seen = new Set();
59
+ const result = [];
60
+ for (const m of methods) {
61
+ if (!seen.has(m)) {
62
+ seen.add(m);
63
+ result.push(m);
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+ //# sourceMappingURL=resolve-login-methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-login-methods.js","sourceRoot":"","sources":["../../src/clients/resolve-login-methods.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyBH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAA8C,EAC9C,MAA8B;IAE9B,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnE,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC,mBAAmB,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAsB;IAC1D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAC;IACpC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Secret repository — PostgreSQL data access for client_secrets table.
3
+ *
4
+ * Manages the storage of hashed client secrets. The plaintext secret
5
+ * is NEVER stored — only the Argon2id hash. The secret_hash field
6
+ * is only accessible here in the repository layer; the mapRowToClientSecret
7
+ * function intentionally excludes it from the domain model.
8
+ *
9
+ * Key operations:
10
+ * - Insert hashed secret
11
+ * - List secrets (metadata only, no hashes)
12
+ * - Find active secrets with hashes (for verification only)
13
+ * - Revoke secrets
14
+ * - Update last_used_at timestamp
15
+ * - Cleanup expired secrets
16
+ */
17
+ import type { ClientSecret } from './types.js';
18
+ /** Data required to insert a new secret */
19
+ export interface InsertSecretData {
20
+ clientId: string;
21
+ secretHash: string;
22
+ secretSha256: string | null;
23
+ label: string | null;
24
+ expiresAt: Date | null;
25
+ }
26
+ /**
27
+ * Insert a new client secret.
28
+ *
29
+ * Stores the Argon2id hash — never the plaintext.
30
+ *
31
+ * @param data - Secret data including the hash
32
+ * @returns The created secret metadata (without hash)
33
+ */
34
+ export declare function insertSecret(data: InsertSecretData): Promise<ClientSecret>;
35
+ /**
36
+ * List all secrets for a client (metadata only, no hashes).
37
+ *
38
+ * @param clientId - Client internal UUID
39
+ * @returns Array of secret metadata
40
+ */
41
+ export declare function listSecretsByClient(clientId: string): Promise<ClientSecret[]>;
42
+ /**
43
+ * Find a specific secret by ID.
44
+ *
45
+ * @param id - Secret UUID
46
+ * @returns Secret metadata or null
47
+ */
48
+ export declare function findSecretById(id: string): Promise<ClientSecret | null>;
49
+ /**
50
+ * Get active secret hashes for verification.
51
+ *
52
+ * This is the ONLY function that returns secret_hash values.
53
+ * Used exclusively by the secret service for Argon2id verification.
54
+ * Returns secrets that are active AND not expired.
55
+ *
56
+ * @param clientId - Client internal UUID
57
+ * @returns Array of {id, hash} pairs for active secrets
58
+ */
59
+ export declare function getActiveSecretHashes(clientId: string): Promise<Array<{
60
+ id: string;
61
+ hash: string;
62
+ }>>;
63
+ /**
64
+ * Revoke a secret (set status = 'revoked').
65
+ *
66
+ * This is a permanent operation — revoked secrets cannot be reactivated.
67
+ *
68
+ * @param id - Secret UUID
69
+ * @returns Updated secret metadata, or null if not found
70
+ */
71
+ export declare function revokeSecret(id: string): Promise<ClientSecret | null>;
72
+ /**
73
+ * Update the last_used_at timestamp for a secret.
74
+ *
75
+ * Called after successful secret verification to track usage.
76
+ *
77
+ * @param id - Secret UUID
78
+ */
79
+ export declare function updateLastUsedAt(id: string): Promise<void>;
80
+ /**
81
+ * Delete expired secrets that have been expired for more than the given days.
82
+ *
83
+ * Only deletes secrets where expires_at is in the past by at least `retentionDays`.
84
+ * This prevents premature deletion of recently-expired secrets that might
85
+ * still appear in audit logs.
86
+ *
87
+ * @param retentionDays - Number of days to retain expired secrets (default: 30)
88
+ * @returns Number of deleted secrets
89
+ */
90
+ export declare function cleanupExpiredSecrets(retentionDays?: number): Promise<number>;
91
+ /**
92
+ * Get the SHA-256 hash of the most recent active, non-expired secret.
93
+ *
94
+ * Used by findForOidc() to include the SHA-256 hash as client_secret
95
+ * in oidc-provider metadata. Returns null if no active secret has a
96
+ * SHA-256 hash (e.g., secrets created before migration 013).
97
+ *
98
+ * @param clientId - Client internal UUID
99
+ * @returns SHA-256 hex hash string, or null if none available
100
+ */
101
+ export declare function getLatestActiveSha256(clientId: string): Promise<string | null>;
102
+ /**
103
+ * Count active secrets for a client.
104
+ *
105
+ * @param clientId - Client internal UUID
106
+ * @returns Number of active (non-revoked, non-expired) secrets
107
+ */
108
+ export declare function countActiveSecrets(clientId: string): Promise<number>;
109
+ //# sourceMappingURL=secret-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-repository.d.ts","sourceRoot":"","sources":["../../src/clients/secret-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AAOhE,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAWhF;AAMD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASnF;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU7E;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAa9C;AAMD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU3E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAWvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBpF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY1E"}