@portaidentity/server 1.7.3 → 1.9.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 (494) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/applications/index.d.ts +2 -2
  3. package/dist/applications/index.d.ts.map +1 -1
  4. package/dist/applications/index.js +2 -2
  5. package/dist/applications/index.js.map +1 -1
  6. package/dist/applications/repository.d.ts +49 -4
  7. package/dist/applications/repository.d.ts.map +1 -1
  8. package/dist/applications/repository.js +148 -10
  9. package/dist/applications/repository.js.map +1 -1
  10. package/dist/applications/service.d.ts +35 -17
  11. package/dist/applications/service.d.ts.map +1 -1
  12. package/dist/applications/service.js +144 -35
  13. package/dist/applications/service.js.map +1 -1
  14. package/dist/applications/types.d.ts +1 -1
  15. package/dist/applications/types.d.ts.map +1 -1
  16. package/dist/applications/validators.d.ts +14 -0
  17. package/dist/applications/validators.d.ts.map +1 -0
  18. package/dist/applications/validators.js +14 -0
  19. package/dist/applications/validators.js.map +1 -0
  20. package/dist/auth/effective-branding.d.ts +35 -0
  21. package/dist/auth/effective-branding.d.ts.map +1 -0
  22. package/dist/auth/effective-branding.js +81 -0
  23. package/dist/auth/effective-branding.js.map +1 -0
  24. package/dist/auth/email-service.d.ts +3 -8
  25. package/dist/auth/email-service.d.ts.map +1 -1
  26. package/dist/auth/email-service.js +22 -30
  27. package/dist/auth/email-service.js.map +1 -1
  28. package/dist/auth/i18n.d.ts +5 -0
  29. package/dist/auth/i18n.d.ts.map +1 -1
  30. package/dist/auth/i18n.js +6 -5
  31. package/dist/auth/i18n.js.map +1 -1
  32. package/dist/auth/rate-limiter.d.ts +6 -10
  33. package/dist/auth/rate-limiter.d.ts.map +1 -1
  34. package/dist/auth/rate-limiter.js +12 -16
  35. package/dist/auth/rate-limiter.js.map +1 -1
  36. package/dist/auth/recovery-job-processor.d.ts.map +1 -1
  37. package/dist/auth/recovery-job-processor.js +1 -1
  38. package/dist/auth/recovery-job-processor.js.map +1 -1
  39. package/dist/auth/template-engine.d.ts +3 -1
  40. package/dist/auth/template-engine.d.ts.map +1 -1
  41. package/dist/auth/template-engine.js +1 -1
  42. package/dist/auth/template-engine.js.map +1 -1
  43. package/dist/auth/token-repository.d.ts +9 -3
  44. package/dist/auth/token-repository.d.ts.map +1 -1
  45. package/dist/auth/token-repository.js +17 -8
  46. package/dist/auth/token-repository.js.map +1 -1
  47. package/dist/cli/commands/init.d.ts +1 -1
  48. package/dist/cli/commands/init.d.ts.map +1 -1
  49. package/dist/cli/commands/init.js +12 -12
  50. package/dist/cli/commands/init.js.map +1 -1
  51. package/dist/cli/error-handler.d.ts +3 -2
  52. package/dist/cli/error-handler.d.ts.map +1 -1
  53. package/dist/cli/error-handler.js +9 -2
  54. package/dist/cli/error-handler.js.map +1 -1
  55. package/dist/cli/index.d.ts +1 -1
  56. package/dist/cli/index.d.ts.map +1 -1
  57. package/dist/cli/index.js +1 -1
  58. package/dist/cli/index.js.map +1 -1
  59. package/dist/clients/index.d.ts +1 -1
  60. package/dist/clients/index.js +1 -1
  61. package/dist/clients/repository.d.ts +24 -0
  62. package/dist/clients/repository.d.ts.map +1 -1
  63. package/dist/clients/repository.js +39 -0
  64. package/dist/clients/repository.js.map +1 -1
  65. package/dist/clients/secret-repository.d.ts +35 -8
  66. package/dist/clients/secret-repository.d.ts.map +1 -1
  67. package/dist/clients/secret-repository.js +69 -16
  68. package/dist/clients/secret-repository.js.map +1 -1
  69. package/dist/clients/secret-service.d.ts +5 -9
  70. package/dist/clients/secret-service.d.ts.map +1 -1
  71. package/dist/clients/secret-service.js +13 -22
  72. package/dist/clients/secret-service.js.map +1 -1
  73. package/dist/clients/service.d.ts +10 -13
  74. package/dist/clients/service.d.ts.map +1 -1
  75. package/dist/clients/service.js +121 -42
  76. package/dist/clients/service.js.map +1 -1
  77. package/dist/clients/types.d.ts +14 -1
  78. package/dist/clients/types.d.ts.map +1 -1
  79. package/dist/clients/types.js +1 -0
  80. package/dist/clients/types.js.map +1 -1
  81. package/dist/clients/validators.d.ts +83 -1
  82. package/dist/clients/validators.d.ts.map +1 -1
  83. package/dist/clients/validators.js +110 -0
  84. package/dist/clients/validators.js.map +1 -1
  85. package/dist/config/index.d.ts +1 -0
  86. package/dist/config/index.d.ts.map +1 -1
  87. package/dist/config/index.js +1 -0
  88. package/dist/config/index.js.map +1 -1
  89. package/dist/config/schema.d.ts +1 -0
  90. package/dist/config/schema.d.ts.map +1 -1
  91. package/dist/config/schema.js +23 -1
  92. package/dist/config/schema.js.map +1 -1
  93. package/dist/custom-claims/repository.d.ts +14 -9
  94. package/dist/custom-claims/repository.d.ts.map +1 -1
  95. package/dist/custom-claims/repository.js +38 -11
  96. package/dist/custom-claims/repository.js.map +1 -1
  97. package/dist/custom-claims/service.d.ts +11 -6
  98. package/dist/custom-claims/service.d.ts.map +1 -1
  99. package/dist/custom-claims/service.js +43 -20
  100. package/dist/custom-claims/service.js.map +1 -1
  101. package/dist/index.js +8 -2
  102. package/dist/index.js.map +1 -1
  103. package/dist/lib/admin-permissions.d.ts +12 -7
  104. package/dist/lib/admin-permissions.d.ts.map +1 -1
  105. package/dist/lib/admin-permissions.js +26 -16
  106. package/dist/lib/admin-permissions.js.map +1 -1
  107. package/dist/lib/audit-log.d.ts +2 -2
  108. package/dist/lib/audit-log.d.ts.map +1 -1
  109. package/dist/lib/audit-log.js +1 -1
  110. package/dist/lib/audit-log.js.map +1 -1
  111. package/dist/lib/authority-revocation.d.ts +18 -0
  112. package/dist/lib/authority-revocation.d.ts.map +1 -0
  113. package/dist/lib/authority-revocation.js +37 -0
  114. package/dist/lib/authority-revocation.js.map +1 -0
  115. package/dist/lib/branding-assets.d.ts +35 -5
  116. package/dist/lib/branding-assets.d.ts.map +1 -1
  117. package/dist/lib/branding-assets.js +33 -26
  118. package/dist/lib/branding-assets.js.map +1 -1
  119. package/dist/lib/bulk-operations.d.ts +1 -1
  120. package/dist/lib/bulk-operations.d.ts.map +1 -1
  121. package/dist/lib/bulk-operations.js +1 -13
  122. package/dist/lib/bulk-operations.js.map +1 -1
  123. package/dist/lib/cursor.d.ts +2 -0
  124. package/dist/lib/cursor.d.ts.map +1 -1
  125. package/dist/lib/cursor.js +2 -7
  126. package/dist/lib/cursor.js.map +1 -1
  127. package/dist/lib/database.d.ts.map +1 -1
  128. package/dist/lib/database.js +5 -0
  129. package/dist/lib/database.js.map +1 -1
  130. package/dist/lib/deletion-cleanup.d.ts +43 -0
  131. package/dist/lib/deletion-cleanup.d.ts.map +1 -0
  132. package/dist/lib/deletion-cleanup.js +207 -0
  133. package/dist/lib/deletion-cleanup.js.map +1 -0
  134. package/dist/lib/image-validator.d.ts +3 -1
  135. package/dist/lib/image-validator.d.ts.map +1 -1
  136. package/dist/lib/image-validator.js +32 -19
  137. package/dist/lib/image-validator.js.map +1 -1
  138. package/dist/lib/log-format.d.ts +20 -0
  139. package/dist/lib/log-format.d.ts.map +1 -0
  140. package/dist/lib/log-format.js +22 -0
  141. package/dist/lib/log-format.js.map +1 -0
  142. package/dist/lib/logger.d.ts +3 -1
  143. package/dist/lib/logger.d.ts.map +1 -1
  144. package/dist/lib/logger.js +21 -4
  145. package/dist/lib/logger.js.map +1 -1
  146. package/dist/lib/redis.d.ts.map +1 -1
  147. package/dist/lib/redis.js +3 -0
  148. package/dist/lib/redis.js.map +1 -1
  149. package/dist/lib/session-tracking.d.ts +73 -11
  150. package/dist/lib/session-tracking.d.ts.map +1 -1
  151. package/dist/lib/session-tracking.js +76 -32
  152. package/dist/lib/session-tracking.js.map +1 -1
  153. package/dist/lib/signing-key-crypto.d.ts.map +1 -1
  154. package/dist/lib/signing-key-crypto.js +4 -5
  155. package/dist/lib/signing-key-crypto.js.map +1 -1
  156. package/dist/lib/signing-keys.d.ts +3 -4
  157. package/dist/lib/signing-keys.d.ts.map +1 -1
  158. package/dist/lib/signing-keys.js +66 -41
  159. package/dist/lib/signing-keys.js.map +1 -1
  160. package/dist/lib/super-admin-protection.d.ts +5 -5
  161. package/dist/lib/super-admin-protection.d.ts.map +1 -1
  162. package/dist/lib/super-admin-protection.js +6 -9
  163. package/dist/lib/super-admin-protection.js.map +1 -1
  164. package/dist/lib/system-config-catalog.d.ts +268 -0
  165. package/dist/lib/system-config-catalog.d.ts.map +1 -0
  166. package/dist/lib/system-config-catalog.js +90 -0
  167. package/dist/lib/system-config-catalog.js.map +1 -0
  168. package/dist/lib/system-config.d.ts +30 -33
  169. package/dist/lib/system-config.d.ts.map +1 -1
  170. package/dist/lib/system-config.js +78 -93
  171. package/dist/lib/system-config.js.map +1 -1
  172. package/dist/lib/with-timeout.d.ts +32 -0
  173. package/dist/lib/with-timeout.d.ts.map +1 -0
  174. package/dist/lib/with-timeout.js +45 -0
  175. package/dist/lib/with-timeout.js.map +1 -0
  176. package/dist/middleware/admin-auth.d.ts +6 -5
  177. package/dist/middleware/admin-auth.d.ts.map +1 -1
  178. package/dist/middleware/admin-auth.js +30 -20
  179. package/dist/middleware/admin-auth.js.map +1 -1
  180. package/dist/middleware/admin-cors.d.ts +3 -3
  181. package/dist/middleware/admin-cors.js +3 -3
  182. package/dist/middleware/admin-mutation-audit.d.ts +3 -2
  183. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
  184. package/dist/middleware/admin-mutation-audit.js +12 -5
  185. package/dist/middleware/admin-mutation-audit.js.map +1 -1
  186. package/dist/middleware/admin-rate-limiter.d.ts +7 -8
  187. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
  188. package/dist/middleware/admin-rate-limiter.js +7 -8
  189. package/dist/middleware/admin-rate-limiter.js.map +1 -1
  190. package/dist/middleware/client-secret-hash.d.ts +10 -29
  191. package/dist/middleware/client-secret-hash.d.ts.map +1 -1
  192. package/dist/middleware/client-secret-hash.js +161 -59
  193. package/dist/middleware/client-secret-hash.js.map +1 -1
  194. package/dist/middleware/health.d.ts +17 -0
  195. package/dist/middleware/health.d.ts.map +1 -1
  196. package/dist/middleware/health.js +25 -21
  197. package/dist/middleware/health.js.map +1 -1
  198. package/dist/middleware/ready.d.ts.map +1 -1
  199. package/dist/middleware/ready.js +1 -12
  200. package/dist/middleware/ready.js.map +1 -1
  201. package/dist/middleware/require-existing-organization.d.ts +18 -0
  202. package/dist/middleware/require-existing-organization.d.ts.map +1 -0
  203. package/dist/middleware/require-existing-organization.js +38 -0
  204. package/dist/middleware/require-existing-organization.js.map +1 -0
  205. package/dist/middleware/require-permission.d.ts.map +1 -1
  206. package/dist/middleware/require-permission.js +35 -1
  207. package/dist/middleware/require-permission.js.map +1 -1
  208. package/dist/middleware/require-user-organization.d.ts.map +1 -1
  209. package/dist/middleware/require-user-organization.js +4 -2
  210. package/dist/middleware/require-user-organization.js.map +1 -1
  211. package/dist/middleware/security-headers.d.ts +18 -0
  212. package/dist/middleware/security-headers.d.ts.map +1 -1
  213. package/dist/middleware/security-headers.js +32 -1
  214. package/dist/middleware/security-headers.js.map +1 -1
  215. package/dist/middleware/tenant-resolver.d.ts +1 -2
  216. package/dist/middleware/tenant-resolver.d.ts.map +1 -1
  217. package/dist/middleware/tenant-resolver.js +1 -5
  218. package/dist/middleware/tenant-resolver.js.map +1 -1
  219. package/dist/middleware/token-rate-limiter.d.ts +37 -16
  220. package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
  221. package/dist/middleware/token-rate-limiter.js +126 -54
  222. package/dist/middleware/token-rate-limiter.js.map +1 -1
  223. package/dist/oidc/account-finder.d.ts +5 -5
  224. package/dist/oidc/account-finder.d.ts.map +1 -1
  225. package/dist/oidc/account-finder.js +31 -23
  226. package/dist/oidc/account-finder.js.map +1 -1
  227. package/dist/oidc/adapter-factory.d.ts.map +1 -1
  228. package/dist/oidc/adapter-factory.js +83 -3
  229. package/dist/oidc/adapter-factory.js.map +1 -1
  230. package/dist/oidc/configuration.d.ts +3 -8
  231. package/dist/oidc/configuration.d.ts.map +1 -1
  232. package/dist/oidc/configuration.js +67 -50
  233. package/dist/oidc/configuration.js.map +1 -1
  234. package/dist/oidc/provider.d.ts.map +1 -1
  235. package/dist/oidc/provider.js +7 -0
  236. package/dist/oidc/provider.js.map +1 -1
  237. package/dist/oidc/redis-adapter.d.ts +2 -3
  238. package/dist/oidc/redis-adapter.d.ts.map +1 -1
  239. package/dist/oidc/redis-adapter.js +54 -46
  240. package/dist/oidc/redis-adapter.js.map +1 -1
  241. package/dist/organizations/branding-url.d.ts +17 -0
  242. package/dist/organizations/branding-url.d.ts.map +1 -0
  243. package/dist/organizations/branding-url.js +38 -0
  244. package/dist/organizations/branding-url.js.map +1 -0
  245. package/dist/organizations/index.d.ts +2 -2
  246. package/dist/organizations/index.d.ts.map +1 -1
  247. package/dist/organizations/index.js +1 -1
  248. package/dist/organizations/index.js.map +1 -1
  249. package/dist/organizations/repository.d.ts +22 -32
  250. package/dist/organizations/repository.d.ts.map +1 -1
  251. package/dist/organizations/repository.js +64 -45
  252. package/dist/organizations/repository.js.map +1 -1
  253. package/dist/organizations/service.d.ts +14 -46
  254. package/dist/organizations/service.d.ts.map +1 -1
  255. package/dist/organizations/service.js +60 -112
  256. package/dist/organizations/service.js.map +1 -1
  257. package/dist/organizations/types.d.ts +1 -15
  258. package/dist/organizations/types.d.ts.map +1 -1
  259. package/dist/organizations/validators.d.ts +41 -0
  260. package/dist/organizations/validators.d.ts.map +1 -0
  261. package/dist/organizations/validators.js +48 -0
  262. package/dist/organizations/validators.js.map +1 -0
  263. package/dist/portability/apply.d.ts +15 -0
  264. package/dist/portability/apply.d.ts.map +1 -0
  265. package/dist/portability/apply.js +274 -0
  266. package/dist/portability/apply.js.map +1 -0
  267. package/dist/portability/authorization.d.ts +30 -0
  268. package/dist/portability/authorization.d.ts.map +1 -0
  269. package/dist/portability/authorization.js +130 -0
  270. package/dist/portability/authorization.js.map +1 -0
  271. package/dist/portability/cleanup.d.ts +29 -0
  272. package/dist/portability/cleanup.d.ts.map +1 -0
  273. package/dist/portability/cleanup.js +167 -0
  274. package/dist/portability/cleanup.js.map +1 -0
  275. package/dist/portability/export.d.ts +18 -0
  276. package/dist/portability/export.d.ts.map +1 -0
  277. package/dist/portability/export.js +125 -0
  278. package/dist/portability/export.js.map +1 -0
  279. package/dist/portability/import-repository.d.ts +204 -0
  280. package/dist/portability/import-repository.d.ts.map +1 -0
  281. package/dist/portability/import-repository.js +348 -0
  282. package/dist/portability/import-repository.js.map +1 -0
  283. package/dist/portability/import-user-client-writers.d.ts +40 -0
  284. package/dist/portability/import-user-client-writers.d.ts.map +1 -0
  285. package/dist/portability/import-user-client-writers.js +171 -0
  286. package/dist/portability/import-user-client-writers.js.map +1 -0
  287. package/dist/portability/index.d.ts +8 -0
  288. package/dist/portability/index.d.ts.map +1 -0
  289. package/dist/portability/index.js +8 -0
  290. package/dist/portability/index.js.map +1 -0
  291. package/dist/portability/plan-support.d.ts +137 -0
  292. package/dist/portability/plan-support.d.ts.map +1 -0
  293. package/dist/portability/plan-support.js +337 -0
  294. package/dist/portability/plan-support.js.map +1 -0
  295. package/dist/portability/plan.d.ts +34 -0
  296. package/dist/portability/plan.d.ts.map +1 -0
  297. package/dist/portability/plan.js +450 -0
  298. package/dist/portability/plan.js.map +1 -0
  299. package/dist/portability/repository.d.ts +95 -0
  300. package/dist/portability/repository.d.ts.map +1 -0
  301. package/dist/portability/repository.js +390 -0
  302. package/dist/portability/repository.js.map +1 -0
  303. package/dist/portability/schema.d.ts +591 -0
  304. package/dist/portability/schema.d.ts.map +1 -0
  305. package/dist/portability/schema.js +459 -0
  306. package/dist/portability/schema.js.map +1 -0
  307. package/dist/portability/types.d.ts +382 -0
  308. package/dist/portability/types.d.ts.map +1 -0
  309. package/dist/portability/types.js +19 -0
  310. package/dist/portability/types.js.map +1 -0
  311. package/dist/rbac/errors.d.ts +4 -0
  312. package/dist/rbac/errors.d.ts.map +1 -1
  313. package/dist/rbac/errors.js +7 -0
  314. package/dist/rbac/errors.js.map +1 -1
  315. package/dist/rbac/index.d.ts +3 -3
  316. package/dist/rbac/index.d.ts.map +1 -1
  317. package/dist/rbac/index.js +3 -3
  318. package/dist/rbac/index.js.map +1 -1
  319. package/dist/rbac/mapping-repository.d.ts +84 -9
  320. package/dist/rbac/mapping-repository.d.ts.map +1 -1
  321. package/dist/rbac/mapping-repository.js +222 -55
  322. package/dist/rbac/mapping-repository.js.map +1 -1
  323. package/dist/rbac/permission-repository.d.ts +36 -19
  324. package/dist/rbac/permission-repository.d.ts.map +1 -1
  325. package/dist/rbac/permission-repository.js +93 -35
  326. package/dist/rbac/permission-repository.js.map +1 -1
  327. package/dist/rbac/permission-service.d.ts +18 -19
  328. package/dist/rbac/permission-service.d.ts.map +1 -1
  329. package/dist/rbac/permission-service.js +100 -57
  330. package/dist/rbac/permission-service.js.map +1 -1
  331. package/dist/rbac/role-repository.d.ts +29 -24
  332. package/dist/rbac/role-repository.d.ts.map +1 -1
  333. package/dist/rbac/role-repository.js +66 -43
  334. package/dist/rbac/role-repository.js.map +1 -1
  335. package/dist/rbac/role-service.d.ts +35 -32
  336. package/dist/rbac/role-service.d.ts.map +1 -1
  337. package/dist/rbac/role-service.js +210 -96
  338. package/dist/rbac/role-service.js.map +1 -1
  339. package/dist/rbac/slugs.d.ts +16 -27
  340. package/dist/rbac/slugs.d.ts.map +1 -1
  341. package/dist/rbac/slugs.js +36 -59
  342. package/dist/rbac/slugs.js.map +1 -1
  343. package/dist/rbac/types.d.ts +2 -4
  344. package/dist/rbac/types.d.ts.map +1 -1
  345. package/dist/rbac/types.js.map +1 -1
  346. package/dist/rbac/user-role-service.d.ts +23 -24
  347. package/dist/rbac/user-role-service.d.ts.map +1 -1
  348. package/dist/rbac/user-role-service.js +117 -61
  349. package/dist/rbac/user-role-service.js.map +1 -1
  350. package/dist/routes/applications.d.ts +4 -2
  351. package/dist/routes/applications.d.ts.map +1 -1
  352. package/dist/routes/applications.js +57 -19
  353. package/dist/routes/applications.js.map +1 -1
  354. package/dist/routes/audit.js +1 -1
  355. package/dist/routes/audit.js.map +1 -1
  356. package/dist/routes/branding.d.ts +3 -3
  357. package/dist/routes/branding.d.ts.map +1 -1
  358. package/dist/routes/branding.js +44 -16
  359. package/dist/routes/branding.js.map +1 -1
  360. package/dist/routes/bulk.d.ts +0 -5
  361. package/dist/routes/bulk.d.ts.map +1 -1
  362. package/dist/routes/bulk.js +3 -5
  363. package/dist/routes/bulk.js.map +1 -1
  364. package/dist/routes/clients.d.ts +4 -4
  365. package/dist/routes/clients.d.ts.map +1 -1
  366. package/dist/routes/clients.js +113 -52
  367. package/dist/routes/clients.js.map +1 -1
  368. package/dist/routes/config.d.ts +17 -12
  369. package/dist/routes/config.d.ts.map +1 -1
  370. package/dist/routes/config.js +165 -64
  371. package/dist/routes/config.js.map +1 -1
  372. package/dist/routes/custom-claims.d.ts.map +1 -1
  373. package/dist/routes/custom-claims.js +8 -2
  374. package/dist/routes/custom-claims.js.map +1 -1
  375. package/dist/routes/exports.d.ts +2 -1
  376. package/dist/routes/exports.d.ts.map +1 -1
  377. package/dist/routes/exports.js +57 -1
  378. package/dist/routes/exports.js.map +1 -1
  379. package/dist/routes/imports.d.ts +2 -2
  380. package/dist/routes/imports.d.ts.map +1 -1
  381. package/dist/routes/imports.js +95 -40
  382. package/dist/routes/imports.js.map +1 -1
  383. package/dist/routes/interactions.d.ts.map +1 -1
  384. package/dist/routes/interactions.js +113 -87
  385. package/dist/routes/interactions.js.map +1 -1
  386. package/dist/routes/invitation.d.ts.map +1 -1
  387. package/dist/routes/invitation.js +28 -27
  388. package/dist/routes/invitation.js.map +1 -1
  389. package/dist/routes/keys.d.ts.map +1 -1
  390. package/dist/routes/keys.js +26 -13
  391. package/dist/routes/keys.js.map +1 -1
  392. package/dist/routes/magic-link.d.ts.map +1 -1
  393. package/dist/routes/magic-link.js +5 -17
  394. package/dist/routes/magic-link.js.map +1 -1
  395. package/dist/routes/organizations.d.ts +1 -2
  396. package/dist/routes/organizations.d.ts.map +1 -1
  397. package/dist/routes/organizations.js +43 -104
  398. package/dist/routes/organizations.js.map +1 -1
  399. package/dist/routes/password-reset.d.ts.map +1 -1
  400. package/dist/routes/password-reset.js +13 -35
  401. package/dist/routes/password-reset.js.map +1 -1
  402. package/dist/routes/permissions.d.ts +1 -1
  403. package/dist/routes/permissions.d.ts.map +1 -1
  404. package/dist/routes/permissions.js +58 -17
  405. package/dist/routes/permissions.js.map +1 -1
  406. package/dist/routes/public-branding.d.ts +16 -0
  407. package/dist/routes/public-branding.d.ts.map +1 -0
  408. package/dist/routes/public-branding.js +52 -0
  409. package/dist/routes/public-branding.js.map +1 -0
  410. package/dist/routes/roles.d.ts +1 -1
  411. package/dist/routes/roles.d.ts.map +1 -1
  412. package/dist/routes/roles.js +63 -21
  413. package/dist/routes/roles.js.map +1 -1
  414. package/dist/routes/sessions.d.ts.map +1 -1
  415. package/dist/routes/sessions.js +23 -12
  416. package/dist/routes/sessions.js.map +1 -1
  417. package/dist/routes/two-factor.d.ts.map +1 -1
  418. package/dist/routes/two-factor.js +91 -38
  419. package/dist/routes/two-factor.js.map +1 -1
  420. package/dist/routes/user-roles.d.ts.map +1 -1
  421. package/dist/routes/user-roles.js +56 -9
  422. package/dist/routes/user-roles.js.map +1 -1
  423. package/dist/routes/users.d.ts +4 -8
  424. package/dist/routes/users.d.ts.map +1 -1
  425. package/dist/routes/users.js +108 -265
  426. package/dist/routes/users.js.map +1 -1
  427. package/dist/server.d.ts.map +1 -1
  428. package/dist/server.js +53 -37
  429. package/dist/server.js.map +1 -1
  430. package/dist/two-factor/errors.d.ts +9 -0
  431. package/dist/two-factor/errors.d.ts.map +1 -1
  432. package/dist/two-factor/errors.js +12 -0
  433. package/dist/two-factor/errors.js.map +1 -1
  434. package/dist/two-factor/index.d.ts +5 -4
  435. package/dist/two-factor/index.d.ts.map +1 -1
  436. package/dist/two-factor/index.js +4 -4
  437. package/dist/two-factor/index.js.map +1 -1
  438. package/dist/two-factor/repository.d.ts +17 -6
  439. package/dist/two-factor/repository.d.ts.map +1 -1
  440. package/dist/two-factor/repository.js +37 -9
  441. package/dist/two-factor/repository.js.map +1 -1
  442. package/dist/two-factor/service.d.ts.map +1 -1
  443. package/dist/two-factor/service.js +26 -19
  444. package/dist/two-factor/service.js.map +1 -1
  445. package/dist/two-factor/totp.d.ts +13 -2
  446. package/dist/two-factor/totp.d.ts.map +1 -1
  447. package/dist/two-factor/totp.js +20 -7
  448. package/dist/two-factor/totp.js.map +1 -1
  449. package/dist/two-factor/types.d.ts +3 -0
  450. package/dist/two-factor/types.d.ts.map +1 -1
  451. package/dist/two-factor/types.js +5 -0
  452. package/dist/two-factor/types.js.map +1 -1
  453. package/dist/users/gdpr.d.ts +2 -40
  454. package/dist/users/gdpr.d.ts.map +1 -1
  455. package/dist/users/gdpr.js +3 -110
  456. package/dist/users/gdpr.js.map +1 -1
  457. package/dist/users/index.d.ts +5 -4
  458. package/dist/users/index.d.ts.map +1 -1
  459. package/dist/users/index.js +5 -4
  460. package/dist/users/index.js.map +1 -1
  461. package/dist/users/repository.d.ts +49 -3
  462. package/dist/users/repository.d.ts.map +1 -1
  463. package/dist/users/repository.js +169 -18
  464. package/dist/users/repository.js.map +1 -1
  465. package/dist/users/service.d.ts +19 -51
  466. package/dist/users/service.d.ts.map +1 -1
  467. package/dist/users/service.js +72 -122
  468. package/dist/users/service.js.map +1 -1
  469. package/dist/users/types.d.ts +4 -5
  470. package/dist/users/types.d.ts.map +1 -1
  471. package/dist/users/types.js.map +1 -1
  472. package/dist/users/validators.d.ts +28 -0
  473. package/dist/users/validators.d.ts.map +1 -0
  474. package/dist/users/validators.js +25 -0
  475. package/dist/users/validators.js.map +1 -0
  476. package/locales/default/en/errors.json +2 -1
  477. package/migrations/024_application_client_correction.sql +39 -0
  478. package/migrations/025_record_deletion_lifecycle.sql +26 -0
  479. package/migrations/026_simplify_user_lifecycle.sql +33 -0
  480. package/migrations/027_branding_asset_size_limits.sql +19 -0
  481. package/migrations/028_totp_replay_protection.sql +17 -0
  482. package/migrations/029_public_session_identifiers.sql +16 -0
  483. package/migrations/030_global_configuration_catalog.sql +39 -0
  484. package/migrations/031_monotonic_updated_at.sql +28 -0
  485. package/migrations/032_client_require_consent.sql +15 -0
  486. package/package.json +2 -2
  487. package/dist/lib/data-import-plan.d.ts +0 -50
  488. package/dist/lib/data-import-plan.d.ts.map +0 -1
  489. package/dist/lib/data-import-plan.js +0 -235
  490. package/dist/lib/data-import-plan.js.map +0 -1
  491. package/dist/lib/data-import.d.ts +0 -276
  492. package/dist/lib/data-import.d.ts.map +0 -1
  493. package/dist/lib/data-import.js +0 -1694
  494. package/dist/lib/data-import.js.map +0 -1
