@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,388 @@
1
+ /**
2
+ * Application service — business logic orchestrator.
3
+ *
4
+ * Composes the repository, cache, slug utilities, and audit log
5
+ * to provide the complete application management API. All write
6
+ * operations follow the pattern:
7
+ * 1. Validate inputs
8
+ * 2. Perform DB operation (via repository)
9
+ * 3. Invalidate + re-cache (via cache)
10
+ * 4. Write audit log (fire-and-forget)
11
+ *
12
+ * Read operations check cache first, fall back to DB on miss.
13
+ *
14
+ * Status lifecycle rules (different from organizations):
15
+ * - deactivate: active → inactive
16
+ * - activate: inactive → active
17
+ * - archive: active|inactive → archived (permanent, cannot be restored)
18
+ *
19
+ * Module management:
20
+ * - Modules belong to an application (parent must exist)
21
+ * - Module slugs are unique within their parent application
22
+ * - Module deactivation sets status to inactive
23
+ */
24
+ import { insertApplication, findApplicationById, findApplicationBySlug, updateApplication as repoUpdateApp, listApplications as repoListApps, listApplicationsCursor as repoListAppsCursor, slugExists, insertModule, findModuleById, updateModule as repoUpdateModule, listModules as repoListModules, moduleSlugExists, } from './repository.js';
25
+ import { getCachedApplicationById, getCachedApplicationBySlug, cacheApplication, invalidateApplicationCache, } from './cache.js';
26
+ import { generateSlug, validateSlug } from './slugs.js';
27
+ import { writeAuditLog } from '../lib/audit-log.js';
28
+ import { ApplicationNotFoundError, ApplicationValidationError } from './errors.js';
29
+ // ===========================================================================
30
+ // Application CRUD
31
+ // ===========================================================================
32
+ // ---------------------------------------------------------------------------
33
+ // Create
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Create a new application.
37
+ *
38
+ * 1. Generate slug from name if not provided
39
+ * 2. Validate slug format and reserved words
40
+ * 3. Check slug uniqueness in the database
41
+ * 4. Insert application via repository
42
+ * 5. Cache the new application
43
+ * 6. Write audit log entry
44
+ *
45
+ * @param input - Application creation data
46
+ * @param actorId - UUID of the user performing the action (for audit)
47
+ * @returns Created application
48
+ * @throws ApplicationValidationError if slug is invalid or already taken
49
+ */
50
+ export async function createApplication(input, actorId) {
51
+ // Generate or use provided slug
52
+ const slug = input.slug ?? generateSlug(input.name);
53
+ // Validate slug format and reserved words
54
+ const validation = validateSlug(slug);
55
+ if (!validation.isValid) {
56
+ throw new ApplicationValidationError(validation.error);
57
+ }
58
+ // Check uniqueness
59
+ const taken = await slugExists(slug);
60
+ if (taken) {
61
+ throw new ApplicationValidationError('Slug already in use');
62
+ }
63
+ // Insert into database
64
+ const app = await insertApplication({
65
+ name: input.name,
66
+ slug,
67
+ description: input.description,
68
+ });
69
+ // Cache the new application
70
+ await cacheApplication(app);
71
+ // Audit log (fire-and-forget)
72
+ await writeAuditLog({
73
+ eventType: 'app.created',
74
+ eventCategory: 'admin',
75
+ actorId,
76
+ metadata: { applicationId: app.id, slug: app.slug, name: app.name },
77
+ });
78
+ return app;
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Read
82
+ // ---------------------------------------------------------------------------
83
+ /**
84
+ * Find an application by ID.
85
+ * Checks Redis cache first, falls back to database on miss.
86
+ *
87
+ * @param id - Application UUID
88
+ * @returns Application or null if not found
89
+ */
90
+ export async function getApplicationById(id) {
91
+ // Try cache first
92
+ const cached = await getCachedApplicationById(id);
93
+ if (cached)
94
+ return cached;
95
+ // Fall back to database
96
+ const app = await findApplicationById(id);
97
+ if (app) {
98
+ await cacheApplication(app);
99
+ }
100
+ return app;
101
+ }
102
+ /**
103
+ * Find an application by slug.
104
+ * Checks Redis cache first, falls back to database on miss.
105
+ *
106
+ * @param slug - Application slug
107
+ * @returns Application or null if not found
108
+ */
109
+ export async function getApplicationBySlug(slug) {
110
+ // Try cache first
111
+ const cached = await getCachedApplicationBySlug(slug);
112
+ if (cached)
113
+ return cached;
114
+ // Fall back to database
115
+ const app = await findApplicationBySlug(slug);
116
+ if (app) {
117
+ await cacheApplication(app);
118
+ }
119
+ return app;
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Update
123
+ // ---------------------------------------------------------------------------
124
+ /**
125
+ * Update an application's basic fields (name, description).
126
+ *
127
+ * @param id - Application UUID
128
+ * @param input - Fields to update
129
+ * @param actorId - UUID of the user performing the action
130
+ * @returns Updated application
131
+ * @throws ApplicationNotFoundError if application not found
132
+ */
133
+ export async function updateApplication(id, input, actorId) {
134
+ // Build update data from input
135
+ const updateData = {};
136
+ if (input.name !== undefined)
137
+ updateData.name = input.name;
138
+ if (input.description !== undefined)
139
+ updateData.description = input.description;
140
+ let app;
141
+ try {
142
+ app = await repoUpdateApp(id, updateData);
143
+ }
144
+ catch (err) {
145
+ if (err instanceof Error && err.message === 'Application not found') {
146
+ throw new ApplicationNotFoundError(id);
147
+ }
148
+ throw err;
149
+ }
150
+ // Invalidate old cache and re-cache the updated version
151
+ await invalidateApplicationCache(app.slug, app.id);
152
+ await cacheApplication(app);
153
+ // Audit log (fire-and-forget)
154
+ await writeAuditLog({
155
+ eventType: 'app.updated',
156
+ eventCategory: 'admin',
157
+ actorId,
158
+ metadata: { applicationId: app.id, fields: Object.keys(updateData) },
159
+ });
160
+ return app;
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // List
164
+ // ---------------------------------------------------------------------------
165
+ /**
166
+ * List applications with pagination and filtering.
167
+ * Delegates directly to the repository.
168
+ *
169
+ * @param options - Pagination, filter, and sort options
170
+ * @returns Paginated result
171
+ */
172
+ export async function listApplications(options) {
173
+ return repoListApps(options);
174
+ }
175
+ /**
176
+ * List applications with cursor-based keyset pagination.
177
+ * Provides stable, efficient pagination without COUNT queries.
178
+ *
179
+ * @param options - Cursor, limit, filter, and sort options
180
+ * @returns Cursor-paginated result with nextCursor/hasMore
181
+ */
182
+ export async function listApplicationsCursor(options) {
183
+ return repoListAppsCursor(options);
184
+ }
185
+ // ===========================================================================
186
+ // Status lifecycle
187
+ // ===========================================================================
188
+ /**
189
+ * Load and validate an application exists before a status change.
190
+ * @throws ApplicationNotFoundError if not found
191
+ */
192
+ async function loadAppForStatusChange(id) {
193
+ const app = await findApplicationById(id);
194
+ if (!app)
195
+ throw new ApplicationNotFoundError(id);
196
+ return app;
197
+ }
198
+ /**
199
+ * Deactivate an application (active → inactive).
200
+ *
201
+ * @param id - Application UUID
202
+ * @param actorId - UUID of the user performing the action
203
+ * @throws ApplicationNotFoundError if not found
204
+ * @throws ApplicationValidationError if not currently active
205
+ */
206
+ export async function deactivateApplication(id, actorId) {
207
+ const app = await loadAppForStatusChange(id);
208
+ if (app.status !== 'active') {
209
+ throw new ApplicationValidationError(`Cannot deactivate application from status: ${app.status}`);
210
+ }
211
+ await repoUpdateApp(id, { status: 'inactive' });
212
+ await invalidateApplicationCache(app.slug, app.id);
213
+ await writeAuditLog({
214
+ eventType: 'app.deactivated',
215
+ eventCategory: 'admin',
216
+ actorId,
217
+ metadata: { applicationId: app.id },
218
+ });
219
+ }
220
+ /**
221
+ * Activate an application (inactive → active).
222
+ *
223
+ * @param id - Application UUID
224
+ * @param actorId - UUID of the user performing the action
225
+ * @throws ApplicationNotFoundError if not found
226
+ * @throws ApplicationValidationError if not currently inactive
227
+ */
228
+ export async function activateApplication(id, actorId) {
229
+ const app = await loadAppForStatusChange(id);
230
+ if (app.status !== 'inactive') {
231
+ throw new ApplicationValidationError(`Cannot activate application from status: ${app.status}`);
232
+ }
233
+ await repoUpdateApp(id, { status: 'active' });
234
+ await invalidateApplicationCache(app.slug, app.id);
235
+ await writeAuditLog({
236
+ eventType: 'app.activated',
237
+ eventCategory: 'admin',
238
+ actorId,
239
+ metadata: { applicationId: app.id },
240
+ });
241
+ }
242
+ /**
243
+ * Archive an application (active or inactive → archived).
244
+ *
245
+ * Archive is a permanent soft-delete — archived applications cannot
246
+ * be restored (unlike organizations which support restore).
247
+ *
248
+ * @param id - Application UUID
249
+ * @param actorId - UUID of the user performing the action
250
+ * @throws ApplicationNotFoundError if not found
251
+ * @throws ApplicationValidationError if already archived
252
+ */
253
+ export async function archiveApplication(id, actorId) {
254
+ const app = await loadAppForStatusChange(id);
255
+ if (app.status === 'archived') {
256
+ throw new ApplicationValidationError('Application is already archived');
257
+ }
258
+ await repoUpdateApp(id, { status: 'archived' });
259
+ await invalidateApplicationCache(app.slug, app.id);
260
+ await writeAuditLog({
261
+ eventType: 'app.archived',
262
+ eventCategory: 'admin',
263
+ actorId,
264
+ metadata: { applicationId: app.id, previousStatus: app.status },
265
+ });
266
+ }
267
+ // ===========================================================================
268
+ // Module management
269
+ // ===========================================================================
270
+ /**
271
+ * Create a new module within an application.
272
+ *
273
+ * 1. Validate the parent application exists
274
+ * 2. Generate slug from name if not provided
275
+ * 3. Validate slug format
276
+ * 4. Check module slug uniqueness within the application
277
+ * 5. Insert module via repository
278
+ * 6. Write audit log entry
279
+ *
280
+ * @param applicationId - Parent application UUID
281
+ * @param input - Module creation data
282
+ * @param actorId - UUID of the user performing the action
283
+ * @returns Created module
284
+ * @throws ApplicationNotFoundError if parent application not found
285
+ * @throws ApplicationValidationError if slug is invalid or taken within app
286
+ */
287
+ export async function createModule(applicationId, input, actorId) {
288
+ // Validate parent application exists
289
+ const app = await findApplicationById(applicationId);
290
+ if (!app)
291
+ throw new ApplicationNotFoundError(applicationId);
292
+ // Generate or use provided slug
293
+ const slug = input.slug ?? generateSlug(input.name);
294
+ // Validate slug format and reserved words
295
+ const validation = validateSlug(slug);
296
+ if (!validation.isValid) {
297
+ throw new ApplicationValidationError(validation.error);
298
+ }
299
+ // Check uniqueness within the application
300
+ const taken = await moduleSlugExists(applicationId, slug);
301
+ if (taken) {
302
+ throw new ApplicationValidationError('Module slug already in use within this application');
303
+ }
304
+ // Insert into database
305
+ const mod = await insertModule({
306
+ applicationId,
307
+ name: input.name,
308
+ slug,
309
+ description: input.description,
310
+ });
311
+ // Audit log (fire-and-forget)
312
+ await writeAuditLog({
313
+ eventType: 'app.module.created',
314
+ eventCategory: 'admin',
315
+ actorId,
316
+ metadata: { applicationId, moduleId: mod.id, slug: mod.slug, name: mod.name },
317
+ });
318
+ return mod;
319
+ }
320
+ /**
321
+ * Update a module's basic fields (name, description).
322
+ *
323
+ * @param moduleId - Module UUID
324
+ * @param input - Fields to update
325
+ * @param actorId - UUID of the user performing the action
326
+ * @returns Updated module
327
+ * @throws ApplicationNotFoundError if module not found
328
+ */
329
+ export async function updateModule(moduleId, input, actorId) {
330
+ // Build update data from input
331
+ const updateData = {};
332
+ if (input.name !== undefined)
333
+ updateData.name = input.name;
334
+ if (input.description !== undefined)
335
+ updateData.description = input.description;
336
+ let mod;
337
+ try {
338
+ mod = await repoUpdateModule(moduleId, updateData);
339
+ }
340
+ catch (err) {
341
+ if (err instanceof Error && err.message === 'Module not found') {
342
+ throw new ApplicationNotFoundError(moduleId);
343
+ }
344
+ throw err;
345
+ }
346
+ // Audit log (fire-and-forget)
347
+ await writeAuditLog({
348
+ eventType: 'app.module.updated',
349
+ eventCategory: 'admin',
350
+ actorId,
351
+ metadata: { moduleId: mod.id, applicationId: mod.applicationId, fields: Object.keys(updateData) },
352
+ });
353
+ return mod;
354
+ }
355
+ /**
356
+ * Deactivate a module (set status to inactive).
357
+ *
358
+ * @param moduleId - Module UUID
359
+ * @param actorId - UUID of the user performing the action
360
+ * @throws ApplicationNotFoundError if module not found
361
+ * @throws ApplicationValidationError if not currently active
362
+ */
363
+ export async function deactivateModule(moduleId, actorId) {
364
+ const mod = await findModuleById(moduleId);
365
+ if (!mod)
366
+ throw new ApplicationNotFoundError(moduleId);
367
+ if (mod.status !== 'active') {
368
+ throw new ApplicationValidationError(`Cannot deactivate module from status: ${mod.status}`);
369
+ }
370
+ await repoUpdateModule(moduleId, { status: 'inactive' });
371
+ await writeAuditLog({
372
+ eventType: 'app.module.deactivated',
373
+ eventCategory: 'admin',
374
+ actorId,
375
+ metadata: { moduleId: mod.id, applicationId: mod.applicationId },
376
+ });
377
+ }
378
+ /**
379
+ * List all modules for an application.
380
+ * Delegates directly to the repository.
381
+ *
382
+ * @param applicationId - Application UUID
383
+ * @returns Array of modules
384
+ */
385
+ export async function listModules(applicationId) {
386
+ return repoListModules(applicationId);
387
+ }
388
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/applications/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Slug generation and validation utilities for applications.
3
+ *
4
+ * Application slugs are URL-safe identifiers used to reference
5
+ * applications in API paths and configuration. They must be
6
+ * 3–100 characters, lowercase alphanumeric with hyphens,
7
+ * and cannot be a reserved system word.
8
+ *
9
+ * This module provides:
10
+ * - `generateSlug(name)` — Derive a slug from an application name
11
+ * - `validateSlug(slug)` — Check format and reserved-word rules
12
+ * - `RESERVED_SLUGS` — The set of words that cannot be used as application slugs
13
+ *
14
+ * Note: Application reserved words differ from organization reserved words
15
+ * because app slugs appear in different contexts (e.g., app references in
16
+ * client metadata, module namespacing).
17
+ */
18
+ /**
19
+ * Reserved slugs that cannot be used as application slugs.
20
+ * These conflict with system concepts, internal naming, or
21
+ * could cause confusion with infrastructure functionality.
22
+ */
23
+ export declare const RESERVED_SLUGS: ReadonlySet<string>;
24
+ /**
25
+ * Generate a URL-safe slug from an application name.
26
+ *
27
+ * Transformation rules:
28
+ * 1. Convert to lowercase
29
+ * 2. Replace non-alphanumeric characters with hyphens
30
+ * 3. Collapse multiple consecutive hyphens into one
31
+ * 4. Trim leading and trailing hyphens
32
+ * 5. Truncate to 100 characters (trimming trailing hyphens after truncation)
33
+ *
34
+ * Returns an empty string for empty/whitespace-only input — the caller
35
+ * (service layer) is responsible for validation.
36
+ *
37
+ * @param name - Application name to derive a slug from
38
+ * @returns Generated slug string
39
+ */
40
+ export declare function generateSlug(name: string): string;
41
+ /** Result of slug validation — isValid flag with optional error message */
42
+ export interface SlugValidationResult {
43
+ isValid: boolean;
44
+ error?: string;
45
+ }
46
+ /**
47
+ * Validate a slug against format and reserved word rules.
48
+ *
49
+ * Checks (in order):
50
+ * 1. Minimum length (3 characters)
51
+ * 2. Maximum length (100 characters)
52
+ * 3. Format (lowercase alphanumeric + hyphens, no leading/trailing hyphens)
53
+ * 4. Not a reserved word
54
+ *
55
+ * Does NOT check uniqueness — that's the repository/service layer's job.
56
+ *
57
+ * @param slug - Slug string to validate
58
+ * @returns Object with isValid boolean and optional error message
59
+ */
60
+ export declare function validateSlug(slug: string): SlugValidationResult;
61
+ //# sourceMappingURL=slugs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../src/applications/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAQ7C,CAAC;AAiBH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBjD;AAMD,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CA2B/D"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Slug generation and validation utilities for applications.
3
+ *
4
+ * Application slugs are URL-safe identifiers used to reference
5
+ * applications in API paths and configuration. They must be
6
+ * 3–100 characters, lowercase alphanumeric with hyphens,
7
+ * and cannot be a reserved system word.
8
+ *
9
+ * This module provides:
10
+ * - `generateSlug(name)` — Derive a slug from an application name
11
+ * - `validateSlug(slug)` — Check format and reserved-word rules
12
+ * - `RESERVED_SLUGS` — The set of words that cannot be used as application slugs
13
+ *
14
+ * Note: Application reserved words differ from organization reserved words
15
+ * because app slugs appear in different contexts (e.g., app references in
16
+ * client metadata, module namespacing).
17
+ */
18
+ // ---------------------------------------------------------------------------
19
+ // Reserved slugs
20
+ // ---------------------------------------------------------------------------
21
+ /**
22
+ * Reserved slugs that cannot be used as application slugs.
23
+ * These conflict with system concepts, internal naming, or
24
+ * could cause confusion with infrastructure functionality.
25
+ */
26
+ export const RESERVED_SLUGS = new Set([
27
+ 'admin',
28
+ 'api',
29
+ 'system',
30
+ 'internal',
31
+ 'default',
32
+ 'health',
33
+ 'status',
34
+ ]);
35
+ // ---------------------------------------------------------------------------
36
+ // Slug format
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Slug format regex: 3–100 characters, lowercase alphanumeric + hyphens.
40
+ * Must start and end with an alphanumeric character (no leading/trailing hyphens).
41
+ * The middle section allows 1–98 characters of alphanumeric + hyphens.
42
+ */
43
+ const SLUG_REGEX = /^[a-z0-9][a-z0-9-]{1,98}[a-z0-9]$/;
44
+ // ---------------------------------------------------------------------------
45
+ // Slug generation
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * Generate a URL-safe slug from an application name.
49
+ *
50
+ * Transformation rules:
51
+ * 1. Convert to lowercase
52
+ * 2. Replace non-alphanumeric characters with hyphens
53
+ * 3. Collapse multiple consecutive hyphens into one
54
+ * 4. Trim leading and trailing hyphens
55
+ * 5. Truncate to 100 characters (trimming trailing hyphens after truncation)
56
+ *
57
+ * Returns an empty string for empty/whitespace-only input — the caller
58
+ * (service layer) is responsible for validation.
59
+ *
60
+ * @param name - Application name to derive a slug from
61
+ * @returns Generated slug string
62
+ */
63
+ export function generateSlug(name) {
64
+ if (!name || !name.trim()) {
65
+ return '';
66
+ }
67
+ const slug = name
68
+ .toLowerCase()
69
+ // Replace any character that's not a-z, 0-9, or hyphen with a hyphen
70
+ .replace(/[^a-z0-9-]/g, '-')
71
+ // Collapse consecutive hyphens into a single hyphen
72
+ .replace(/-+/g, '-')
73
+ // Remove leading and trailing hyphens
74
+ .replace(/^-+|-+$/g, '');
75
+ // Truncate to 100 characters, then trim any trailing hyphen caused by truncation
76
+ return slug.slice(0, 100).replace(/-+$/, '');
77
+ }
78
+ /**
79
+ * Validate a slug against format and reserved word rules.
80
+ *
81
+ * Checks (in order):
82
+ * 1. Minimum length (3 characters)
83
+ * 2. Maximum length (100 characters)
84
+ * 3. Format (lowercase alphanumeric + hyphens, no leading/trailing hyphens)
85
+ * 4. Not a reserved word
86
+ *
87
+ * Does NOT check uniqueness — that's the repository/service layer's job.
88
+ *
89
+ * @param slug - Slug string to validate
90
+ * @returns Object with isValid boolean and optional error message
91
+ */
92
+ export function validateSlug(slug) {
93
+ // Check minimum length
94
+ if (slug.length < 3) {
95
+ return { isValid: false, error: 'Slug must be at least 3 characters' };
96
+ }
97
+ // Check maximum length
98
+ if (slug.length > 100) {
99
+ return { isValid: false, error: 'Slug must be at most 100 characters' };
100
+ }
101
+ // Check format: lowercase alphanumeric + hyphens, no leading/trailing hyphens
102
+ if (!SLUG_REGEX.test(slug)) {
103
+ return {
104
+ isValid: false,
105
+ error: 'Slug must contain only lowercase letters, numbers, and hyphens, ' +
106
+ 'and cannot start or end with a hyphen',
107
+ };
108
+ }
109
+ // Check reserved words
110
+ if (RESERVED_SLUGS.has(slug)) {
111
+ return { isValid: false, error: `Slug "${slug}" is reserved and cannot be used` };
112
+ }
113
+ return { isValid: true };
114
+ }
115
+ //# sourceMappingURL=slugs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slugs.js","sourceRoot":"","sources":["../../src/applications/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACzD,OAAO;IACP,KAAK;IACL,QAAQ;IACR,UAAU;IACV,SAAS;IACT,QAAQ;IACR,QAAQ;CACT,CAAC,CAAC;AAEH,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,GAAG,mCAAmC,CAAC;AAEvD,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI;SACd,WAAW,EAAE;QACd,qEAAqE;SACpE,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;QAC5B,oDAAoD;SACnD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,sCAAsC;SACrC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAE3B,iFAAiF;IACjF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAYD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,uBAAuB;IACvB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACzE,CAAC;IAED,uBAAuB;IACvB,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;IAC1E,CAAC;IAED,8EAA8E;IAC9E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EACH,kEAAkE;gBAClE,uCAAuC;SAC1C,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,IAAI,kCAAkC,EAAE,CAAC;IACpF,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}