@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,261 @@
1
+ /**
2
+ * Admin permission constants and role definitions for granular admin access control.
3
+ *
4
+ * Replaces the single porta-admin role with a permission-based model where
5
+ * each admin endpoint requires specific permissions. Five predefined admin
6
+ * roles group permissions by responsibility area.
7
+ *
8
+ * @module admin-permissions
9
+ * @see 03-granular-admin-roles.md
10
+ */
11
+ // ============================================================================
12
+ // Permission Constants
13
+ // ============================================================================
14
+ /**
15
+ * Admin permission slugs following the `module:resource:action` pattern.
16
+ * Used by admin-auth middleware's `requirePermission()` factory
17
+ * and route handlers for endpoint-level authorization.
18
+ *
19
+ * The `admin` module prefix satisfies the RBAC permission slug validation
20
+ * requirement of at least 3 colon-separated segments.
21
+ *
22
+ * Permissions are seeded into the admin application during `porta init`
23
+ * and resolved at runtime from the user's assigned admin roles.
24
+ */
25
+ export const ADMIN_PERMISSIONS = {
26
+ // Organization management
27
+ ORG_CREATE: 'admin:org:create',
28
+ ORG_READ: 'admin:org:read',
29
+ ORG_UPDATE: 'admin:org:update',
30
+ ORG_SUSPEND: 'admin:org:suspend',
31
+ ORG_ARCHIVE: 'admin:org:archive',
32
+ // Application management
33
+ APP_CREATE: 'admin:app:create',
34
+ APP_READ: 'admin:app:read',
35
+ APP_UPDATE: 'admin:app:update',
36
+ APP_ARCHIVE: 'admin:app:archive',
37
+ // Client management
38
+ CLIENT_CREATE: 'admin:client:create',
39
+ CLIENT_READ: 'admin:client:read',
40
+ CLIENT_UPDATE: 'admin:client:update',
41
+ CLIENT_REVOKE: 'admin:client:revoke',
42
+ // User management
43
+ USER_CREATE: 'admin:user:create',
44
+ USER_READ: 'admin:user:read',
45
+ USER_UPDATE: 'admin:user:update',
46
+ USER_SUSPEND: 'admin:user:suspend',
47
+ USER_ARCHIVE: 'admin:user:archive',
48
+ USER_INVITE: 'admin:user:invite',
49
+ USER_2FA: 'admin:user:2fa',
50
+ // Role management
51
+ ROLE_CREATE: 'admin:role:create',
52
+ ROLE_READ: 'admin:role:read',
53
+ ROLE_UPDATE: 'admin:role:update',
54
+ ROLE_ARCHIVE: 'admin:role:archive',
55
+ ROLE_ASSIGN: 'admin:role:assign',
56
+ // Permission management
57
+ PERMISSION_CREATE: 'admin:permission:create',
58
+ PERMISSION_READ: 'admin:permission:read',
59
+ PERMISSION_ARCHIVE: 'admin:permission:archive',
60
+ // Custom claims management
61
+ CLAIM_CREATE: 'admin:claim:create',
62
+ CLAIM_READ: 'admin:claim:read',
63
+ CLAIM_UPDATE: 'admin:claim:update',
64
+ CLAIM_ARCHIVE: 'admin:claim:archive',
65
+ // System configuration
66
+ CONFIG_READ: 'admin:config:read',
67
+ CONFIG_UPDATE: 'admin:config:update',
68
+ // Signing keys
69
+ KEY_READ: 'admin:key:read',
70
+ KEY_GENERATE: 'admin:key:generate',
71
+ KEY_ROTATE: 'admin:key:rotate',
72
+ // Audit
73
+ AUDIT_READ: 'admin:audit:read',
74
+ // Session management
75
+ SESSION_READ: 'admin:session:read',
76
+ SESSION_REVOKE: 'admin:session:revoke',
77
+ // Dashboard statistics
78
+ STATS_READ: 'admin:stats:read',
79
+ // Import/export
80
+ EXPORT_READ: 'admin:export:read',
81
+ IMPORT_WRITE: 'admin:import:write',
82
+ };
83
+ /** Array of all admin permission slug values (useful for iteration/validation) */
84
+ export const ALL_ADMIN_PERMISSIONS = Object.values(ADMIN_PERMISSIONS);
85
+ /**
86
+ * Predefined admin role definitions with their permission sets.
87
+ *
88
+ * These roles are seeded during `porta init` into the admin application's
89
+ * RBAC system. Each role groups permissions by administrative responsibility:
90
+ *
91
+ * - **Super Admin** — Full access to all admin operations (all permissions)
92
+ * - **Org Admin** — Organization lifecycle management and statistics
93
+ * - **User Admin** — User management, invitations, role assignment, sessions
94
+ * - **App Admin** — Application/client/RBAC/claims management
95
+ * - **Auditor** — Read-only access across all resources plus audit log
96
+ */
97
+ export const ADMIN_ROLE_DEFINITIONS = {
98
+ SUPER_ADMIN: {
99
+ slug: 'porta-super-admin',
100
+ name: 'Super Admin',
101
+ description: 'Full system access, cannot be deleted',
102
+ permissions: ALL_ADMIN_PERMISSIONS,
103
+ },
104
+ ORG_ADMIN: {
105
+ slug: 'porta-org-admin',
106
+ name: 'Organization Admin',
107
+ description: 'Manage organizations, branding, settings',
108
+ permissions: [
109
+ ADMIN_PERMISSIONS.ORG_CREATE,
110
+ ADMIN_PERMISSIONS.ORG_READ,
111
+ ADMIN_PERMISSIONS.ORG_UPDATE,
112
+ ADMIN_PERMISSIONS.ORG_SUSPEND,
113
+ ADMIN_PERMISSIONS.ORG_ARCHIVE,
114
+ ADMIN_PERMISSIONS.STATS_READ,
115
+ ],
116
+ },
117
+ USER_ADMIN: {
118
+ slug: 'porta-user-admin',
119
+ name: 'User Admin',
120
+ description: 'Manage users, send invitations, manage roles',
121
+ permissions: [
122
+ ADMIN_PERMISSIONS.USER_CREATE,
123
+ ADMIN_PERMISSIONS.USER_READ,
124
+ ADMIN_PERMISSIONS.USER_UPDATE,
125
+ ADMIN_PERMISSIONS.USER_SUSPEND,
126
+ ADMIN_PERMISSIONS.USER_ARCHIVE,
127
+ ADMIN_PERMISSIONS.USER_INVITE,
128
+ ADMIN_PERMISSIONS.USER_2FA,
129
+ ADMIN_PERMISSIONS.ROLE_ASSIGN,
130
+ ADMIN_PERMISSIONS.ROLE_READ,
131
+ ADMIN_PERMISSIONS.CLAIM_READ,
132
+ ADMIN_PERMISSIONS.SESSION_READ,
133
+ ADMIN_PERMISSIONS.SESSION_REVOKE,
134
+ ],
135
+ },
136
+ APP_ADMIN: {
137
+ slug: 'porta-app-admin',
138
+ name: 'Application Admin',
139
+ description: 'Manage applications, clients, RBAC definitions',
140
+ permissions: [
141
+ ADMIN_PERMISSIONS.APP_CREATE,
142
+ ADMIN_PERMISSIONS.APP_READ,
143
+ ADMIN_PERMISSIONS.APP_UPDATE,
144
+ ADMIN_PERMISSIONS.APP_ARCHIVE,
145
+ ADMIN_PERMISSIONS.CLIENT_CREATE,
146
+ ADMIN_PERMISSIONS.CLIENT_READ,
147
+ ADMIN_PERMISSIONS.CLIENT_UPDATE,
148
+ ADMIN_PERMISSIONS.CLIENT_REVOKE,
149
+ ADMIN_PERMISSIONS.ROLE_CREATE,
150
+ ADMIN_PERMISSIONS.ROLE_READ,
151
+ ADMIN_PERMISSIONS.ROLE_UPDATE,
152
+ ADMIN_PERMISSIONS.ROLE_ARCHIVE,
153
+ ADMIN_PERMISSIONS.PERMISSION_CREATE,
154
+ ADMIN_PERMISSIONS.PERMISSION_READ,
155
+ ADMIN_PERMISSIONS.PERMISSION_ARCHIVE,
156
+ ADMIN_PERMISSIONS.CLAIM_CREATE,
157
+ ADMIN_PERMISSIONS.CLAIM_READ,
158
+ ADMIN_PERMISSIONS.CLAIM_UPDATE,
159
+ ADMIN_PERMISSIONS.CLAIM_ARCHIVE,
160
+ ],
161
+ },
162
+ AUDITOR: {
163
+ slug: 'porta-auditor',
164
+ name: 'Auditor',
165
+ description: 'Read-only access to everything, full audit log access',
166
+ permissions: [
167
+ ADMIN_PERMISSIONS.ORG_READ,
168
+ ADMIN_PERMISSIONS.APP_READ,
169
+ ADMIN_PERMISSIONS.CLIENT_READ,
170
+ ADMIN_PERMISSIONS.USER_READ,
171
+ ADMIN_PERMISSIONS.ROLE_READ,
172
+ ADMIN_PERMISSIONS.PERMISSION_READ,
173
+ ADMIN_PERMISSIONS.CLAIM_READ,
174
+ ADMIN_PERMISSIONS.CONFIG_READ,
175
+ ADMIN_PERMISSIONS.KEY_READ,
176
+ ADMIN_PERMISSIONS.AUDIT_READ,
177
+ ADMIN_PERMISSIONS.SESSION_READ,
178
+ ADMIN_PERMISSIONS.STATS_READ,
179
+ ADMIN_PERMISSIONS.EXPORT_READ,
180
+ ],
181
+ },
182
+ };
183
+ /** All admin role definition values as an array (for iteration) */
184
+ export const ALL_ADMIN_ROLES = Object.values(ADMIN_ROLE_DEFINITIONS);
185
+ // ============================================================================
186
+ // Legacy Compatibility
187
+ // ============================================================================
188
+ /**
189
+ * Legacy admin role slug from pre-granular auth.
190
+ * Users with this role are automatically treated as super-admins
191
+ * for backward compatibility during the transition period.
192
+ */
193
+ export const LEGACY_ADMIN_ROLE = 'porta-admin';
194
+ /**
195
+ * Check if a role slug represents a super-admin role.
196
+ * Recognizes both the new `porta-super-admin` and legacy `porta-admin` slugs.
197
+ *
198
+ * @param roleSlug - The role slug to check
199
+ * @returns true if the role grants super-admin level access
200
+ */
201
+ export function isSuperAdminRole(roleSlug) {
202
+ return (roleSlug === ADMIN_ROLE_DEFINITIONS.SUPER_ADMIN.slug || roleSlug === LEGACY_ADMIN_ROLE);
203
+ }
204
+ /**
205
+ * Resolve the effective admin role slug, mapping legacy roles to their
206
+ * modern equivalents.
207
+ *
208
+ * @param roleSlug - The role slug to resolve
209
+ * @returns The effective role slug (legacy porta-admin → porta-super-admin)
210
+ */
211
+ export function resolveAdminRoleSlug(roleSlug) {
212
+ if (roleSlug === LEGACY_ADMIN_ROLE) {
213
+ return ADMIN_ROLE_DEFINITIONS.SUPER_ADMIN.slug;
214
+ }
215
+ return roleSlug;
216
+ }
217
+ /**
218
+ * Get the permission set for an admin role slug.
219
+ * Returns all permissions for super-admin roles (including legacy).
220
+ * Returns an empty array for unrecognized role slugs.
221
+ *
222
+ * @param roleSlug - The admin role slug to look up
223
+ * @returns Array of permission slugs granted by this role
224
+ */
225
+ export function getPermissionsForAdminRole(roleSlug) {
226
+ // Legacy porta-admin gets all permissions (backward compatible)
227
+ if (roleSlug === LEGACY_ADMIN_ROLE) {
228
+ return ALL_ADMIN_PERMISSIONS;
229
+ }
230
+ // Find matching role definition
231
+ const roleDef = ALL_ADMIN_ROLES.find((r) => r.slug === roleSlug);
232
+ return roleDef ? roleDef.permissions : [];
233
+ }
234
+ /**
235
+ * Resolve the union of all permissions from multiple admin role slugs.
236
+ * Deduplicates the result. Handles legacy role mapping automatically.
237
+ *
238
+ * @param roleSlugs - Array of admin role slugs assigned to a user
239
+ * @returns Deduplicated array of all permission slugs
240
+ */
241
+ export function resolvePermissionsFromRoles(roleSlugs) {
242
+ const permissionSet = new Set();
243
+ for (const slug of roleSlugs) {
244
+ const permissions = getPermissionsForAdminRole(slug);
245
+ for (const p of permissions) {
246
+ permissionSet.add(p);
247
+ }
248
+ }
249
+ return [...permissionSet];
250
+ }
251
+ /**
252
+ * Check if a set of permissions includes all required permissions.
253
+ *
254
+ * @param userPermissions - The user's resolved permission set
255
+ * @param requiredPermissions - The permissions required for an operation
256
+ * @returns true if all required permissions are present
257
+ */
258
+ export function hasPermissions(userPermissions, requiredPermissions) {
259
+ return requiredPermissions.every((p) => userPermissions.includes(p));
260
+ }
261
+ //# sourceMappingURL=admin-permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-permissions.js","sourceRoot":"","sources":["../../src/lib/admin-permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Audit-log writers for best-effort events and transaction-bound administrative mutations.
3
+ *
4
+ * Most existing callers use the compatibility writer, which keeps historical best-effort
5
+ * semantics. Administrative data mutations use the transaction-bound writer so their mutation
6
+ * and durable audit row either commit together or both roll back.
7
+ *
8
+ * This module is not specific to organizations and is shared by users, clients, authentication,
9
+ * and administrative workflows.
10
+ */
11
+ import type { PoolClient } from 'pg';
12
+ /** Input data for writing an audit log entry */
13
+ export interface AuditLogEntry {
14
+ organizationId?: string;
15
+ userId?: string;
16
+ actorId?: string;
17
+ eventType: string;
18
+ eventCategory: string;
19
+ description?: string;
20
+ metadata?: Record<string, unknown>;
21
+ ipAddress?: string;
22
+ userAgent?: string;
23
+ }
24
+ /**
25
+ * Write an audit log entry to the database.
26
+ *
27
+ * Compatibility events never change the owning operation's result. Outside a database transaction
28
+ * they are written immediately; inside one they are deferred until commit. Errors are reduced to a
29
+ * privacy-safe warning and are never thrown to the caller.
30
+ *
31
+ * @param entry - Audit log entry data
32
+ */
33
+ export declare function writeAuditLog(entry: AuditLogEntry): Promise<void>;
34
+ /**
35
+ * Persist a business audit row through the caller's open transaction.
36
+ *
37
+ * Unlike the compatibility writer above, this function deliberately propagates failures. Covered
38
+ * administrative mutations must call it before commit so an unavailable durable audit boundary
39
+ * rolls back the mutation instead of creating an unaudited success.
40
+ *
41
+ * @param client - PostgreSQL client which owns the mutation transaction.
42
+ * @param entry - Closed business audit entry.
43
+ */
44
+ export declare function writeAuditLogInTransaction(client: PoolClient, entry: AuditLogEntry): Promise<void>;
45
+ //# sourceMappingURL=audit-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.d.ts","sourceRoot":"","sources":["../../src/lib/audit-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAQrC,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BvE;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CAoBf"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Audit-log writers for best-effort events and transaction-bound administrative mutations.
3
+ *
4
+ * Most existing callers use the compatibility writer, which keeps historical best-effort
5
+ * semantics. Administrative data mutations use the transaction-bound writer so their mutation
6
+ * and durable audit row either commit together or both roll back.
7
+ *
8
+ * This module is not specific to organizations and is shared by users, clients, authentication,
9
+ * and administrative workflows.
10
+ */
11
+ import { afterDatabaseCommit, getPool } from './database.js';
12
+ import { logger } from './logger.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Writer
15
+ // ---------------------------------------------------------------------------
16
+ /**
17
+ * Write an audit log entry to the database.
18
+ *
19
+ * Compatibility events never change the owning operation's result. Outside a database transaction
20
+ * they are written immediately; inside one they are deferred until commit. Errors are reduced to a
21
+ * privacy-safe warning and are never thrown to the caller.
22
+ *
23
+ * @param entry - Audit log entry data
24
+ */
25
+ export async function writeAuditLog(entry) {
26
+ await afterDatabaseCommit(async () => {
27
+ try {
28
+ const pool = getPool();
29
+ await pool.query(`INSERT INTO audit_log (
30
+ organization_id, user_id, actor_id,
31
+ event_type, event_category, description,
32
+ metadata, ip_address, user_agent
33
+ )
34
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [
35
+ entry.organizationId ?? null,
36
+ entry.userId ?? null,
37
+ entry.actorId ?? null,
38
+ entry.eventType,
39
+ entry.eventCategory,
40
+ entry.description ?? null,
41
+ entry.metadata ? JSON.stringify(entry.metadata) : '{}',
42
+ entry.ipAddress ?? null,
43
+ entry.userAgent ?? null,
44
+ ]);
45
+ }
46
+ catch {
47
+ logger.warn({ event: 'compatibility-audit-write-failed', eventType: entry.eventType }, 'Compatibility audit write failed');
48
+ }
49
+ });
50
+ }
51
+ /**
52
+ * Persist a business audit row through the caller's open transaction.
53
+ *
54
+ * Unlike the compatibility writer above, this function deliberately propagates failures. Covered
55
+ * administrative mutations must call it before commit so an unavailable durable audit boundary
56
+ * rolls back the mutation instead of creating an unaudited success.
57
+ *
58
+ * @param client - PostgreSQL client which owns the mutation transaction.
59
+ * @param entry - Closed business audit entry.
60
+ */
61
+ export async function writeAuditLogInTransaction(client, entry) {
62
+ await client.query(`INSERT INTO audit_log (
63
+ organization_id, user_id, actor_id,
64
+ event_type, event_category, description,
65
+ metadata, ip_address, user_agent
66
+ )
67
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [
68
+ entry.organizationId ?? null,
69
+ entry.userId ?? null,
70
+ entry.actorId ?? null,
71
+ entry.eventType,
72
+ entry.eventCategory,
73
+ entry.description ?? null,
74
+ entry.metadata ? JSON.stringify(entry.metadata) : '{}',
75
+ entry.ipAddress ?? null,
76
+ entry.userAgent ?? null,
77
+ ]);
78
+ }
79
+ //# sourceMappingURL=audit-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/lib/audit-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAmBrC,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAoB;IACtD,MAAM,mBAAmB,CAAC,KAAK,IAAI,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,KAAK,CACd;;;;;mDAK2C,EAC3C;gBACE,KAAK,CAAC,cAAc,IAAI,IAAI;gBAC5B,KAAK,CAAC,MAAM,IAAI,IAAI;gBACpB,KAAK,CAAC,OAAO,IAAI,IAAI;gBACrB,KAAK,CAAC,SAAS;gBACf,KAAK,CAAC,aAAa;gBACnB,KAAK,CAAC,WAAW,IAAI,IAAI;gBACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;gBACtD,KAAK,CAAC,SAAS,IAAI,IAAI;gBACvB,KAAK,CAAC,SAAS,IAAI,IAAI;aACxB,CACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CACT,EAAE,KAAK,EAAE,kCAAkC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EACzE,kCAAkC,CACnC,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,MAAkB,EAClB,KAAoB;IAEpB,MAAM,MAAM,CAAC,KAAK,CAChB;;;;;iDAK6C,EAC7C;QACE,KAAK,CAAC,cAAc,IAAI,IAAI;QAC5B,KAAK,CAAC,MAAM,IAAI,IAAI;QACpB,KAAK,CAAC,OAAO,IAAI,IAAI;QACrB,KAAK,CAAC,SAAS;QACf,KAAK,CAAC,aAAa;QACnB,KAAK,CAAC,WAAW,IAAI,IAAI;QACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;QACtD,KAAK,CAAC,SAAS,IAAI,IAAI;QACvB,KAAK,CAAC,SAAS,IAAI,IAAI;KACxB,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Branding assets service.
3
+ *
4
+ * Manages organization logo and favicon image uploads stored as PostgreSQL
5
+ * bytea. Images are validated for type, size, and content before storage.
6
+ *
7
+ * Supported formats: PNG, SVG, ICO, JPEG, WebP
8
+ * Max file size: 512 KB
9
+ *
10
+ * @module branding-assets
11
+ * @see 06-bulk-operations-branding.md
12
+ */
13
+ export type AssetType = 'logo' | 'favicon';
14
+ export interface BrandingAsset {
15
+ id: string;
16
+ organizationId: string;
17
+ assetType: AssetType;
18
+ contentType: string;
19
+ fileSize: number;
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ }
23
+ export interface BrandingAssetWithData extends BrandingAsset {
24
+ data: Buffer;
25
+ }
26
+ /**
27
+ * Upload (upsert) a branding asset for an organization.
28
+ * If an asset of the same type already exists, it is replaced.
29
+ *
30
+ * @throws Error if content type is not allowed or file too large
31
+ */
32
+ export declare function uploadAsset(organizationId: string, assetType: AssetType, contentType: string, data: Buffer): Promise<BrandingAsset>;
33
+ /**
34
+ * Get a branding asset with its binary data.
35
+ * Returns null if no asset exists.
36
+ */
37
+ export declare function getAsset(organizationId: string, assetType: AssetType): Promise<BrandingAssetWithData | null>;
38
+ /**
39
+ * List branding assets for an organization (metadata only, no binary data).
40
+ */
41
+ export declare function listAssets(organizationId: string): Promise<BrandingAsset[]>;
42
+ /**
43
+ * Delete a branding asset.
44
+ * Returns true if the asset existed and was deleted.
45
+ */
46
+ export declare function deleteAsset(organizationId: string, assetType: AssetType): Promise<boolean>;
47
+ //# sourceMappingURL=branding-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branding-assets.d.ts","sourceRoot":"","sources":["../../src/lib/branding-assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,IAAI,EAAE,MAAM,CAAC;CACd;AAqBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,CA6BxB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAWvC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAYjF;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,OAAO,CAAC,CAOlB"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Branding assets service.
3
+ *
4
+ * Manages organization logo and favicon image uploads stored as PostgreSQL
5
+ * bytea. Images are validated for type, size, and content before storage.
6
+ *
7
+ * Supported formats: PNG, SVG, ICO, JPEG, WebP
8
+ * Max file size: 512 KB
9
+ *
10
+ * @module branding-assets
11
+ * @see 06-bulk-operations-branding.md
12
+ */
13
+ import { getPool } from './database.js';
14
+ // ============================================================================
15
+ // Constants
16
+ // ============================================================================
17
+ const MAX_FILE_SIZE = 524288; // 512 KB
18
+ const ALLOWED_CONTENT_TYPES = new Set([
19
+ 'image/png',
20
+ 'image/svg+xml',
21
+ 'image/x-icon',
22
+ 'image/vnd.microsoft.icon',
23
+ 'image/jpeg',
24
+ 'image/webp',
25
+ ]);
26
+ // ============================================================================
27
+ // Service functions
28
+ // ============================================================================
29
+ /**
30
+ * Upload (upsert) a branding asset for an organization.
31
+ * If an asset of the same type already exists, it is replaced.
32
+ *
33
+ * @throws Error if content type is not allowed or file too large
34
+ */
35
+ export async function uploadAsset(organizationId, assetType, contentType, data) {
36
+ if (!ALLOWED_CONTENT_TYPES.has(contentType)) {
37
+ throw new Error(`Unsupported content type: ${contentType}. Allowed: ${[...ALLOWED_CONTENT_TYPES].join(', ')}`);
38
+ }
39
+ if (data.length === 0) {
40
+ throw new Error('Asset data cannot be empty');
41
+ }
42
+ if (data.length > MAX_FILE_SIZE) {
43
+ throw new Error(`File too large: ${data.length} bytes (max ${MAX_FILE_SIZE})`);
44
+ }
45
+ const pool = getPool();
46
+ const { rows } = await pool.query(`INSERT INTO branding_assets (organization_id, asset_type, content_type, data, file_size)
47
+ VALUES ($1, $2, $3, $4, $5)
48
+ ON CONFLICT (organization_id, asset_type) DO UPDATE SET
49
+ content_type = EXCLUDED.content_type,
50
+ data = EXCLUDED.data,
51
+ file_size = EXCLUDED.file_size,
52
+ updated_at = NOW()
53
+ RETURNING id, organization_id AS "organizationId", asset_type AS "assetType",
54
+ content_type AS "contentType", file_size AS "fileSize",
55
+ created_at AS "createdAt", updated_at AS "updatedAt"`, [organizationId, assetType, contentType, data, data.length]);
56
+ return rows[0];
57
+ }
58
+ /**
59
+ * Get a branding asset with its binary data.
60
+ * Returns null if no asset exists.
61
+ */
62
+ export async function getAsset(organizationId, assetType) {
63
+ const pool = getPool();
64
+ const { rows } = await pool.query(`SELECT id, organization_id AS "organizationId", asset_type AS "assetType",
65
+ content_type AS "contentType", data, file_size AS "fileSize",
66
+ created_at AS "createdAt", updated_at AS "updatedAt"
67
+ FROM branding_assets
68
+ WHERE organization_id = $1 AND asset_type = $2`, [organizationId, assetType]);
69
+ return rows[0] ?? null;
70
+ }
71
+ /**
72
+ * List branding assets for an organization (metadata only, no binary data).
73
+ */
74
+ export async function listAssets(organizationId) {
75
+ const pool = getPool();
76
+ const { rows } = await pool.query(`SELECT id, organization_id AS "organizationId", asset_type AS "assetType",
77
+ content_type AS "contentType", file_size AS "fileSize",
78
+ created_at AS "createdAt", updated_at AS "updatedAt"
79
+ FROM branding_assets
80
+ WHERE organization_id = $1
81
+ ORDER BY asset_type`, [organizationId]);
82
+ return rows;
83
+ }
84
+ /**
85
+ * Delete a branding asset.
86
+ * Returns true if the asset existed and was deleted.
87
+ */
88
+ export async function deleteAsset(organizationId, assetType) {
89
+ const pool = getPool();
90
+ const { rowCount } = await pool.query(`DELETE FROM branding_assets WHERE organization_id = $1 AND asset_type = $2`, [organizationId, assetType]);
91
+ return (rowCount ?? 0) > 0;
92
+ }
93
+ //# sourceMappingURL=branding-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branding-assets.js","sourceRoot":"","sources":["../../src/lib/branding-assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAsBxC,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,SAAS;AAEvC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,WAAW;IACX,eAAe;IACf,cAAc;IACd,0BAA0B;IAC1B,YAAY;IACZ,YAAY;CACb,CAAC,CAAC;AAEH,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,cAAsB,EACtB,SAAoB,EACpB,WAAmB,EACnB,IAAY;IAEZ,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,cAAc,CAAC,GAAG,qBAAqB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjH,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,eAAe,aAAa,GAAG,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;;;;;;;;oEASgE,EAChE,CAAC,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAC5D,CAAC;IAEF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,cAAsB,EACtB,SAAoB;IAEpB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;;;oDAIgD,EAChD,CAAC,cAAc,EAAE,SAAS,CAAC,CAC5B,CAAC;IACF,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,cAAsB;IACrD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;;;;yBAKqB,EACrB,CAAC,cAAc,CAAC,CACjB,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,cAAsB,EACtB,SAAoB;IAEpB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CACnC,4EAA4E,EAC5E,CAAC,cAAc,EAAE,SAAS,CAAC,CAC5B,CAAC;IACF,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Tenant-safe bulk status operations with ordered partial results.
3
+ *
4
+ * Whole-request validation completes before the first mutation. Each admitted item then owns one
5
+ * database transaction containing its lock, transition, update, and durable audit record. Domain
6
+ * rejections are isolated to that item. Dependency failures stop the operation and mark the
7
+ * current and remaining items as not attempted.
8
+ */
9
+ /** Supported entity types for bulk operations. */
10
+ export type BulkEntityType = 'organization' | 'user';
11
+ /** Supported actions across both bulk entity types. */
12
+ export type BulkAction = 'activate' | 'suspend' | 'deactivate' | 'lock' | 'unlock' | 'archive';
13
+ /** Closed public outcome for one requested item. */
14
+ export type BulkItemOutcome = 'succeeded' | 'failed' | 'not_attempted';
15
+ /** Closed public reason for an unsuccessful item. */
16
+ export type BulkItemCode = 'not_found_or_not_authorized' | 'invalid_transition' | 'not_attempted';
17
+ /** Input for a validated bulk status operation. */
18
+ export interface BulkStatusChangeInput {
19
+ readonly entityType: BulkEntityType;
20
+ readonly entityIds: readonly string[];
21
+ readonly action: BulkAction;
22
+ readonly reason?: string;
23
+ /** Required tenant scope for user operations. */
24
+ readonly organizationId?: string;
25
+ /** Authenticated administrator recorded in each committed audit entry. */
26
+ readonly actorId?: string;
27
+ }
28
+ /** Public result for one item, preserving the original compatibility fields. */
29
+ export interface BulkItemResult {
30
+ readonly id: string;
31
+ readonly success: boolean;
32
+ readonly outcome: BulkItemOutcome;
33
+ readonly code: BulkItemCode | null;
34
+ readonly error?: string;
35
+ readonly previousStatus?: string;
36
+ readonly newStatus?: string;
37
+ }
38
+ /** Ordered public summary for one bulk operation. */
39
+ export interface BulkOperationResult {
40
+ readonly total: number;
41
+ readonly succeeded: number;
42
+ readonly failed: number;
43
+ readonly results: readonly BulkItemResult[];
44
+ /** Present only when infrastructure stopped processing. */
45
+ readonly correlationId?: string;
46
+ }
47
+ /**
48
+ * Execute an ordered partial-result bulk status operation.
49
+ *
50
+ * @param input - Fully validated entity, action, scope, and actor input.
51
+ * @returns Ordered item outcomes. A dependency stop includes one server correlation ID.
52
+ */
53
+ export declare function bulkStatusChange(input: BulkStatusChangeInput): Promise<BulkOperationResult>;
54
+ //# sourceMappingURL=bulk-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-operations.d.ts","sourceRoot":"","sources":["../../src/lib/bulk-operations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,kDAAkD;AAClD,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,MAAM,CAAC;AAErD,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/F,oDAAoD;AACpD,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,eAAe,CAAC;AAEvE,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,6BAA6B,GAAG,oBAAoB,GAAG,eAAe,CAAC;AAElG,mDAAmD;AACnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAuKD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqEjG"}