@@ -29,12 +29,21 @@ import type { Permission, CreatePermissionInput, UpdatePermissionInput } from '.
29
29
  */
30
30
  export declare function insertPermission(input: CreatePermissionInput): Promise<Permission>;
31
31
  /**
32
- * Find a permission by its UUID.
32
+ * Find a permission through its authoritative application parent.
33
33
  *
34
+ * @param applicationId - Parent application UUID
34
35
  * @param id - Permission UUID
35
36
  * @returns Permission or null if not found
36
37
  */
37
- export declare function findPermissionById(id: string): Promise<Permission | null>;
38
+ export declare function findPermissionById(applicationId: string, id: string): Promise<Permission | null>;
39
+ /**
40
+ * Lock and return a permission through its authoritative application parent.
41
+ *
42
+ * @param applicationId - Parent application UUID
43
+ * @param id - Permission UUID
44
+ * @returns Locked permission or null when the parent-child pair does not exist
45
+ */
46
+ export declare function lockPermissionById(applicationId: string, id: string): Promise<Permission | null>;
38
47
  /**
39
48
  * Find a permission by application ID and slug.
40
49
  *
@@ -49,22 +58,40 @@ export declare function findPermissionBySlug(applicationId: string, slug: string
49
58
  * Only explicitly provided fields (not undefined) are included in the
50
59
  * UPDATE statement. Null is a valid value for description (clears it).
51
60
  *
61
+ * @param applicationId - Parent application UUID
52
62
  * @param id - Permission UUID
53
63
  * @param input - Fields to update (name, description only)
54
64
  * @returns Updated permission
55
65
  * @throws Error if permission not found or no fields provided
56
66
  */
