@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 @@
1
+ {"version":3,"file":"super-admin-protection.js","sourceRoot":"","sources":["../../src/lib/super-admin-protection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,gEAAgE;AAChE,MAAM,CAAC,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;AAE7D;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ;IACR,SAAS;IACT,MAAM;IACN,YAAY;IACZ,yBAAyB;IACzB,YAAY;CACJ,CAAC;AAIX,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAc;IACnD,yEAAyE;IACzE,gFAAgF;IAChF,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAClF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,gBAAgB,KAAK,MAAM,CAAC;AACrC,CAAC;AAED,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,oCAAoC;IAC3B,MAAM,GAAG,GAAG,CAAC;IACtB,uCAAuC;IAC9B,SAAS,CAAqB;IAEvC,YAAY,SAA6B;QACvC,KAAK,CAAC,UAAU,SAAS,uBAAuB,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,SAA6B;IAE7B,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * System configuration service — reads runtime settings from the system_config table.
3
+ *
4
+ * Values are cached in-memory with a configurable TTL to minimize database queries.
5
+ * The cache is shared across all requests within the process.
6
+ *
7
+ * The system_config table stores values as JSONB. Duration-type values are stored
8
+ * as JSONB strings (e.g., '"3600"'), while booleans and numbers are stored as
9
+ * native JSONB types. The typed getters handle parsing and coercion for each type.
10
+ *
11
+ * @example
12
+ * const ttl = await getSystemConfigNumber('access_token_ttl', 3600);
13
+ * const secure = await getSystemConfigBoolean('cookie_secure', true);
14
+ * const allTtls = await loadOidcTtlConfig();
15
+ */
16
+ /** OIDC TTL configuration loaded from system_config table */
17
+ export interface OidcTtlConfig {
18
+ /** Access token lifetime in seconds (default: 3600 = 1 hour) */
19
+ accessToken: number;
20
+ /** ID token lifetime in seconds (default: 3600 = 1 hour) */
21
+ idToken: number;
22
+ /** Refresh token lifetime in seconds (default: 2592000 = 30 days) */
23
+ refreshToken: number;
24
+ /** Authorization code lifetime in seconds (default: 600 = 10 minutes) */
25
+ authorizationCode: number;
26
+ /** Session lifetime in seconds (default: 86400 = 24 hours) */
27
+ session: number;
28
+ /** Interaction lifetime in seconds — hardcoded, not in system_config (default: 3600 = 1 hour) */
29
+ interaction: number;
30
+ /** Grant lifetime in seconds — same as refresh token (default: 2592000 = 30 days) */
31
+ grant: number;
32
+ }
33
+ /**
34
+ * Get a string config value from the system_config table.
35
+ *
36
+ * @param key - Config key (e.g., 'magic_link_length')
37
+ * @param fallback - Default value returned if key not found or value is not a string
38
+ * @returns The config value as a string, or the fallback
39
+ */
40
+ export declare function getSystemConfigString(key: string, fallback: string): Promise<string>;
41
+ /**
42
+ * Get a numeric config value from the system_config table.
43
+ *
44
+ * Handles two storage patterns:
45
+ * - Duration-type values stored as JSONB strings (e.g., '"3600"') → parsed to number
46
+ * - Number-type values stored as native JSONB numbers (e.g., 10) → returned directly
47
+ *
48
+ * @param key - Config key (e.g., 'access_token_ttl')
49
+ * @param fallback - Default value returned if key not found or not a valid number
50
+ * @returns The config value as a number, or the fallback
51
+ */
52
+ export declare function getSystemConfigNumber(key: string, fallback: number): Promise<number>;
53
+ /**
54
+ * Get a boolean config value from the system_config table.
55
+ *
56
+ * Handles native JSONB booleans (true/false) and string representations
57
+ * ('true'/'false') for maximum flexibility.
58
+ *
59
+ * @param key - Config key (e.g., 'cookie_secure')
60
+ * @param fallback - Default value returned if key not found or not a valid boolean
61
+ * @returns The config value as a boolean, or the fallback
62
+ */
63
+ export declare function getSystemConfigBoolean(key: string, fallback: boolean): Promise<boolean>;
64
+ /**
65
+ * Load all TTL config values needed by the OIDC provider.
66
+ *
67
+ * Reads each TTL key from system_config with hardcoded fallback defaults.
68
+ * Called once at provider initialization to build the TTL configuration.
69
+ * The interaction TTL is hardcoded (not stored in system_config).
70
+ *
71
+ * @returns Object with all OIDC TTL settings in seconds
72
+ */
73
+ export declare function loadOidcTtlConfig(): Promise<OidcTtlConfig>;
74
+ /**
75
+ * Clear the in-memory config cache.
76
+ * Useful for testing to ensure fresh reads from the database.
77
+ */
78
+ export declare function clearSystemConfigCache(): void;
79
+ //# sourceMappingURL=system-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-config.d.ts","sourceRoot":"","sources":["../../src/lib/system-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC;CACf;AA8CD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM1F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB1F;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAe7F;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,CAoBhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * System configuration service — reads runtime settings from the system_config table.
3
+ *
4
+ * Values are cached in-memory with a configurable TTL to minimize database queries.
5
+ * The cache is shared across all requests within the process.
6
+ *
7
+ * The system_config table stores values as JSONB. Duration-type values are stored
8
+ * as JSONB strings (e.g., '"3600"'), while booleans and numbers are stored as
9
+ * native JSONB types. The typed getters handle parsing and coercion for each type.
10
+ *
11
+ * @example
12
+ * const ttl = await getSystemConfigNumber('access_token_ttl', 3600);
13
+ * const secure = await getSystemConfigBoolean('cookie_secure', true);
14
+ * const allTtls = await loadOidcTtlConfig();
15
+ */
16
+ import { getPool } from './database.js';
17
+ import { logger } from './logger.js';
18
+ // In-memory cache with TTL (default: 60 seconds)
19
+ const cache = new Map();
20
+ const CACHE_TTL_MS = 60_000;
21
+ /**
22
+ * Fetch a raw config value from the database by key.
23
+ * Returns undefined if the key does not exist.
24
+ * Results are cached for CACHE_TTL_MS milliseconds.
25
+ *
26
+ * @param key - Config key to look up (e.g., 'access_token_ttl')
27
+ * @returns The JSONB value from the database, or undefined if not found
28
+ */
29
+ async function getRawConfigValue(key) {
30
+ const now = Date.now();
31
+ // Check cache first
32
+ const cached = cache.get(key);
33
+ if (cached && cached.expiresAt > now) {
34
+ return cached.value;
35
+ }
36
+ try {
37
+ const pool = getPool();
38
+ const result = await pool.query('SELECT value FROM system_config WHERE key = $1', [key]);
39
+ if (result.rows.length === 0) {
40
+ // Cache the miss to avoid repeated DB queries for unknown keys
41
+ cache.set(key, { value: undefined, expiresAt: now + CACHE_TTL_MS });
42
+ return undefined;
43
+ }
44
+ const value = result.rows[0].value;
45
+ cache.set(key, { value, expiresAt: now + CACHE_TTL_MS });
46
+ return value;
47
+ }
48
+ catch (error) {
49
+ // Log warning but don't fail — callers always provide fallback defaults
50
+ logger.warn({ key, error }, 'Failed to read system_config value, using fallback');
51
+ return undefined;
52
+ }
53
+ }
54
+ /**
55
+ * Get a string config value from the system_config table.
56
+ *
57
+ * @param key - Config key (e.g., 'magic_link_length')
58
+ * @param fallback - Default value returned if key not found or value is not a string
59
+ * @returns The config value as a string, or the fallback
60
+ */
61
+ export async function getSystemConfigString(key, fallback) {
62
+ const raw = await getRawConfigValue(key);
63
+ if (raw === undefined || raw === null)
64
+ return fallback;
65
+ // JSONB values may be strings, numbers, or booleans — coerce to string
66
+ return String(raw);
67
+ }
68
+ /**
69
+ * Get a numeric config value from the system_config table.
70
+ *
71
+ * Handles two storage patterns:
72
+ * - Duration-type values stored as JSONB strings (e.g., '"3600"') → parsed to number
73
+ * - Number-type values stored as native JSONB numbers (e.g., 10) → returned directly
74
+ *
75
+ * @param key - Config key (e.g., 'access_token_ttl')
76
+ * @param fallback - Default value returned if key not found or not a valid number
77
+ * @returns The config value as a number, or the fallback
78
+ */
79
+ export async function getSystemConfigNumber(key, fallback) {
80
+ const raw = await getRawConfigValue(key);
81
+ if (raw === undefined || raw === null)
82
+ return fallback;
83
+ // If already a number (native JSONB number), return directly
84
+ if (typeof raw === 'number' && !Number.isNaN(raw))
85
+ return raw;
86
+ // If it's a string (duration values stored as JSONB strings like '"3600"'),
87
+ // parse as number
88
+ if (typeof raw === 'string') {
89
+ const parsed = Number(raw);
90
+ if (!Number.isNaN(parsed))
91
+ return parsed;
92
+ }
93
+ logger.warn({ key, raw }, 'system_config value is not a valid number, using fallback');
94
+ return fallback;
95
+ }
96
+ /**
97
+ * Get a boolean config value from the system_config table.
98
+ *
99
+ * Handles native JSONB booleans (true/false) and string representations
100
+ * ('true'/'false') for maximum flexibility.
101
+ *
102
+ * @param key - Config key (e.g., 'cookie_secure')
103
+ * @param fallback - Default value returned if key not found or not a valid boolean
104
+ * @returns The config value as a boolean, or the fallback
105
+ */
106
+ export async function getSystemConfigBoolean(key, fallback) {
107
+ const raw = await getRawConfigValue(key);
108
+ if (raw === undefined || raw === null)
109
+ return fallback;
110
+ // Native JSONB boolean
111
+ if (typeof raw === 'boolean')
112
+ return raw;
113
+ // String representation (from some JSONB encodings)
114
+ if (typeof raw === 'string') {
115
+ if (raw === 'true')
116
+ return true;
117
+ if (raw === 'false')
118
+ return false;
119
+ }
120
+ logger.warn({ key, raw }, 'system_config value is not a valid boolean, using fallback');
121
+ return fallback;
122
+ }
123
+ /**
124
+ * Load all TTL config values needed by the OIDC provider.
125
+ *
126
+ * Reads each TTL key from system_config with hardcoded fallback defaults.
127
+ * Called once at provider initialization to build the TTL configuration.
128
+ * The interaction TTL is hardcoded (not stored in system_config).
129
+ *
130
+ * @returns Object with all OIDC TTL settings in seconds
131
+ */
132
+ export async function loadOidcTtlConfig() {
133
+ const [accessToken, idToken, refreshToken, authorizationCode, session] = await Promise.all([
134
+ getSystemConfigNumber('access_token_ttl', 3600),
135
+ getSystemConfigNumber('id_token_ttl', 3600),
136
+ getSystemConfigNumber('refresh_token_ttl', 2592000),
137
+ getSystemConfigNumber('authorization_code_ttl', 600),
138
+ getSystemConfigNumber('session_ttl', 86400),
139
+ ]);
140
+ return {
141
+ accessToken,
142
+ idToken,
143
+ refreshToken,
144
+ authorizationCode,
145
+ session,
146
+ // Interaction TTL is hardcoded — not configurable via system_config
147
+ interaction: 3600,
148
+ // Grant TTL matches refresh token TTL by default
149
+ grant: refreshToken,
150
+ };
151
+ }
152
+ /**
153
+ * Clear the in-memory config cache.
154
+ * Useful for testing to ensure fresh reads from the database.
155
+ */
156
+ export function clearSystemConfigCache() {
157
+ cache.clear();
158
+ }
159
+ //# sourceMappingURL=system-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-config.js","sourceRoot":"","sources":["../../src/lib/system-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Admin API authentication and authorization middleware.
3
+ *
4
+ * Validates Bearer access tokens against Porta's own OIDC provider
5
+ * using opaque token lookup (provider.AccessToken.find()). Verifies
6
+ * the user belongs to the super-admin organization and has the
7
+ * porta-admin role. Sets ctx.state.adminUser for downstream handlers
8
+ * and audit logging.
9
+ *
10
+ * This middleware replaces the old requireSuperAdmin() that checked
11
+ * ctx.state.organization.isSuperAdmin (which required tenant-resolver
12
+ * context and was always undefined for /api/admin/* routes).
13
+ *
14
+ * Authentication flow:
15
+ * 1. Extract Bearer token from Authorization header
16
+ * 2. Validate opaque access token via OIDC provider lookup
17
+ * 3. Resolve super-admin organization
18
+ * 4. Look up user — must be active
19
+ * 5. Verify user belongs to the super-admin organization
20
+ * 6. Verify user has the porta-admin role
21
+ * 7. Set ctx.state.adminUser and proceed
22
+ *
23
+ * Response codes:
24
+ * 401 — Missing/invalid Bearer token, expired, revoked, unknown user
25
+ * 403 — Valid token but user not in admin org or lacks admin role
26
+ * 500 — System not initialized (provider not set, no super-admin org)
27
+ */
28
+ import type { Middleware } from 'koa';
29
+ import type { Organization } from '../organizations/types.js';
30
+ /** Minimal opaque-token lookup boundary required from the OIDC provider. */
31
+ export interface AdminAccessTokenProvider {
32
+ /** Provider model used to resolve one opaque access token. */
33
+ readonly AccessToken: {
34
+ /** Resolve a token without exposing its storage mechanism to middleware. */
35
+ find(token: string): Promise<{
36
+ accountId?: string;
37
+ } | undefined>;
38
+ };
39
+ }
40
+ /**
41
+ * Set the OIDC provider instance used for opaque access token validation.
42
+ * Must be called once at startup before any admin API requests are handled.
43
+ *
44
+ * The provider's AccessToken.find() method is used to look up opaque tokens
45
+ * from the token store (Redis for short-lived tokens).
46
+ */
47
+ export declare function setAdminAuthProvider(provider: AdminAccessTokenProvider): void;
48
+ /** Remove the process-owned OIDC provider reference during orderly teardown. */
49
+ export declare function clearAdminAuthProvider(): void;
50
+ /**
51
+ * Authenticated admin user identity.
52
+ *
53
+ * Populated by requireAdminAuth() middleware and available to all
54
+ * downstream route handlers via ctx.state.adminUser. Contains the
55
+ * user's ID, email, organization, and assigned role slugs.
56
+ */
57
+ export interface AdminUser {
58
+ /** User UUID from access token accountId */
59
+ id: string;
60
+ /** User email address */
61
+ email: string;
62
+ /** Super-admin organization UUID */
63
+ organizationId: string;
64
+ /** Assigned role slugs (e.g., ['porta-super-admin', 'porta-org-admin']) */
65
+ roles: string[];
66
+ /** Resolved admin permissions from all assigned roles */
67
+ permissions: readonly string[];
68
+ }
69
+ /**
70
+ * Enforce super-admin organization membership through the shared public denial boundary.
71
+ *
72
+ * @returns `true` only when the authenticated account belongs to the required organization.
73
+ */
74
+ export declare function requireAdminOrganizationMembership(ctx: Parameters<Middleware>[0], userOrganizationId: string, adminOrganizationId: string): boolean;
75
+ /**
76
+ * Extend Koa's default state to include the adminUser property.
77
+ * This provides type safety for route handlers accessing ctx.state.adminUser.
78
+ */
79
+ declare module 'koa' {
80
+ interface DefaultState {
81
+ /** Tenant organization — set by tenant-resolver middleware on /:orgSlug/* routes */
82
+ organization?: Organization;
83
+ /** Authenticated admin identity — set by requireAdminAuth middleware on /api/admin/* routes */
84
+ adminUser?: AdminUser;
85
+ }
86
+ }
87
+ /**
88
+ * Create middleware that requires admin authentication and authorization.
89
+ *
90
+ * Validates the Bearer access token in the Authorization header by looking
91
+ * it up via the OIDC provider's opaque token store, then verifies the user
92
+ * is an active member of the super-admin organization with the porta-admin role.
93
+ *
94
+ * On success, sets ctx.state.adminUser with the authenticated identity.
95
+ * On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
96
+ *
97
+ * @returns Koa middleware
98
+ */
99
+ export declare function requireAdminAuth(): Middleware;
100
+ //# sourceMappingURL=admin-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-auth.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAY9D,4EAA4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,EAAE;QACpB,4EAA4E;QAC5E,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAC,CAAC;KAClE,CAAC;CACH;AAID;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAE7E;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yDAAyD;IACzD,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAC9B,kBAAkB,EAAE,MAAM,EAC1B,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAaT;AAMD;;;GAGG;AACH,OAAO,QAAQ,KAAK,CAAC;IACnB,UAAU,YAAY;QACpB,oFAAoF;QACpF,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,+FAA+F;QAC/F,SAAS,CAAC,EAAE,SAAS,CAAC;KACvB;CACF;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CA+J7C"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Admin API authentication and authorization middleware.
3
+ *
4
+ * Validates Bearer access tokens against Porta's own OIDC provider
5
+ * using opaque token lookup (provider.AccessToken.find()). Verifies
6
+ * the user belongs to the super-admin organization and has the
7
+ * porta-admin role. Sets ctx.state.adminUser for downstream handlers
8
+ * and audit logging.
9
+ *
10
+ * This middleware replaces the old requireSuperAdmin() that checked
11
+ * ctx.state.organization.isSuperAdmin (which required tenant-resolver
12
+ * context and was always undefined for /api/admin/* routes).
13
+ *
14
+ * Authentication flow:
15
+ * 1. Extract Bearer token from Authorization header
16
+ * 2. Validate opaque access token via OIDC provider lookup
17
+ * 3. Resolve super-admin organization
18
+ * 4. Look up user — must be active
19
+ * 5. Verify user belongs to the super-admin organization
20
+ * 6. Verify user has the porta-admin role
21
+ * 7. Set ctx.state.adminUser and proceed
22
+ *
23
+ * Response codes:
24
+ * 401 — Missing/invalid Bearer token, expired, revoked, unknown user
25
+ * 403 — Valid token but user not in admin org or lacks admin role
26
+ * 500 — System not initialized (provider not set, no super-admin org)
27
+ */
28
+ import { findUserForOidc } from '../users/service.js';
29
+ import { findSuperAdminOrganization } from '../organizations/repository.js';
30
+ import { getUserRoles } from '../rbac/user-role-service.js';
31
+ import { logger } from '../lib/logger.js';
32
+ import { resolvePermissionsFromRoles } from '../lib/admin-permissions.js';
33
+ import { recordSecurityDecision, recordSecurityReference } from '../security/decision-context.js';
34
+ let _provider = null;
35
+ /**
36
+ * Set the OIDC provider instance used for opaque access token validation.
37
+ * Must be called once at startup before any admin API requests are handled.
38
+ *
39
+ * The provider's AccessToken.find() method is used to look up opaque tokens
40
+ * from the token store (Redis for short-lived tokens).
41
+ */
42
+ export function setAdminAuthProvider(provider) {
43
+ _provider = provider;
44
+ }
45
+ /** Remove the process-owned OIDC provider reference during orderly teardown. */
46
+ export function clearAdminAuthProvider() {
47
+ _provider = null;
48
+ }
49
+ /**
50
+ * Enforce super-admin organization membership through the shared public denial boundary.
51
+ *
52
+ * @returns `true` only when the authenticated account belongs to the required organization.
53
+ */
54
+ export function requireAdminOrganizationMembership(ctx, userOrganizationId, adminOrganizationId) {
55
+ if (userOrganizationId === adminOrganizationId)
56
+ return true;
57
+ recordSecurityDecision(ctx, {
58
+ decisionPoint: 'membership',
59
+ reasonCode: 'membership-required',
60
+ outcome: 'deny',
61
+ });
62
+ ctx.status = 403;
63
+ ctx.body = {
64
+ error: 'Forbidden',
65
+ message: 'Administrative access is not permitted',
66
+ };
67
+ return false;
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Admin auth middleware factory
71
+ // ---------------------------------------------------------------------------
72
+ /**
73
+ * Admin role slug prefix — all admin roles start with 'porta-'.
74
+ * Legacy 'porta-admin' role is treated as super-admin for backward compatibility.
75
+ */
76
+ const ADMIN_ROLE_PREFIX = 'porta-';
77
+ /**
78
+ * Create middleware that requires admin authentication and authorization.
79
+ *
80
+ * Validates the Bearer access token in the Authorization header by looking
81
+ * it up via the OIDC provider's opaque token store, then verifies the user
82
+ * is an active member of the super-admin organization with the porta-admin role.
83
+ *
84
+ * On success, sets ctx.state.adminUser with the authenticated identity.
85
+ * On failure, responds with 401 (unauthenticated) or 403 (unauthorized).
86
+ *
87
+ * @returns Koa middleware
88
+ */
89
+ export function requireAdminAuth() {
90
+ return async (ctx, next) => {
91
+ // -----------------------------------------------------------------
92
+ // Step 1: Extract Bearer token from Authorization header
93
+ // -----------------------------------------------------------------
94
+ const authHeader = ctx.get('Authorization');
95
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
96
+ recordSecurityDecision(ctx, {
97
+ decisionPoint: 'authentication',
98
+ reasonCode: 'authentication-required',
99
+ outcome: 'deny',
100
+ });
101
+ ctx.status = 401;
102
+ ctx.body = {
103
+ error: 'Authentication required',
104
+ message: 'Missing or invalid Authorization header',
105
+ };
106
+ return;
107
+ }
108
+ const token = authHeader.slice(7); // Remove 'Bearer ' prefix
109
+ // -----------------------------------------------------------------
110
+ // Step 2: Validate opaque access token via OIDC provider
111
+ // -----------------------------------------------------------------
112
+ // Timing analysis (Phase K audit):
113
+ // Token validation uses DB/Redis lookups via provider.AccessToken.find(),
114
+ // which have inherent timing variability from network I/O. All auth
115
+ // failure paths return the same 401 status and generic error message
116
+ // ("Token validation failed"), preventing error-message enumeration.
117
+ // Constant-time string comparison is not needed here because we never
118
+ // compare secret material directly — the opaque token is used as a
119
+ // lookup key, not compared against a stored value.
120
+ // -----------------------------------------------------------------
121
+ // The OIDC provider issues opaque access tokens (not JWTs). We look
122
+ // them up directly in the token store using provider.AccessToken.find().
123
+ // This handles expiry (Redis TTL), revocation, and format validation
124
+ // in a single call — no need for JWT signature verification or issuer
125
+ // checks since the provider is the authoritative token store.
126
+ if (!_provider) {
127
+ logger.error('Admin auth: OIDC provider not initialized');
128
+ recordSecurityDecision(ctx, {
129
+ decisionPoint: 'handler',
130
+ reasonCode: 'handler-failed',
131
+ outcome: 'error',
132
+ });
133
+ ctx.status = 500;
134
+ ctx.body = { error: 'Server configuration error' };
135
+ return;
136
+ }
137
+ let userId;
138
+ try {
139
+ const accessToken = await _provider.AccessToken.find(token);
140
+ if (!accessToken || !accessToken.accountId) {
141
+ logger.debug('Admin auth: access token not found or missing accountId');
142
+ recordSecurityDecision(ctx, {
143
+ decisionPoint: 'authentication',
144
+ reasonCode: 'authentication-required',
145
+ outcome: 'deny',
146
+ });
147
+ ctx.status = 401;
148
+ ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
149
+ return;
150
+ }
151
+ userId = accessToken.accountId;
152
+ }
153
+ catch {
154
+ // Intentionally vague error message — don't reveal internal details.
155
+ // Log the real error server-side for debugging.
156
+ logger.debug({ event: 'admin-token-lookup-rejected' }, 'Admin token lookup rejected');
157
+ recordSecurityDecision(ctx, {
158
+ decisionPoint: 'authentication',
159
+ reasonCode: 'authentication-required',
160
+ outcome: 'deny',
161
+ });
162
+ ctx.status = 401;
163
+ ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
164
+ return;
165
+ }
166
+ // -----------------------------------------------------------------
167
+ // Step 3: Resolve super-admin organization
168
+ // -----------------------------------------------------------------
169
+ // Cached in-memory (60s TTL) so this is fast after first call.
170
+ const superAdminOrg = await findSuperAdminOrganization();
171
+ if (!superAdminOrg) {
172
+ // System not initialized — porta init has not been run
173
+ logger.error('Admin auth: super-admin organization not found — run porta init');
174
+ recordSecurityDecision(ctx, {
175
+ decisionPoint: 'handler',
176
+ reasonCode: 'handler-failed',
177
+ outcome: 'error',
178
+ });
179
+ ctx.status = 500;
180
+ ctx.body = { error: 'Server configuration error' };
181
+ return;
182
+ }
183
+ // -----------------------------------------------------------------
184
+ // Step 4: Look up user — must be active
185
+ // -----------------------------------------------------------------
186
+ // findUserForOidc returns null for non-existent or non-active users
187
+ const user = await findUserForOidc(userId);
188
+ if (!user) {
189
+ recordSecurityDecision(ctx, {
190
+ decisionPoint: 'authentication',
191
+ reasonCode: 'authentication-required',
192
+ outcome: 'deny',
193
+ });
194
+ ctx.status = 401;
195
+ ctx.body = { error: 'Invalid token', message: 'Token validation failed' };
196
+ return;
197
+ }
198
+ // -----------------------------------------------------------------
199
+ // Step 5: Verify user belongs to the super-admin organization
200
+ // -----------------------------------------------------------------
201
+ if (!requireAdminOrganizationMembership(ctx, user.organizationId, superAdminOrg.id))
202
+ return;
203
+ // -----------------------------------------------------------------
204
+ // Step 6: Verify user has an admin role (any porta-* role)
205
+ // -----------------------------------------------------------------
206
+ // Supports both legacy porta-admin and new granular roles:
207
+ // porta-super-admin, porta-org-admin, porta-user-admin, etc.
208
+ const userRoles = await getUserRoles(userId);
209
+ const adminRoleSlugs = userRoles
210
+ .map((role) => role.slug)
211
+ .filter((slug) => slug.startsWith(ADMIN_ROLE_PREFIX));
212
+ if (adminRoleSlugs.length === 0) {
213
+ recordSecurityDecision(ctx, {
214
+ decisionPoint: 'membership',
215
+ reasonCode: 'membership-required',
216
+ outcome: 'deny',
217
+ });
218
+ ctx.status = 403;
219
+ ctx.body = { error: 'Forbidden', message: 'Administrative access is not permitted' };
220
+ return;
221
+ }
222
+ // -----------------------------------------------------------------
223
+ // Step 7: Resolve permissions from all admin roles
224
+ // -----------------------------------------------------------------
225
+ const permissions = resolvePermissionsFromRoles(adminRoleSlugs);
226
+ // -----------------------------------------------------------------
227
+ // Step 8: Set admin user context and proceed to route handler
228
+ // -----------------------------------------------------------------
229
+ ctx.state.adminUser = {
230
+ id: userId,
231
+ email: user.email,
232
+ organizationId: user.organizationId,
233
+ roles: adminRoleSlugs,
234
+ permissions,
235
+ };
236
+ recordSecurityReference(ctx, 'actor', userId);
237
+ recordSecurityReference(ctx, 'tenant', user.organizationId);
238
+ await next();
239
+ };
240
+ }
241
+ //# sourceMappingURL=admin-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-auth.js","sourceRoot":"","sources":["../../src/middleware/admin-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Admin API CORS allow-list middleware.
3
+ *
4
+ * Implements a strict CORS policy for `/api/admin/*` endpoints.
5
+ * By default (empty `adminCorsOrigins` config), **no CORS headers are
6
+ * emitted** — all cross-origin requests are blocked by the browser.
7
+ *
8
+ * When `ADMIN_CORS_ORIGINS` is configured with one or more origin URLs,
9
+ * only those exact origins receive CORS headers. This is intended for
10
+ * operators who deploy a web-based admin dashboard on a different origin.
11
+ *
12
+ * Non-browser clients (CLI, same-origin requests) never send an `Origin`
13
+ * header, so they pass through this middleware untouched.
14
+ *
15
+ * Placement: mount after the admin metadata router and before
16
+ * `setAdminAuthProvider()` — preflight `OPTIONS` requests don't carry
17
+ * an `Authorization` header, so CORS must respond before auth runs.
18
+ *
19
+ * @module middleware/admin-cors
20
+ */
21
+ import type { Middleware } from 'koa';
22
+ import type { AppConfig } from '../config/schema.js';
23
+ /** HTTP methods allowed for cross-origin admin API requests. */
24
+ export declare const CORS_ALLOWED_METHODS = "GET, POST, PUT, PATCH, DELETE, OPTIONS";
25
+ /** HTTP headers allowed in cross-origin admin API requests. */
26
+ export declare const CORS_ALLOWED_HEADERS = "Authorization, Content-Type";
27
+ /** Preflight cache duration in seconds (24 hours). */
28
+ export declare const CORS_MAX_AGE = "86400";
29
+ /**
30
+ * Create admin CORS middleware with the given application config.
31
+ *
32
+ * Uses a `Set` for O(1) origin lookup. The `Vary: Origin` header is
33
+ * required by the CORS specification when `Access-Control-Allow-Origin`
34
+ * is not the wildcard `*` — it tells caches that the response varies by
35
+ * the request's `Origin` header.
36
+ *
37
+ * @param config - Application config (reads `adminCorsOrigins`)
38
+ * @returns Koa middleware that handles CORS for `/api/admin/*` routes
39
+ */
40
+ export declare function adminCors(config: AppConfig): Middleware;
41
+ //# sourceMappingURL=admin-cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-cors.d.ts","sourceRoot":"","sources":["../../src/middleware/admin-cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAMrD,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,2CAA2C,CAAC;AAE7E,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,sDAAsD;AACtD,eAAO,MAAM,YAAY,UAAU,CAAC;AAMpC;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CA4CvD"}