57
- export declare function updatePermission(id: string, input: UpdatePermissionInput): Promise<Permission>;
67
+ export declare function updatePermission(applicationId: string, id: string, input: UpdatePermissionInput): Promise<Permission>;
58
68
  /**
59
- * Delete a permission by ID.
69
+ * Check whether a module belongs to an application before permission creation.
60
70
  *
61
- * Returns true if a row was deleted, false if the permission didn't exist.
62
- * CASCADE constraints will automatically remove related role_permissions entries.
71
+ * The parent predicate prevents a globally valid module UUID from being attached
72
+ * to a permission owned by another application.
63
73
  *
64
- * @param id - Permission UUID
65
- * @returns true if deleted, false if not found
74
+ * @param applicationId - Parent application UUID
75
+ * @param moduleId - Module UUID supplied by the permission request
76
+ * @returns True when the module exists beneath the application
66
77
  */
67
- export declare function deletePermission(id: string): Promise<boolean>;
78
+ export declare function lockPermissionModule(applicationId: string, moduleId: string): Promise<boolean>;
79
+ /** Lock, capture, and delete a permission through its authoritative application parent. */
80
+ export declare function deletePermission(applicationId: string, permissionId: string): Promise<{
81
+ permission: Permission;
82
+ userIds: string[];
83
+ roleIds: string[];
84
+ grantIds: string[];
85
+ } | null>;
86
+ /** Lock and capture a permission without deleting it. */
87
+ export declare function capturePermissionForDeletion(applicationId: string, permissionId: string): Promise<{
88
+ permission: Permission;
89
+ userIds: string[];
90
+ roleIds: string[];
91
+ grantIds: string[];
92
+ } | null>;
93
+ /** Physically delete a permission previously locked through its parent. */
94
+ export declare function deleteCapturedPermission(applicationId: string, permissionId: string): Promise<void>;
68
95
  /**
69
96
  * List permissions for an application, optionally filtered by module.
70
97
  *
@@ -87,14 +114,4 @@ export declare function listPermissionsByApplication(applicationId: string, modu
87
114
  * @returns true if the slug already exists
88
115
  */
89
116
  export declare function permissionSlugExists(applicationId: string, slug: string): Promise<boolean>;
90
- /**
91
- * Count roles that have a specific permission assigned.
92
- *
93
- * Used by the service layer as a deletion guard: if roles have this
94
- * permission, it cannot be deleted without force=true.
95
- *
96
- * @param permissionId - Permission UUID
97
- * @returns Number of roles with this permission
98
- */
99
- export declare function countRolesWithPermission(permissionId: string): Promise<number>;
100
117
  //# sourceMappingURL=permission-repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permission-repository.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAiB,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAO1G;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBxF;AAMD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU/E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC,CA+BrB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASnE;AAMD;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAgBvB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAQlB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpF"}
1
+ {"version":3,"file":"permission-repository.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EACV,UAAU,EAEV,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBxF;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ5B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAQlB;AAMD,2FAA2F;AAC3F,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,IAAI,CAAC,CAKR;AAED,yDAAyD;AACzD,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,IAAI,CAAC,CAoDR;AAED,2EAA2E;AAC3E,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAKf;AAMD;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAgBvB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhG"}
@@ -48,18 +48,32 @@ export async function insertPermission(input) {
48
48
  // Find
49
49
  // ---------------------------------------------------------------------------
50
50
  /**
51
- * Find a permission by its UUID.
51
+ * Find a permission through its authoritative application parent.
52
52
  *
53
+ * @param applicationId - Parent application UUID
53
54
  * @param id - Permission UUID
54
55
  * @returns Permission or null if not found
55
56
  */
56
- export async function findPermissionById(id) {
57
+ export async function findPermissionById(applicationId, id) {
57
58
  const pool = getPool();
58
- const result = await pool.query('SELECT * FROM permissions WHERE id = $1', [id]);
59
+ const result = await pool.query('SELECT * FROM permissions WHERE application_id = $1 AND id = $2', [applicationId, id]);
59
60
  if (result.rows.length === 0)
60
61
  return null;
61
62
  return mapRowToPermission(result.rows[0]);
62
63
  }
64
+ /**
65
+ * Lock and return a permission through its authoritative application parent.
66
+ *
67
+ * @param applicationId - Parent application UUID
68
+ * @param id - Permission UUID
69
+ * @returns Locked permission or null when the parent-child pair does not exist
70
+ */
71
+ export async function lockPermissionById(applicationId, id) {
72
+ const result = await getPool().query(`SELECT * FROM permissions
73
+ WHERE application_id = $1 AND id = $2
74
+ FOR UPDATE`, [applicationId, id]);
75
+ return result.rows[0] ? mapRowToPermission(result.rows[0]) : null;
76
+ }
63
77
  /**
64
78
  * Find a permission by application ID and slug.
65
79
  *
@@ -83,17 +97,18 @@ export async function findPermissionBySlug(applicationId, slug) {
83
97
  * Only explicitly provided fields (not undefined) are included in the
84
98
  * UPDATE statement. Null is a valid value for description (clears it).
85
99
  *
100
+ * @param applicationId - Parent application UUID
86
101
  * @param id - Permission UUID
87
102
  * @param input - Fields to update (name, description only)
88
103
  * @returns Updated permission
89
104
  * @throws Error if permission not found or no fields provided
90
105
  */
91
- export async function updatePermission(id, input) {
106
+ export async function updatePermission(applicationId, id, input) {
92
107
  const pool = getPool();
93
108
  // Build dynamic SET clause — only name and description are updatable
94
109
  const setClauses = [];
95
- const values = [id]; // $1 is always the ID
96
- let paramIndex = 2;
110
+ const values = [applicationId, id];
111
+ let paramIndex = 3;
97
112
  if (input.name !== undefined) {
98
113
  setClauses.push(`name = $${paramIndex}`);
99
114
  values.push(input.name);
@@ -106,29 +121,89 @@ export async function updatePermission(id, input) {
106
121
  if (setClauses.length === 0) {
107
122
  throw new Error('No fields to update');
108
123
  }
109
- const sql = `UPDATE permissions SET ${setClauses.join(', ')} WHERE id = $1 RETURNING *`;
124
+ const sql = `UPDATE permissions SET ${setClauses.join(', ')}
125
+ WHERE application_id = $1 AND id = $2 RETURNING *`;
110
126
  const result = await pool.query(sql, values);
111
127
  if (result.rows.length === 0) {
112
128
  throw new Error('Permission not found');
113
129
  }
114
130
  return mapRowToPermission(result.rows[0]);
115
131
  }
116
- // ---------------------------------------------------------------------------
117
- // Delete
118
- // ---------------------------------------------------------------------------
119
132
  /**
120
- * Delete a permission by ID.
133
+ * Check whether a module belongs to an application before permission creation.
121
134
  *
122
- * Returns true if a row was deleted, false if the permission didn't exist.
123
- * CASCADE constraints will automatically remove related role_permissions entries.
135
+ * The parent predicate prevents a globally valid module UUID from being attached
136
+ * to a permission owned by another application.
124
137
  *
125
- * @param id - Permission UUID
126
- * @returns true if deleted, false if not found
138
+ * @param applicationId - Parent application UUID
139
+ * @param moduleId - Module UUID supplied by the permission request
140
+ * @returns True when the module exists beneath the application
127
141
  */
128
- export async function deletePermission(id) {
142
+ export async function lockPermissionModule(applicationId, moduleId) {
143
+ const result = await getPool().query(`SELECT id FROM application_modules
144
+ WHERE application_id = $1 AND id = $2
145
+ FOR KEY SHARE`, [applicationId, moduleId]);
146
+ return result.rows.length === 1;
147
+ }
148
+ // ---------------------------------------------------------------------------
149
+ // Delete
150
+ // ---------------------------------------------------------------------------
151
+ /** Lock, capture, and delete a permission through its authoritative application parent. */
152
+ export async function deletePermission(applicationId, permissionId) {
153
+ const capture = await capturePermissionForDeletion(applicationId, permissionId);
154
+ if (!capture)
155
+ return null;
156
+ await deleteCapturedPermission(applicationId, permissionId);
157
+ return capture;
158
+ }
159
+ /** Lock and capture a permission without deleting it. */
160
+ export async function capturePermissionForDeletion(applicationId, permissionId) {
129
161
  const pool = getPool();
130
- const result = await pool.query('DELETE FROM permissions WHERE id = $1', [id]);
131
- return (result.rowCount ?? 0) > 0;
162
+ const target = await pool.query(`SELECT * FROM permissions WHERE application_id = $1 AND id = $2 FOR UPDATE`, [applicationId, permissionId]);
163
+ if (!target.rows[0])
164
+ return null;
165
+ await pool.query(`SELECT role.id
166
+ FROM roles role
167
+ JOIN role_permissions mapping ON mapping.role_id = role.id
168
+ WHERE mapping.permission_id = $1
169
+ AND role.application_id = $2
170
+ ORDER BY role.id
171
+ FOR UPDATE OF role`, [permissionId, applicationId]);
172
+ const graph = await pool.query(`WITH affected_roles AS (
173
+ SELECT mapping.role_id
174
+ FROM role_permissions mapping
175
+ JOIN roles role ON role.id = mapping.role_id
176
+ WHERE mapping.permission_id = $1
177
+ AND role.application_id = $2
178
+ ), affected_users AS (
179
+ SELECT DISTINCT assignment.user_id FROM user_roles assignment
180
+ WHERE assignment.role_id = ANY(ARRAY(SELECT role_id FROM affected_roles))
181
+ )
182
+ SELECT
183
+ ARRAY(SELECT user_id FROM affected_users ORDER BY user_id) AS user_ids,
184
+ ARRAY(SELECT role_id FROM affected_roles ORDER BY role_id) AS role_ids,
185
+ ARRAY(
186
+ SELECT payload.id FROM oidc_payloads payload
187
+ WHERE payload.type = 'Grant'
188
+ AND payload.payload->>'accountId' = ANY(ARRAY(SELECT user_id::text FROM affected_users))
189
+ AND payload.payload->>'clientId' = ANY(ARRAY(
190
+ SELECT client_id FROM clients WHERE application_id = $2
191
+ ))
192
+ ORDER BY payload.id
193
+ ) AS grant_ids`, [permissionId, applicationId]);
194
+ return {
195
+ permission: mapRowToPermission(target.rows[0]),
196
+ userIds: graph.rows[0].user_ids,
197
+ roleIds: graph.rows[0].role_ids,
198
+ grantIds: graph.rows[0].grant_ids,
199
+ };
200
+ }
201
+ /** Physically delete a permission previously locked through its parent. */
202
+ export async function deleteCapturedPermission(applicationId, permissionId) {
203
+ await getPool().query('DELETE FROM permissions WHERE application_id = $1 AND id = $2', [
204
+ applicationId,
205
+ permissionId,
206
+ ]);
132
207
  }
133
208
  // ---------------------------------------------------------------------------
134
209
  // List
@@ -170,21 +245,4 @@ export async function permissionSlugExists(applicationId, slug) {
170
245
  const result = await pool.query('SELECT EXISTS(SELECT 1 FROM permissions WHERE application_id = $1 AND slug = $2) as exists', [applicationId, slug]);
171
246
  return result.rows[0].exists;
172
247
  }
173
- // ---------------------------------------------------------------------------
174
- // Role count (deletion guard)
175
- // ---------------------------------------------------------------------------
176
- /**
177
- * Count roles that have a specific permission assigned.
178
- *
179
- * Used by the service layer as a deletion guard: if roles have this
180
- * permission, it cannot be deleted without force=true.
181
- *
182
- * @param permissionId - Permission UUID
183
- * @returns Number of roles with this permission
184
- */
185
- export async function countRolesWithPermission(permissionId) {
186
- const pool = getPool();
187
- const result = await pool.query('SELECT COUNT(*)::int as count FROM role_permissions WHERE permission_id = $1', [permissionId]);
188
- return parseInt(result.rows[0].count, 10);
189
- }
190
248
  //# sourceMappingURL=permission-repository.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"permission-repository.js","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permission-repository.js","sourceRoot":"","sources":["../../src/rbac/permission-repository.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,8 @@
4
4
  * Orchestrates permission CRUD operations with slug format validation,
5
5
  * uniqueness checks, deletion guards, cache management, and audit logging.
6
6
  *
7
- * Permission slugs follow the module:resource:action format (e.g.,
8
- * "crm:contacts:read") and are immutable after creation — only name
9
- * and description can be updated.
7
+ * Permission slugs are application-defined claim values and are immutable after creation — only
8
+ * name and description can be updated.
10
9
  *
11
10
  * All write operations follow the pattern:
12
11
  * validate → DB operation → cache invalidate → audit log
@@ -19,8 +18,7 @@ import type { Permission, Role, CreatePermissionInput, UpdatePermissionInput } f
19
18
  /**
20
19
  * Create a new permission for an application.
21
20
  *
22
- * Validates that the slug follows the module:resource:action format
23
- * and ensures uniqueness within the application.
21
+ * Validates the exact claim value and ensures uniqueness within the application.
24
22
  *
25
23
  * @param input - Permission creation data
26
24
  * @param actorId - Optional UUID of the admin performing the action
@@ -31,10 +29,11 @@ export declare function createPermission(input: CreatePermissionInput, actorId?:
31
29
  /**
32
30
  * Find a permission by ID.
33
31
  *
32
+ * @param applicationId - Parent application UUID
34
33
  * @param id - Permission UUID
35
34
  * @returns Permission or null if not found
36
35
  */
37
- export declare function findPermissionById(id: string): Promise<Permission | null>;
36
+ export declare function findPermissionById(applicationId: string, id: string): Promise<Permission | null>;
38
37
  /**
39
38
  * Find a permission by application ID and slug.
40
39
  *
@@ -54,32 +53,32 @@ export declare function listPermissionsByApplication(applicationId: string, modu
54
53
  /**
55
54
  * Update a permission by ID (name and description only — slug is immutable).
56
55
  *
56
+ * @param applicationId - Parent application UUID
57
57
  * @param id - Permission UUID
58
58
  * @param input - Fields to update (name, description only)
59
59
  * @param actorId - Optional UUID of the admin performing the action
60
60
  * @returns Updated permission
61
61
  * @throws PermissionNotFoundError if permission doesn't exist
62
62
  */
63
- export declare function updatePermission(id: string, input: UpdatePermissionInput, actorId?: string): Promise<Permission>;
63
+ export declare function updatePermission(applicationId: string, id: string, input: UpdatePermissionInput, actorId?: string): Promise<Permission>;
64
64
  /**
65
- * Delete a permission by ID.
65
+ * Delete a permission through its authoritative application parent.
66
66
  *
67
- * By default (force=false), refuses to delete permissions that are
68
- * assigned to any role. Pass force=true to delete regardless —
69
- * CASCADE will remove role_permissions entries.
70
- *
71
- * @param id - Permission UUID
72
- * @param force - If true, delete even if assigned to roles
73
- * @param actorId - Optional UUID of the admin performing the action
74
- * @throws PermissionNotFoundError if permission doesn't exist
75
- * @throws RbacValidationError if assigned to roles and force is false
67
+ * @param applicationId - Parent application UUID.
68
+ * @param permissionId - Child permission UUID.
69
+ * @param actorId - Actor identifier used for audit attribution when applicable.
70
+ * @returns Whether the actor must authenticate again
71
+ * @throws PermissionNotFoundError when the permission is absent from the requested boundary.
76
72
  */
77
- export declare function deletePermission(id: string, force?: boolean, actorId?: string): Promise<void>;
73
+ export declare function deletePermission(applicationId: string, permissionId: string, actorId?: string): Promise<{
74
+ reauthenticationRequired: boolean;
75
+ }>;
78
76
  /**
79
77
  * Get all roles that have a specific permission assigned.
80
78
  *
79
+ * @param applicationId - Parent application UUID
81
80
  * @param permissionId - Permission UUID
82
81
  * @returns Array of roles with this permission
83
82
  */
84
- export declare function getRolesWithPermission(permissionId: string): Promise<Role[]>;
83
+ export declare function getRolesWithPermission(applicationId: string, permissionId: string): Promise<Role[]>;
85
84
  //# sourceMappingURL=permission-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permission-service.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAiBH,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAMjG;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAMD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE/E;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAmBrB;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,OAAe,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAgCf;AAMD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAElF"}
1
+ {"version":3,"file":"permission-service.d.ts","sourceRoot":"","sources":["../../src/rbac/permission-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAkBH,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgBjG;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAuCrB;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAE5B;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,wBAAwB,EAAE,OAAO,CAAA;CAAE,CAAC,CAkChD;AAMD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,EAAE,CAAC,CAIjB"}
@@ -4,9 +4,8 @@
4
4
  * Orchestrates permission CRUD operations with slug format validation,
5
5
  * uniqueness checks, deletion guards, cache management, and audit logging.
6
6
  *
7
- * Permission slugs follow the module:resource:action format (e.g.,
8
- * "crm:contacts:read") and are immutable after creation — only name
9
- * and description can be updated.
7
+ * Permission slugs are application-defined claim values and are immutable after creation — only
8
+ * name and description can be updated.
10
9
  *
11
10
  * All write operations follow the pattern:
12
11
  * validate → DB operation → cache invalidate → audit log
@@ -15,20 +14,27 @@
15
14
  * @see mapping-repository.ts — Role-permission lookups
16
15
  * @see cache.ts — Redis cache operations
17
16
  */
18
- import { insertPermission, findPermissionById as repoFindPermissionById, findPermissionBySlug as repoFindPermissionBySlug, updatePermission as repoUpdatePermission, deletePermission as repoDeletePermission, listPermissionsByApplication as repoListPermissionsByApplication, permissionSlugExists, countRolesWithPermission, } from './permission-repository.js';
17
+ import { insertPermission, findPermissionById as repoFindPermissionById, lockPermissionById, lockPermissionModule, findPermissionBySlug as repoFindPermissionBySlug, updatePermission as repoUpdatePermission, capturePermissionForDeletion, deleteCapturedPermission, listPermissionsByApplication as repoListPermissionsByApplication, permissionSlugExists, } from './permission-repository.js';
19
18
  import { getRolesWithPermission as repoGetRolesWithPermission } from './mapping-repository.js';
20
- import { invalidateAllUserRbacCaches } from './cache.js';
21
- import { validatePermissionSlug } from './slugs.js';
19
+ import { normalizeRbacSlug, validatePermissionSlug } from './slugs.js';
22
20
  import { PermissionNotFoundError, RbacValidationError } from './errors.js';
23
21
  import { writeAuditLog } from '../lib/audit-log.js';
22
+ import { getDatabaseTransactionClient } from '../lib/database.js';
23
+ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
24
+ import { registerDeletionCleanup } from '../lib/deletion-cleanup.js';
25
+ import { revokeAffectedAuthorityInTransaction } from '../lib/authority-revocation.js';
26
+ import { getApplicationBySlug } from '../applications/service.js';
27
+ import { ALL_ADMIN_PERMISSIONS } from '../lib/admin-permissions.js';
28
+ const PERMISSION_DELETED_EVENT = 'permission.deleted';
29
+ const ADMIN_APPLICATION_SLUG = 'porta-admin';
30
+ const ADMIN_PERMISSION_SLUGS = new Set(ALL_ADMIN_PERMISSIONS);
24
31
  // ---------------------------------------------------------------------------
25
32
  // Create
26
33
  // ---------------------------------------------------------------------------
27
34
  /**
28
35
  * Create a new permission for an application.
29
36
  *
30
- * Validates that the slug follows the module:resource:action format
31
- * and ensures uniqueness within the application.
37
+ * Validates the exact claim value and ensures uniqueness within the application.
32
38
  *
33
39
  * @param input - Permission creation data
34
40
  * @param actorId - Optional UUID of the admin performing the action
@@ -36,17 +42,26 @@ import { writeAuditLog } from '../lib/audit-log.js';
36
42
  * @throws RbacValidationError if slug format is invalid or already exists
37
43
  */
38
44
  export async function createPermission(input, actorId) {
39
- // Validate permission slug format (module:resource:action)
40
- if (!validatePermissionSlug(input.slug)) {
41
- throw new RbacValidationError(`Invalid permission slug format: "${input.slug}". Must follow module:resource:action pattern with at least 3 colon-separated segments.`);
45
+ const slug = normalizeRbacSlug(input.slug);
46
+ if (!validatePermissionSlug(slug)) {
47
+ throw new RbacValidationError('Invalid permission slug. Must be 1-150 characters without control characters.');
48
+ }
49
+ await guardCanonicalAdminPermission(input.applicationId, slug);
50
+ if (input.moduleId) {
51
+ if (!getDatabaseTransactionClient()) {
52
+ throw new Error('Permission module validation requires an active database transaction');
53
+ }
54
+ if (!(await lockPermissionModule(input.applicationId, input.moduleId))) {
55
+ throw new RbacValidationError('Permission module must belong to the selected application');
56
+ }
42
57
  }
43
58
  // Check slug uniqueness within the application
44
- const exists = await permissionSlugExists(input.applicationId, input.slug);
59
+ const exists = await permissionSlugExists(input.applicationId, slug);
45
60
  if (exists) {
46
- throw new RbacValidationError(`Permission slug "${input.slug}" already exists for this application.`);
61
+ throw new RbacValidationError(`Permission slug "${slug}" already exists for this application.`);
47
62
  }
48
63
  // Insert the permission
49
- const permission = await insertPermission(input);
64
+ const permission = await insertPermission({ ...input, slug });
50
65
  // Audit log (fire-and-forget)
51
66
  void writeAuditLog({
52
67
  eventType: 'permission.created',
@@ -66,11 +81,12 @@ export async function createPermission(input, actorId) {
66
81
  /**
67
82
  * Find a permission by ID.
68
83
  *
84
+ * @param applicationId - Parent application UUID
69
85
  * @param id - Permission UUID
70
86
  * @returns Permission or null if not found
71
87
  */
72
- export async function findPermissionById(id) {
73
- return repoFindPermissionById(id);
88
+ export async function findPermissionById(applicationId, id) {
89
+ return repoFindPermissionById(applicationId, id);
74
90
  }
75
91
  /**
76
92
  * Find a permission by application ID and slug.
@@ -98,26 +114,34 @@ export async function listPermissionsByApplication(applicationId, moduleId) {
98
114
  /**
99
115
  * Update a permission by ID (name and description only — slug is immutable).
100
116
  *
117
+ * @param applicationId - Parent application UUID
101
118
  * @param id - Permission UUID
102
119
  * @param input - Fields to update (name, description only)
103
120
  * @param actorId - Optional UUID of the admin performing the action
104
121
  * @returns Updated permission
105
122
  * @throws PermissionNotFoundError if permission doesn't exist
106
123
  */
107
- export async function updatePermission(id, input, actorId) {
108
- // Verify permission exists
109
- const existing = await repoFindPermissionById(id);
124
+ export async function updatePermission(applicationId, id, input, actorId) {
125
+ if (!getDatabaseTransactionClient()) {
126
+ throw new Error('Permission update requires an active database transaction');
127
+ }
128
+ const existing = await lockPermissionById(applicationId, id);
110
129
  if (!existing) {
111
130
  throw new PermissionNotFoundError(id);
112
131
  }
132
+ await guardCanonicalAdminPermission(applicationId, existing.slug);
133
+ const changed = (input.name !== undefined && input.name !== existing.name) ||
134
+ (input.description !== undefined && input.description !== existing.description);
135
+ if (!changed)
136
+ return existing;
113
137
  // Perform the update (slug is not updatable at the repository level)
114
- const updated = await repoUpdatePermission(id, input);
138
+ const updated = await repoUpdatePermission(applicationId, id, input);
115
139
  // Audit log (fire-and-forget)
116
140
  void writeAuditLog({
117
141
  eventType: 'permission.updated',
118
142
  eventCategory: 'admin',
119
143
  actorId,
120
- metadata: { permissionId: id, changes: input },
144
+ metadata: { applicationId, permissionId: id, changes: input },
121
145
  });
122
146
  return updated;
123
147
  }
@@ -125,44 +149,50 @@ export async function updatePermission(id, input, actorId) {
125
149
  // Delete
126
150
  // ---------------------------------------------------------------------------
127
151
  /**
128
- * Delete a permission by ID.
129
- *
130
- * By default (force=false), refuses to delete permissions that are
131
- * assigned to any role. Pass force=true to delete regardless —
132
- * CASCADE will remove role_permissions entries.
152
+ * Delete a permission through its authoritative application parent.
133
153
  *
134
- * @param id - Permission UUID
135
- * @param force - If true, delete even if assigned to roles
136
- * @param actorId - Optional UUID of the admin performing the action
137
- * @throws PermissionNotFoundError if permission doesn't exist
138
- * @throws RbacValidationError if assigned to roles and force is false
154
+ * @param applicationId - Parent application UUID.
155
+ * @param permissionId - Child permission UUID.
156
+ * @param actorId - Actor identifier used for audit attribution when applicable.
157
+ * @returns Whether the actor must authenticate again
158
+ * @throws PermissionNotFoundError when the permission is absent from the requested boundary.
139
159
  */
140
- export async function deletePermission(id, force = false, actorId) {
141
- // Verify permission exists
142
- const existing = await repoFindPermissionById(id);
143
- if (!existing) {
144
- throw new PermissionNotFoundError(id);
145
- }
146
- // Deletion guard: check for assigned roles
147
- if (!force) {
148
- const roleCount = await countRolesWithPermission(id);
149
- if (roleCount > 0) {
150
- throw new RbacValidationError(`Cannot delete permission "${existing.slug}": assigned to ${roleCount} role(s). Use force=true to override.`);
151
- }
152
- }
153
- // Delete the permission (CASCADE handles related records)
154
- await repoDeletePermission(id);
155
- // Invalidate user caches — permissions may have changed for users who had this
156
- if (force) {
157
- await invalidateAllUserRbacCaches();
158
- }
159
- // Audit log (fire-and-forget)
160
- void writeAuditLog({
161
- eventType: 'permission.deleted',
162
- eventCategory: 'admin',
160
+ export async function deletePermission(applicationId, permissionId, actorId) {
161
+ const transaction = getDatabaseTransactionClient();
162
+ if (!transaction)
163
+ throw new Error('Permission deletion requires an active database transaction');
164
+ const capture = await capturePermissionForDeletion(applicationId, permissionId);
165
+ if (!capture)
166
+ throw new PermissionNotFoundError(permissionId);
167
+ await guardCanonicalAdminPermission(applicationId, capture.permission.slug);
168
+ const revoked = await revokeAffectedAuthorityInTransaction(capture.userIds);
169
+ await writeAuditLogInTransaction(transaction, {
163
170
  actorId,
164
- metadata: { permissionId: id, slug: existing.slug, force },
171
+ eventType: PERMISSION_DELETED_EVENT,
172
+ eventCategory: 'admin',
173
+ metadata: {
174
+ applicationId,
175
+ permissionId,
176
+ slug: capture.permission.slug,
177
+ },
178
+ });
179
+ await deleteCapturedPermission(applicationId, permissionId);
180
+ await registerDeletionCleanup({
181
+ resource: 'permission',
182
+ targetId: permissionId,
183
+ parentId: applicationId,
184
+ userIds: capture.userIds,
185
+ clientIds: [],
186
+ publicClientIds: [],
187
+ grantIds: revoked.grantIds,
188
+ roleIds: capture.roleIds,
189
+ permissionIds: [permissionId],
190
+ claimIds: [],
191
+ applicationIds: [applicationId],
165
192
  });
193
+ return {
194
+ reauthenticationRequired: actorId !== undefined && capture.userIds.includes(actorId),
195
+ };
166
196
  }
167
197
  // ---------------------------------------------------------------------------
168
198
  // Role lookups
@@ -170,10 +200,23 @@ export async function deletePermission(id, force = false, actorId) {
170
200
  /**
171
201
  * Get all roles that have a specific permission assigned.
172
202
  *
203
+ * @param applicationId - Parent application UUID
173
204
  * @param permissionId - Permission UUID
174
205
  * @returns Array of roles with this permission
175
206
  */
176
- export async function getRolesWithPermission(permissionId) {
177
- return repoGetRolesWithPermission(permissionId);
207
+ export async function getRolesWithPermission(applicationId, permissionId) {
208
+ const permission = await repoFindPermissionById(applicationId, permissionId);
209
+ if (!permission)
210
+ throw new PermissionNotFoundError(permissionId);
211
+ return repoGetRolesWithPermission(applicationId, permissionId);
212
+ }
213
+ /** Reject generic creation or mutation of canonical Porta Admin permissions. */
214
+ async function guardCanonicalAdminPermission(applicationId, permissionSlug) {
215
+ if (!ADMIN_PERMISSION_SLUGS.has(permissionSlug))
216
+ return;
217
+ const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
218
+ if (adminApplication?.id === applicationId) {
219
+ throw new RbacValidationError('Canonical Porta Admin permissions cannot be modified');
220
+ }
178
221
  }
179
222
  //# sourceMappingURL=permission-service.js.map