@portaidentity/server 1.7.3 → 1.8.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 (487) hide show
  1. package/CHANGELOG.md +5 -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/cli/commands/init.d.ts +1 -1
  44. package/dist/cli/commands/init.d.ts.map +1 -1
  45. package/dist/cli/commands/init.js +12 -12
  46. package/dist/cli/commands/init.js.map +1 -1
  47. package/dist/cli/error-handler.d.ts +3 -2
  48. package/dist/cli/error-handler.d.ts.map +1 -1
  49. package/dist/cli/error-handler.js +9 -2
  50. package/dist/cli/error-handler.js.map +1 -1
  51. package/dist/cli/index.d.ts +1 -1
  52. package/dist/cli/index.d.ts.map +1 -1
  53. package/dist/cli/index.js +1 -1
  54. package/dist/cli/index.js.map +1 -1
  55. package/dist/clients/index.d.ts +1 -1
  56. package/dist/clients/index.js +1 -1
  57. package/dist/clients/repository.d.ts +18 -0
  58. package/dist/clients/repository.d.ts.map +1 -1
  59. package/dist/clients/repository.js +36 -0
  60. package/dist/clients/repository.js.map +1 -1
  61. package/dist/clients/secret-repository.d.ts +35 -8
  62. package/dist/clients/secret-repository.d.ts.map +1 -1
  63. package/dist/clients/secret-repository.js +69 -16
  64. package/dist/clients/secret-repository.js.map +1 -1
  65. package/dist/clients/secret-service.d.ts +5 -9
  66. package/dist/clients/secret-service.d.ts.map +1 -1
  67. package/dist/clients/secret-service.js +13 -22
  68. package/dist/clients/secret-service.js.map +1 -1
  69. package/dist/clients/service.d.ts +10 -13
  70. package/dist/clients/service.d.ts.map +1 -1
  71. package/dist/clients/service.js +112 -40
  72. package/dist/clients/service.js.map +1 -1
  73. package/dist/clients/types.d.ts +1 -1
  74. package/dist/clients/types.d.ts.map +1 -1
  75. package/dist/clients/validators.d.ts +83 -1
  76. package/dist/clients/validators.d.ts.map +1 -1
  77. package/dist/clients/validators.js +110 -0
  78. package/dist/clients/validators.js.map +1 -1
  79. package/dist/config/index.d.ts +1 -0
  80. package/dist/config/index.d.ts.map +1 -1
  81. package/dist/config/index.js +1 -0
  82. package/dist/config/index.js.map +1 -1
  83. package/dist/config/schema.d.ts +1 -0
  84. package/dist/config/schema.d.ts.map +1 -1
  85. package/dist/config/schema.js +23 -1
  86. package/dist/config/schema.js.map +1 -1
  87. package/dist/custom-claims/repository.d.ts +14 -9
  88. package/dist/custom-claims/repository.d.ts.map +1 -1
  89. package/dist/custom-claims/repository.js +38 -11
  90. package/dist/custom-claims/repository.js.map +1 -1
  91. package/dist/custom-claims/service.d.ts +11 -6
  92. package/dist/custom-claims/service.d.ts.map +1 -1
  93. package/dist/custom-claims/service.js +43 -20
  94. package/dist/custom-claims/service.js.map +1 -1
  95. package/dist/index.js +8 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/lib/admin-permissions.d.ts +12 -7
  98. package/dist/lib/admin-permissions.d.ts.map +1 -1
  99. package/dist/lib/admin-permissions.js +26 -16
  100. package/dist/lib/admin-permissions.js.map +1 -1
  101. package/dist/lib/audit-log.d.ts +2 -2
  102. package/dist/lib/audit-log.d.ts.map +1 -1
  103. package/dist/lib/audit-log.js +1 -1
  104. package/dist/lib/audit-log.js.map +1 -1
  105. package/dist/lib/authority-revocation.d.ts +18 -0
  106. package/dist/lib/authority-revocation.d.ts.map +1 -0
  107. package/dist/lib/authority-revocation.js +37 -0
  108. package/dist/lib/authority-revocation.js.map +1 -0
  109. package/dist/lib/branding-assets.d.ts +35 -5
  110. package/dist/lib/branding-assets.d.ts.map +1 -1
  111. package/dist/lib/branding-assets.js +33 -26
  112. package/dist/lib/branding-assets.js.map +1 -1
  113. package/dist/lib/bulk-operations.d.ts +1 -1
  114. package/dist/lib/bulk-operations.d.ts.map +1 -1
  115. package/dist/lib/bulk-operations.js +1 -13
  116. package/dist/lib/bulk-operations.js.map +1 -1
  117. package/dist/lib/cursor.d.ts +2 -0
  118. package/dist/lib/cursor.d.ts.map +1 -1
  119. package/dist/lib/cursor.js +2 -7
  120. package/dist/lib/cursor.js.map +1 -1
  121. package/dist/lib/database.d.ts.map +1 -1
  122. package/dist/lib/database.js +5 -0
  123. package/dist/lib/database.js.map +1 -1
  124. package/dist/lib/deletion-cleanup.d.ts +43 -0
  125. package/dist/lib/deletion-cleanup.d.ts.map +1 -0
  126. package/dist/lib/deletion-cleanup.js +207 -0
  127. package/dist/lib/deletion-cleanup.js.map +1 -0
  128. package/dist/lib/image-validator.d.ts +3 -1
  129. package/dist/lib/image-validator.d.ts.map +1 -1
  130. package/dist/lib/image-validator.js +32 -19
  131. package/dist/lib/image-validator.js.map +1 -1
  132. package/dist/lib/log-format.d.ts +20 -0
  133. package/dist/lib/log-format.d.ts.map +1 -0
  134. package/dist/lib/log-format.js +22 -0
  135. package/dist/lib/log-format.js.map +1 -0
  136. package/dist/lib/logger.d.ts +3 -1
  137. package/dist/lib/logger.d.ts.map +1 -1
  138. package/dist/lib/logger.js +21 -4
  139. package/dist/lib/logger.js.map +1 -1
  140. package/dist/lib/redis.d.ts.map +1 -1
  141. package/dist/lib/redis.js +3 -0
  142. package/dist/lib/redis.js.map +1 -1
  143. package/dist/lib/session-tracking.d.ts +73 -11
  144. package/dist/lib/session-tracking.d.ts.map +1 -1
  145. package/dist/lib/session-tracking.js +76 -32
  146. package/dist/lib/session-tracking.js.map +1 -1
  147. package/dist/lib/signing-key-crypto.d.ts.map +1 -1
  148. package/dist/lib/signing-key-crypto.js +4 -5
  149. package/dist/lib/signing-key-crypto.js.map +1 -1
  150. package/dist/lib/signing-keys.d.ts +3 -4
  151. package/dist/lib/signing-keys.d.ts.map +1 -1
  152. package/dist/lib/signing-keys.js +66 -41
  153. package/dist/lib/signing-keys.js.map +1 -1
  154. package/dist/lib/super-admin-protection.d.ts +5 -5
  155. package/dist/lib/super-admin-protection.d.ts.map +1 -1
  156. package/dist/lib/super-admin-protection.js +6 -9
  157. package/dist/lib/super-admin-protection.js.map +1 -1
  158. package/dist/lib/system-config-catalog.d.ts +268 -0
  159. package/dist/lib/system-config-catalog.d.ts.map +1 -0
  160. package/dist/lib/system-config-catalog.js +90 -0
  161. package/dist/lib/system-config-catalog.js.map +1 -0
  162. package/dist/lib/system-config.d.ts +30 -33
  163. package/dist/lib/system-config.d.ts.map +1 -1
  164. package/dist/lib/system-config.js +78 -93
  165. package/dist/lib/system-config.js.map +1 -1
  166. package/dist/lib/with-timeout.d.ts +32 -0
  167. package/dist/lib/with-timeout.d.ts.map +1 -0
  168. package/dist/lib/with-timeout.js +45 -0
  169. package/dist/lib/with-timeout.js.map +1 -0
  170. package/dist/middleware/admin-auth.d.ts +6 -5
  171. package/dist/middleware/admin-auth.d.ts.map +1 -1
  172. package/dist/middleware/admin-auth.js +30 -20
  173. package/dist/middleware/admin-auth.js.map +1 -1
  174. package/dist/middleware/admin-cors.d.ts +3 -3
  175. package/dist/middleware/admin-cors.js +3 -3
  176. package/dist/middleware/admin-mutation-audit.d.ts +3 -2
  177. package/dist/middleware/admin-mutation-audit.d.ts.map +1 -1
  178. package/dist/middleware/admin-mutation-audit.js +12 -5
  179. package/dist/middleware/admin-mutation-audit.js.map +1 -1
  180. package/dist/middleware/admin-rate-limiter.d.ts +7 -8
  181. package/dist/middleware/admin-rate-limiter.d.ts.map +1 -1
  182. package/dist/middleware/admin-rate-limiter.js +7 -8
  183. package/dist/middleware/admin-rate-limiter.js.map +1 -1
  184. package/dist/middleware/client-secret-hash.d.ts +10 -29
  185. package/dist/middleware/client-secret-hash.d.ts.map +1 -1
  186. package/dist/middleware/client-secret-hash.js +161 -59
  187. package/dist/middleware/client-secret-hash.js.map +1 -1
  188. package/dist/middleware/health.d.ts +17 -0
  189. package/dist/middleware/health.d.ts.map +1 -1
  190. package/dist/middleware/health.js +25 -21
  191. package/dist/middleware/health.js.map +1 -1
  192. package/dist/middleware/ready.d.ts.map +1 -1
  193. package/dist/middleware/ready.js +1 -12
  194. package/dist/middleware/ready.js.map +1 -1
  195. package/dist/middleware/require-existing-organization.d.ts +18 -0
  196. package/dist/middleware/require-existing-organization.d.ts.map +1 -0
  197. package/dist/middleware/require-existing-organization.js +38 -0
  198. package/dist/middleware/require-existing-organization.js.map +1 -0
  199. package/dist/middleware/require-permission.d.ts.map +1 -1
  200. package/dist/middleware/require-permission.js +35 -1
  201. package/dist/middleware/require-permission.js.map +1 -1
  202. package/dist/middleware/require-user-organization.d.ts.map +1 -1
  203. package/dist/middleware/require-user-organization.js +4 -2
  204. package/dist/middleware/require-user-organization.js.map +1 -1
  205. package/dist/middleware/security-headers.d.ts +18 -0
  206. package/dist/middleware/security-headers.d.ts.map +1 -1
  207. package/dist/middleware/security-headers.js +32 -1
  208. package/dist/middleware/security-headers.js.map +1 -1
  209. package/dist/middleware/tenant-resolver.d.ts +1 -2
  210. package/dist/middleware/tenant-resolver.d.ts.map +1 -1
  211. package/dist/middleware/tenant-resolver.js +1 -5
  212. package/dist/middleware/tenant-resolver.js.map +1 -1
  213. package/dist/middleware/token-rate-limiter.d.ts +37 -16
  214. package/dist/middleware/token-rate-limiter.d.ts.map +1 -1
  215. package/dist/middleware/token-rate-limiter.js +126 -54
  216. package/dist/middleware/token-rate-limiter.js.map +1 -1
  217. package/dist/oidc/account-finder.d.ts +5 -5
  218. package/dist/oidc/account-finder.d.ts.map +1 -1
  219. package/dist/oidc/account-finder.js +31 -23
  220. package/dist/oidc/account-finder.js.map +1 -1
  221. package/dist/oidc/adapter-factory.d.ts.map +1 -1
  222. package/dist/oidc/adapter-factory.js +83 -3
  223. package/dist/oidc/adapter-factory.js.map +1 -1
  224. package/dist/oidc/configuration.d.ts +3 -8
  225. package/dist/oidc/configuration.d.ts.map +1 -1
  226. package/dist/oidc/configuration.js +64 -50
  227. package/dist/oidc/configuration.js.map +1 -1
  228. package/dist/oidc/provider.d.ts.map +1 -1
  229. package/dist/oidc/provider.js +7 -0
  230. package/dist/oidc/provider.js.map +1 -1
  231. package/dist/oidc/redis-adapter.d.ts +2 -3
  232. package/dist/oidc/redis-adapter.d.ts.map +1 -1
  233. package/dist/oidc/redis-adapter.js +54 -46
  234. package/dist/oidc/redis-adapter.js.map +1 -1
  235. package/dist/organizations/branding-url.d.ts +17 -0
  236. package/dist/organizations/branding-url.d.ts.map +1 -0
  237. package/dist/organizations/branding-url.js +38 -0
  238. package/dist/organizations/branding-url.js.map +1 -0
  239. package/dist/organizations/index.d.ts +2 -2
  240. package/dist/organizations/index.d.ts.map +1 -1
  241. package/dist/organizations/index.js +1 -1
  242. package/dist/organizations/index.js.map +1 -1
  243. package/dist/organizations/repository.d.ts +22 -32
  244. package/dist/organizations/repository.d.ts.map +1 -1
  245. package/dist/organizations/repository.js +64 -45
  246. package/dist/organizations/repository.js.map +1 -1
  247. package/dist/organizations/service.d.ts +14 -46
  248. package/dist/organizations/service.d.ts.map +1 -1
  249. package/dist/organizations/service.js +60 -112
  250. package/dist/organizations/service.js.map +1 -1
  251. package/dist/organizations/types.d.ts +1 -15
  252. package/dist/organizations/types.d.ts.map +1 -1
  253. package/dist/organizations/validators.d.ts +41 -0
  254. package/dist/organizations/validators.d.ts.map +1 -0
  255. package/dist/organizations/validators.js +48 -0
  256. package/dist/organizations/validators.js.map +1 -0
  257. package/dist/portability/apply.d.ts +15 -0
  258. package/dist/portability/apply.d.ts.map +1 -0
  259. package/dist/portability/apply.js +274 -0
  260. package/dist/portability/apply.js.map +1 -0
  261. package/dist/portability/authorization.d.ts +30 -0
  262. package/dist/portability/authorization.d.ts.map +1 -0
  263. package/dist/portability/authorization.js +130 -0
  264. package/dist/portability/authorization.js.map +1 -0
  265. package/dist/portability/cleanup.d.ts +29 -0
  266. package/dist/portability/cleanup.d.ts.map +1 -0
  267. package/dist/portability/cleanup.js +167 -0
  268. package/dist/portability/cleanup.js.map +1 -0
  269. package/dist/portability/export.d.ts +18 -0
  270. package/dist/portability/export.d.ts.map +1 -0
  271. package/dist/portability/export.js +125 -0
  272. package/dist/portability/export.js.map +1 -0
  273. package/dist/portability/import-repository.d.ts +204 -0
  274. package/dist/portability/import-repository.d.ts.map +1 -0
  275. package/dist/portability/import-repository.js +347 -0
  276. package/dist/portability/import-repository.js.map +1 -0
  277. package/dist/portability/import-user-client-writers.d.ts +40 -0
  278. package/dist/portability/import-user-client-writers.d.ts.map +1 -0
  279. package/dist/portability/import-user-client-writers.js +168 -0
  280. package/dist/portability/import-user-client-writers.js.map +1 -0
  281. package/dist/portability/index.d.ts +8 -0
  282. package/dist/portability/index.d.ts.map +1 -0
  283. package/dist/portability/index.js +8 -0
  284. package/dist/portability/index.js.map +1 -0
  285. package/dist/portability/plan-support.d.ts +137 -0
  286. package/dist/portability/plan-support.d.ts.map +1 -0
  287. package/dist/portability/plan-support.js +336 -0
  288. package/dist/portability/plan-support.js.map +1 -0
  289. package/dist/portability/plan.d.ts +34 -0
  290. package/dist/portability/plan.d.ts.map +1 -0
  291. package/dist/portability/plan.js +450 -0
  292. package/dist/portability/plan.js.map +1 -0
  293. package/dist/portability/repository.d.ts +95 -0
  294. package/dist/portability/repository.d.ts.map +1 -0
  295. package/dist/portability/repository.js +388 -0
  296. package/dist/portability/repository.js.map +1 -0
  297. package/dist/portability/schema.d.ts +589 -0
  298. package/dist/portability/schema.d.ts.map +1 -0
  299. package/dist/portability/schema.js +458 -0
  300. package/dist/portability/schema.js.map +1 -0
  301. package/dist/portability/types.d.ts +381 -0
  302. package/dist/portability/types.d.ts.map +1 -0
  303. package/dist/portability/types.js +19 -0
  304. package/dist/portability/types.js.map +1 -0
  305. package/dist/rbac/errors.d.ts +4 -0
  306. package/dist/rbac/errors.d.ts.map +1 -1
  307. package/dist/rbac/errors.js +7 -0
  308. package/dist/rbac/errors.js.map +1 -1
  309. package/dist/rbac/index.d.ts +3 -3
  310. package/dist/rbac/index.d.ts.map +1 -1
  311. package/dist/rbac/index.js +3 -3
  312. package/dist/rbac/index.js.map +1 -1
  313. package/dist/rbac/mapping-repository.d.ts +84 -9
  314. package/dist/rbac/mapping-repository.d.ts.map +1 -1
  315. package/dist/rbac/mapping-repository.js +222 -55
  316. package/dist/rbac/mapping-repository.js.map +1 -1
  317. package/dist/rbac/permission-repository.d.ts +36 -19
  318. package/dist/rbac/permission-repository.d.ts.map +1 -1
  319. package/dist/rbac/permission-repository.js +93 -35
  320. package/dist/rbac/permission-repository.js.map +1 -1
  321. package/dist/rbac/permission-service.d.ts +18 -19
  322. package/dist/rbac/permission-service.d.ts.map +1 -1
  323. package/dist/rbac/permission-service.js +100 -57
  324. package/dist/rbac/permission-service.js.map +1 -1
  325. package/dist/rbac/role-repository.d.ts +29 -24
  326. package/dist/rbac/role-repository.d.ts.map +1 -1
  327. package/dist/rbac/role-repository.js +66 -43
  328. package/dist/rbac/role-repository.js.map +1 -1
  329. package/dist/rbac/role-service.d.ts +35 -32
  330. package/dist/rbac/role-service.d.ts.map +1 -1
  331. package/dist/rbac/role-service.js +210 -96
  332. package/dist/rbac/role-service.js.map +1 -1
  333. package/dist/rbac/slugs.d.ts +16 -27
  334. package/dist/rbac/slugs.d.ts.map +1 -1
  335. package/dist/rbac/slugs.js +36 -59
  336. package/dist/rbac/slugs.js.map +1 -1
  337. package/dist/rbac/types.d.ts +2 -4
  338. package/dist/rbac/types.d.ts.map +1 -1
  339. package/dist/rbac/types.js.map +1 -1
  340. package/dist/rbac/user-role-service.d.ts +23 -24
  341. package/dist/rbac/user-role-service.d.ts.map +1 -1
  342. package/dist/rbac/user-role-service.js +117 -61
  343. package/dist/rbac/user-role-service.js.map +1 -1
  344. package/dist/routes/applications.d.ts +4 -2
  345. package/dist/routes/applications.d.ts.map +1 -1
  346. package/dist/routes/applications.js +57 -19
  347. package/dist/routes/applications.js.map +1 -1
  348. package/dist/routes/audit.js +1 -1
  349. package/dist/routes/audit.js.map +1 -1
  350. package/dist/routes/branding.d.ts +3 -3
  351. package/dist/routes/branding.d.ts.map +1 -1
  352. package/dist/routes/branding.js +44 -16
  353. package/dist/routes/branding.js.map +1 -1
  354. package/dist/routes/bulk.d.ts +0 -5
  355. package/dist/routes/bulk.d.ts.map +1 -1
  356. package/dist/routes/bulk.js +3 -5
  357. package/dist/routes/bulk.js.map +1 -1
  358. package/dist/routes/clients.d.ts +4 -4
  359. package/dist/routes/clients.d.ts.map +1 -1
  360. package/dist/routes/clients.js +111 -52
  361. package/dist/routes/clients.js.map +1 -1
  362. package/dist/routes/config.d.ts +17 -12
  363. package/dist/routes/config.d.ts.map +1 -1
  364. package/dist/routes/config.js +165 -64
  365. package/dist/routes/config.js.map +1 -1
  366. package/dist/routes/custom-claims.d.ts.map +1 -1
  367. package/dist/routes/custom-claims.js +8 -2
  368. package/dist/routes/custom-claims.js.map +1 -1
  369. package/dist/routes/exports.d.ts +2 -1
  370. package/dist/routes/exports.d.ts.map +1 -1
  371. package/dist/routes/exports.js +57 -1
  372. package/dist/routes/exports.js.map +1 -1
  373. package/dist/routes/imports.d.ts +2 -2
  374. package/dist/routes/imports.d.ts.map +1 -1
  375. package/dist/routes/imports.js +95 -40
  376. package/dist/routes/imports.js.map +1 -1
  377. package/dist/routes/interactions.d.ts.map +1 -1
  378. package/dist/routes/interactions.js +16 -34
  379. package/dist/routes/interactions.js.map +1 -1
  380. package/dist/routes/invitation.d.ts.map +1 -1
  381. package/dist/routes/invitation.js +10 -23
  382. package/dist/routes/invitation.js.map +1 -1
  383. package/dist/routes/keys.d.ts.map +1 -1
  384. package/dist/routes/keys.js +26 -13
  385. package/dist/routes/keys.js.map +1 -1
  386. package/dist/routes/magic-link.d.ts.map +1 -1
  387. package/dist/routes/magic-link.js +5 -17
  388. package/dist/routes/magic-link.js.map +1 -1
  389. package/dist/routes/organizations.d.ts +1 -2
  390. package/dist/routes/organizations.d.ts.map +1 -1
  391. package/dist/routes/organizations.js +43 -104
  392. package/dist/routes/organizations.js.map +1 -1
  393. package/dist/routes/password-reset.d.ts.map +1 -1
  394. package/dist/routes/password-reset.js +13 -35
  395. package/dist/routes/password-reset.js.map +1 -1
  396. package/dist/routes/permissions.d.ts +1 -1
  397. package/dist/routes/permissions.d.ts.map +1 -1
  398. package/dist/routes/permissions.js +58 -17
  399. package/dist/routes/permissions.js.map +1 -1
  400. package/dist/routes/public-branding.d.ts +16 -0
  401. package/dist/routes/public-branding.d.ts.map +1 -0
  402. package/dist/routes/public-branding.js +52 -0
  403. package/dist/routes/public-branding.js.map +1 -0
  404. package/dist/routes/roles.d.ts +1 -1
  405. package/dist/routes/roles.d.ts.map +1 -1
  406. package/dist/routes/roles.js +63 -21
  407. package/dist/routes/roles.js.map +1 -1
  408. package/dist/routes/sessions.d.ts.map +1 -1
  409. package/dist/routes/sessions.js +23 -12
  410. package/dist/routes/sessions.js.map +1 -1
  411. package/dist/routes/two-factor.d.ts.map +1 -1
  412. package/dist/routes/two-factor.js +91 -38
  413. package/dist/routes/two-factor.js.map +1 -1
  414. package/dist/routes/user-roles.d.ts.map +1 -1
  415. package/dist/routes/user-roles.js +56 -9
  416. package/dist/routes/user-roles.js.map +1 -1
  417. package/dist/routes/users.d.ts +4 -8
  418. package/dist/routes/users.d.ts.map +1 -1
  419. package/dist/routes/users.js +108 -265
  420. package/dist/routes/users.js.map +1 -1
  421. package/dist/server.d.ts.map +1 -1
  422. package/dist/server.js +53 -37
  423. package/dist/server.js.map +1 -1
  424. package/dist/two-factor/errors.d.ts +9 -0
  425. package/dist/two-factor/errors.d.ts.map +1 -1
  426. package/dist/two-factor/errors.js +12 -0
  427. package/dist/two-factor/errors.js.map +1 -1
  428. package/dist/two-factor/index.d.ts +5 -4
  429. package/dist/two-factor/index.d.ts.map +1 -1
  430. package/dist/two-factor/index.js +4 -4
  431. package/dist/two-factor/index.js.map +1 -1
  432. package/dist/two-factor/repository.d.ts +17 -6
  433. package/dist/two-factor/repository.d.ts.map +1 -1
  434. package/dist/two-factor/repository.js +37 -9
  435. package/dist/two-factor/repository.js.map +1 -1
  436. package/dist/two-factor/service.d.ts.map +1 -1
  437. package/dist/two-factor/service.js +26 -19
  438. package/dist/two-factor/service.js.map +1 -1
  439. package/dist/two-factor/totp.d.ts +13 -2
  440. package/dist/two-factor/totp.d.ts.map +1 -1
  441. package/dist/two-factor/totp.js +20 -7
  442. package/dist/two-factor/totp.js.map +1 -1
  443. package/dist/two-factor/types.d.ts +3 -0
  444. package/dist/two-factor/types.d.ts.map +1 -1
  445. package/dist/two-factor/types.js +5 -0
  446. package/dist/two-factor/types.js.map +1 -1
  447. package/dist/users/gdpr.d.ts +2 -40
  448. package/dist/users/gdpr.d.ts.map +1 -1
  449. package/dist/users/gdpr.js +3 -110
  450. package/dist/users/gdpr.js.map +1 -1
  451. package/dist/users/index.d.ts +5 -4
  452. package/dist/users/index.d.ts.map +1 -1
  453. package/dist/users/index.js +5 -4
  454. package/dist/users/index.js.map +1 -1
  455. package/dist/users/repository.d.ts +49 -3
  456. package/dist/users/repository.d.ts.map +1 -1
  457. package/dist/users/repository.js +169 -18
  458. package/dist/users/repository.js.map +1 -1
  459. package/dist/users/service.d.ts +19 -51
  460. package/dist/users/service.d.ts.map +1 -1
  461. package/dist/users/service.js +72 -122
  462. package/dist/users/service.js.map +1 -1
  463. package/dist/users/types.d.ts +4 -5
  464. package/dist/users/types.d.ts.map +1 -1
  465. package/dist/users/types.js.map +1 -1
  466. package/dist/users/validators.d.ts +28 -0
  467. package/dist/users/validators.d.ts.map +1 -0
  468. package/dist/users/validators.js +25 -0
  469. package/dist/users/validators.js.map +1 -0
  470. package/locales/default/en/errors.json +2 -1
  471. package/migrations/024_application_client_correction.sql +39 -0
  472. package/migrations/025_record_deletion_lifecycle.sql +26 -0
  473. package/migrations/026_simplify_user_lifecycle.sql +33 -0
  474. package/migrations/027_branding_asset_size_limits.sql +19 -0
  475. package/migrations/028_totp_replay_protection.sql +17 -0
  476. package/migrations/029_public_session_identifiers.sql +16 -0
  477. package/migrations/030_global_configuration_catalog.sql +39 -0
  478. package/migrations/031_monotonic_updated_at.sql +28 -0
  479. package/package.json +2 -2
  480. package/dist/lib/data-import-plan.d.ts +0 -50
  481. package/dist/lib/data-import-plan.d.ts.map +0 -1
  482. package/dist/lib/data-import-plan.js +0 -235
  483. package/dist/lib/data-import-plan.js.map +0 -1
  484. package/dist/lib/data-import.d.ts +0 -276
  485. package/dist/lib/data-import.d.ts.map +0 -1
  486. package/dist/lib/data-import.js +0 -1694
  487. package/dist/lib/data-import.js.map +0 -1
@@ -1,26 +1,31 @@
1
1
  /**
2
2
  * Role service — business logic for role management.
3
3
  *
4
- * Orchestrates role CRUD operations with slug validation, uniqueness
5
- * checks, deletion guards, cache management, and audit logging.
6
- * Also handles role-permission assignment operations.
7
- *
8
- * All write operations follow the pattern:
9
- * validate → DB operation → cache invalidate/re-cache → audit log
10
- *
11
- * Uses fire-and-forget audit logging — audit failures never block
12
- * the primary operation.
4
+ * Orchestrates application-scoped role CRUD and direct permission mappings.
5
+ * Authority reductions revoke affected database state in the request transaction;
6
+ * cache cleanup runs after commit. Canonical Porta Admin roles and mappings are
7
+ * protected from generic mutation.
13
8
  *
14
9
  * @see role-repository.ts — Database operations
15
10
  * @see mapping-repository.ts — Role-permission join table operations
16
11
  * @see cache.ts — Redis cache operations
17
12
  */
18
- import { insertRole, findRoleById as repoFindRoleById, findRoleBySlug as repoFindRoleBySlug, updateRole as repoUpdateRole, deleteRole as repoDeleteRole, listRolesByApplication as repoListRolesByApplication, roleSlugExists, countUsersWithRole, } from './role-repository.js';
19
- import { assignPermissionsToRole as repoAssignPermissions, removePermissionsFromRole as repoRemovePermissions, getPermissionsForRole as repoGetPermissionsForRole, } from './mapping-repository.js';
20
- import { getCachedRole, setCachedRole, invalidateRoleCache, invalidateAllUserRbacCaches, } from './cache.js';
21
- import { generateRoleSlug, validateRoleSlug } from './slugs.js';
13
+ import { insertRole, findRoleById as repoFindRoleById, lockRoleById, findRoleBySlug as repoFindRoleBySlug, updateRole as repoUpdateRole, captureRoleForDeletion, deleteCapturedRole, listRolesByApplication as repoListRolesByApplication, roleSlugExists, } from './role-repository.js';
14
+ import { assignPermissionsToRole as repoAssignPermissions, removePermissionsFromRole as repoRemovePermissions, getPermissionsForRole as repoGetPermissionsForRole, getUserIdsForRole, lockRolePermissionTargets, } from './mapping-repository.js';
15
+ import { getCachedRole, setCachedRole } from './cache.js';
16
+ import { generateRoleSlug, normalizeRbacSlug, validateRoleSlug } from './slugs.js';
22
17
  import { RoleNotFoundError, RbacValidationError } from './errors.js';
23
18
  import { writeAuditLog } from '../lib/audit-log.js';
19
+ import { getDatabaseTransactionClient } from '../lib/database.js';
20
+ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
21
+ import { registerAuthorityCleanup, registerDeletionCleanup } from '../lib/deletion-cleanup.js';
22
+ import { revokeAffectedAuthorityInTransaction } from '../lib/authority-revocation.js';
23
+ import { getApplicationBySlug } from '../applications/service.js';
24
+ import { ALL_ADMIN_PERMISSIONS, ALL_ADMIN_ROLES, LEGACY_ADMIN_ROLE, } from '../lib/admin-permissions.js';
25
+ const ROLE_DELETED_EVENT = 'role.deleted';
26
+ const ADMIN_APPLICATION_SLUG = 'porta-admin';
27
+ const ADMIN_ROLE_SLUGS = new Set([...ALL_ADMIN_ROLES.map((role) => role.slug), LEGACY_ADMIN_ROLE]);
28
+ const ADMIN_PERMISSION_SLUGS = new Set(ALL_ADMIN_PERMISSIONS);
24
29
  // ---------------------------------------------------------------------------
25
30
  // Create
26
31
  // ---------------------------------------------------------------------------
@@ -37,11 +42,12 @@ import { writeAuditLog } from '../lib/audit-log.js';
37
42
  */
38
43
  export async function createRole(input, actorId) {
39
44
  // Generate slug from name if not provided
40
- const slug = input.slug ?? generateRoleSlug(input.name);
45
+ const slug = normalizeRbacSlug(input.slug ?? generateRoleSlug(input.name));
41
46
  // Validate slug format
42
47
  if (!validateRoleSlug(slug)) {
43
- throw new RbacValidationError(`Invalid role slug format: "${slug}". Must be 1-100 chars, lowercase alphanumeric and hyphens.`);
48
+ throw new RbacValidationError('Invalid role slug. Must be 1-100 characters without control characters.');
44
49
  }
50
+ await guardCanonicalAdminRole(input.applicationId, slug);
45
51
  // Check slug uniqueness within the application
46
52
  const exists = await roleSlugExists(input.applicationId, slug);
47
53
  if (exists) {
@@ -66,16 +72,17 @@ export async function createRole(input, actorId) {
66
72
  /**
67
73
  * Find a role by ID. Cache-first, falls back to DB.
68
74
  *
75
+ * @param applicationId - Parent application UUID
69
76
  * @param id - Role UUID
70
77
  * @returns Role or null if not found
71
78
  */
72
- export async function findRoleById(id) {
79
+ export async function findRoleById(applicationId, id) {
73
80
  // Try cache first
74
81
  const cached = await getCachedRole(id);
75
82
  if (cached)
76
- return cached;
83
+ return cached.applicationId === applicationId ? cached : null;
77
84
  // Cache miss — query DB
78
- const role = await repoFindRoleById(id);
85
+ const role = await repoFindRoleById(applicationId, id);
79
86
  if (role) {
80
87
  // Cache for future lookups
81
88
  await setCachedRole(role);
@@ -108,90 +115,125 @@ export async function listRolesByApplication(applicationId) {
108
115
  * Update a role by ID.
109
116
  *
110
117
  * If the slug is being changed, validates the new slug format and
111
- * checks uniqueness within the application. Invalidates and re-caches
112
- * the role after update.
118
+ * checks uniqueness within the application. An actual slug change revokes
119
+ * authority for users assigned to the role; metadata-only changes do not.
113
120
  *
121
+ * @param applicationId - Parent application UUID
114
122
  * @param id - Role UUID
115
123
  * @param input - Fields to update
116
124
  * @param actorId - Optional UUID of the admin performing the action
117
- * @returns Updated role
125
+ * @returns Updated role and whether the actor must authenticate again
118
126
  * @throws RoleNotFoundError if role doesn't exist
119
127
  * @throws RbacValidationError if new slug is invalid or already exists
120
128
  */
121
- export async function updateRole(id, input, actorId) {
122
- // Verify role exists (needed for applicationId if slug is changing)
123
- const existing = await repoFindRoleById(id);
129
+ export async function updateRole(applicationId, id, input, actorId) {
130
+ const transaction = getDatabaseTransactionClient();
131
+ if (!transaction)
132
+ throw new Error('Role update requires an active database transaction');
133
+ const existing = await lockRoleById(applicationId, id);
124
134
  if (!existing) {
125
135
  throw new RoleNotFoundError(id);
126
136
  }
137
+ await guardCanonicalAdminRole(existing.applicationId, existing.slug);
138
+ const normalizedInput = input.slug === undefined ? input : { ...input, slug: normalizeRbacSlug(input.slug) };
139
+ const changed = (input.name !== undefined && input.name !== existing.name) ||
140
+ (normalizedInput.slug !== undefined && normalizedInput.slug !== existing.slug) ||
141
+ (input.description !== undefined && input.description !== existing.description);
142
+ if (!changed)
143
+ return { role: existing, reauthenticationRequired: false };
127
144
  // If slug is changing, validate format and uniqueness
128
- if (input.slug !== undefined && input.slug !== existing.slug) {
129
- if (!validateRoleSlug(input.slug)) {
130
- throw new RbacValidationError(`Invalid role slug format: "${input.slug}". Must be 1-100 chars, lowercase alphanumeric and hyphens.`);
145
+ const requestedSlug = normalizedInput.slug;
146
+ const slugChanged = requestedSlug !== undefined && requestedSlug !== existing.slug;
147
+ if (slugChanged) {
148
+ await guardCanonicalAdminRole(applicationId, requestedSlug);
149
+ if (!validateRoleSlug(requestedSlug)) {
150
+ throw new RbacValidationError('Invalid role slug. Must be 1-100 characters without control characters.');
131
151
  }
132
- const slugTaken = await roleSlugExists(existing.applicationId, input.slug, id);
152
+ const slugTaken = await roleSlugExists(applicationId, requestedSlug, id);
133
153
  if (slugTaken) {
134
- throw new RbacValidationError(`Role slug "${input.slug}" already exists for this application.`);
154
+ throw new RbacValidationError(`Role slug "${requestedSlug}" already exists for this application.`);
135
155
  }
136
156
  }
137
- // Perform the update
138
- const updated = await repoUpdateRole(id, input);
139
- // Invalidate old cache and store updated role
140
- await invalidateRoleCache(id);
141
- await setCachedRole(updated);
142
- // Audit log (fire-and-forget)
143
- void writeAuditLog({
144
- eventType: 'role.updated',
145
- eventCategory: 'admin',
146
- actorId,
147
- metadata: { roleId: id, changes: input },
157
+ const userIds = slugChanged ? await getUserIdsForRole(applicationId, id) : [];
158
+ const revoked = slugChanged
159
+ ? await revokeAffectedAuthorityInTransaction(userIds)
160
+ : { grantIds: [] };
161
+ const updated = await repoUpdateRole(applicationId, id, normalizedInput);
162
+ if (slugChanged) {
163
+ await writeAuditLogInTransaction(transaction, {
164
+ eventType: 'role.updated',
165
+ eventCategory: 'admin',
166
+ actorId,
167
+ metadata: { applicationId, roleId: id, changes: normalizedInput },
168
+ });
169
+ }
170
+ else {
171
+ void writeAuditLog({
172
+ eventType: 'role.updated',
173
+ eventCategory: 'admin',
174
+ actorId,
175
+ metadata: { applicationId, roleId: id, changes: normalizedInput },
176
+ });
177
+ }
178
+ await registerAuthorityCleanup({
179
+ userIds,
180
+ grantIds: revoked.grantIds,
181
+ roleIds: [id],
182
+ revokeOidcState: slugChanged,
148
183
  });
149
- return updated;
184
+ return {
185
+ role: updated,
186
+ reauthenticationRequired: slugChanged && actorId !== undefined && userIds.includes(actorId),
187
+ };
150
188
  }
151
189
  // ---------------------------------------------------------------------------
152
190
  // Delete
153
191
  // ---------------------------------------------------------------------------
154
192
  /**
155
- * Delete a role by ID.
193
+ * Delete a role through its authoritative application parent.
156
194
  *
157
- * By default (force=false), refuses to delete roles that have users
158
- * assigned. Pass force=true to delete regardless — CASCADE will
159
- * remove user_roles and role_permissions entries.
160
- *
161
- * @param id - Role UUID
162
- * @param force - If true, delete even if users are assigned
163
- * @param actorId - Optional UUID of the admin performing the action
164
- * @throws RoleNotFoundError if role doesn't exist
165
- * @throws RbacValidationError if users are assigned and force is false
195
+ * @param applicationId - Parent application UUID.
196
+ * @param roleId - Child role UUID.
197
+ * @param actorId - Actor identifier used for audit attribution when applicable.
198
+ * @returns Whether the actor must authenticate again
199
+ * @throws RoleNotFoundError when the selected role does not exist within the requested boundary.
166
200
  */
167
- export async function deleteRole(id, force = false, actorId) {
168
- // Verify role exists
169
- const existing = await repoFindRoleById(id);
170
- if (!existing) {
171
- throw new RoleNotFoundError(id);
172
- }
173
- // Deletion guard: check for assigned users
174
- if (!force) {
175
- const userCount = await countUsersWithRole(id);
176
- if (userCount > 0) {
177
- throw new RbacValidationError(`Cannot delete role "${existing.slug}": ${userCount} user(s) still assigned. Use force=true to override.`);
178
- }
179
- }
180
- // Delete the role (CASCADE handles related records)
181
- await repoDeleteRole(id);
182
- // Invalidate caches
183
- await invalidateRoleCache(id);
184
- // User caches may be stale if role had users (force=true case)
185
- if (force) {
186
- await invalidateAllUserRbacCaches();
187
- }
188
- // Audit log (fire-and-forget)
189
- void writeAuditLog({
190
- eventType: 'role.deleted',
191
- eventCategory: 'admin',
201
+ export async function deleteRole(applicationId, roleId, actorId) {
202
+ const transaction = getDatabaseTransactionClient();
203
+ if (!transaction)
204
+ throw new Error('Role deletion requires an active database transaction');
205
+ const capture = await captureRoleForDeletion(applicationId, roleId);
206
+ if (!capture)
207
+ throw new RoleNotFoundError(roleId);
208
+ await guardCanonicalAdminRole(capture.role.applicationId, capture.role.slug);
209
+ const revoked = await revokeAffectedAuthorityInTransaction(capture.userIds);
210
+ await writeAuditLogInTransaction(transaction, {
192
211
  actorId,
193
- metadata: { roleId: id, slug: existing.slug, force },
212
+ eventType: ROLE_DELETED_EVENT,
213
+ eventCategory: 'admin',
214
+ metadata: {
215
+ applicationId,
216
+ roleId,
217
+ slug: capture.role.slug,
218
+ },
219
+ });
220
+ await deleteCapturedRole(applicationId, roleId);
221
+ await registerDeletionCleanup({
222
+ resource: 'role',
223
+ targetId: roleId,
224
+ parentId: applicationId,
225
+ userIds: capture.userIds,
226
+ clientIds: [],
227
+ publicClientIds: [],
228
+ grantIds: revoked.grantIds,
229
+ roleIds: [roleId],
230
+ permissionIds: capture.permissionIds,
231
+ claimIds: [],
232
+ applicationIds: [applicationId],
194
233
  });
234
+ return {
235
+ reauthenticationRequired: actorId !== undefined && capture.userIds.includes(actorId),
236
+ };
195
237
  }
196
238
  // ---------------------------------------------------------------------------
197
239
  // Role-Permission management
@@ -199,58 +241,130 @@ export async function deleteRole(id, force = false, actorId) {
199
241
  /**
200
242
  * Assign permissions to a role.
201
243
  *
202
- * Delegates to the mapping repository for bulk insert. Invalidates
203
- * all user RBAC caches since user permissions may have changed.
244
+ * Validates every permission against the role's application and schedules
245
+ * cache invalidation only for users assigned to the role.
204
246
  *
247
+ * @param applicationId - Parent application UUID
205
248
  * @param roleId - Role UUID
206
249
  * @param permissionIds - Array of permission UUIDs to assign
207
250
  * @param actorId - Optional UUID of the admin performing the action
208
251
  */
209
- export async function assignPermissionsToRole(roleId, permissionIds, actorId) {
252
+ export async function assignPermissionsToRole(applicationId, roleId, permissionIds, actorId) {
210
253
  if (permissionIds.length === 0)
211
254
  return;
212
- await repoAssignPermissions(roleId, permissionIds);
213
- // Invalidate all user RBAC caches — permissions through roles may have changed
214
- await invalidateAllUserRbacCaches();
255
+ if (!getDatabaseTransactionClient()) {
256
+ throw new Error('Role permission assignment requires an active database transaction');
257
+ }
258
+ const targets = await requireRolePermissionTargets(applicationId, roleId, permissionIds);
259
+ await guardCanonicalAdminRole(targets.role.applicationId, targets.role.slug);
260
+ await guardCanonicalAdminPermissions(applicationId, targets.permissions);
261
+ const insertedPermissionIds = await repoAssignPermissions(applicationId, roleId, permissionIds);
262
+ if (insertedPermissionIds.length === 0)
263
+ return;
264
+ const userIds = await getUserIdsForRole(applicationId, roleId);
265
+ await registerAuthorityCleanup({
266
+ userIds,
267
+ grantIds: [],
268
+ roleIds: [],
269
+ revokeOidcState: false,
270
+ });
215
271
  // Audit log (fire-and-forget)
216
272
  void writeAuditLog({
217
273
  eventType: 'role.permissions.assigned',
218
274
  eventCategory: 'admin',
219
275
  actorId,
220
- metadata: { roleId, permissionIds },
276
+ metadata: { applicationId, roleId, permissionIds: insertedPermissionIds },
221
277
  });
222
278
  }
223
279
  /**
224
280
  * Remove permissions from a role.
225
281
  *
226
- * Delegates to the mapping repository. Invalidates all user RBAC
227
- * caches since user permissions may have changed.
282
+ * Validates every permission against the role's application. An actual
283
+ * removal revokes affected authority; an absent mapping is a committed no-op.
228
284
  *
285
+ * @param applicationId - Parent application UUID
229
286
  * @param roleId - Role UUID
230
287
  * @param permissionIds - Array of permission UUIDs to remove
231
288
  * @param actorId - Optional UUID of the admin performing the action
232
289
  */
233
- export async function removePermissionsFromRole(roleId, permissionIds, actorId) {
290
+ export async function removePermissionsFromRole(applicationId, roleId, permissionIds, actorId) {
234
291
  if (permissionIds.length === 0)
235
- return;
236
- await repoRemovePermissions(roleId, permissionIds);
237
- // Invalidate all user RBAC caches
238
- await invalidateAllUserRbacCaches();
239
- // Audit log (fire-and-forget)
240
- void writeAuditLog({
292
+ return { reauthenticationRequired: false };
293
+ const transaction = getDatabaseTransactionClient();
294
+ if (!transaction) {
295
+ throw new Error('Role permission removal requires an active database transaction');
296
+ }
297
+ const targets = await requireRolePermissionTargets(applicationId, roleId, permissionIds);
298
+ await guardCanonicalAdminRole(targets.role.applicationId, targets.role.slug);
299
+ await guardCanonicalAdminPermissions(applicationId, targets.permissions);
300
+ if (targets.assignedPermissionIds.length === 0) {
301
+ return { reauthenticationRequired: false };
302
+ }
303
+ const userIds = await getUserIdsForRole(applicationId, roleId);
304
+ const revoked = await revokeAffectedAuthorityInTransaction(userIds);
305
+ const removedPermissionIds = await repoRemovePermissions(applicationId, roleId, [
306
+ ...targets.assignedPermissionIds,
307
+ ]);
308
+ await writeAuditLogInTransaction(transaction, {
241
309
  eventType: 'role.permissions.removed',
242
310
  eventCategory: 'admin',
243
311
  actorId,
244
- metadata: { roleId, permissionIds },
312
+ metadata: { applicationId, roleId, permissionIds: removedPermissionIds },
313
+ });
314
+ await registerAuthorityCleanup({
315
+ userIds,
316
+ grantIds: revoked.grantIds,
317
+ roleIds: [],
318
+ revokeOidcState: true,
245
319
  });
320
+ return {
321
+ reauthenticationRequired: actorId !== undefined && userIds.includes(actorId),
322
+ };
246
323
  }
247
324
  /**
248
325
  * Get all permissions assigned to a role.
249
326
  *
327
+ * @param applicationId - Parent application UUID
250
328
  * @param roleId - Role UUID
251
329
  * @returns Array of permissions
252
330
  */
253
- export async function getPermissionsForRole(roleId) {
254
- return repoGetPermissionsForRole(roleId);
331
+ export async function getPermissionsForRole(applicationId, roleId) {
332
+ const role = await repoFindRoleById(applicationId, roleId);
333
+ if (!role)
334
+ throw new RoleNotFoundError(roleId);
335
+ return repoGetPermissionsForRole(applicationId, roleId);
336
+ }
337
+ /** Reject generic mutations of canonical Porta Admin role definitions and mappings. */
338
+ async function guardCanonicalAdminRole(applicationId, roleSlug) {
339
+ if (!ADMIN_ROLE_SLUGS.has(roleSlug))
340
+ return;
341
+ const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
342
+ if (adminApplication?.id === applicationId) {
343
+ throw new RbacValidationError('Canonical Porta Admin roles cannot be modified');
344
+ }
345
+ }
346
+ /** Reject mappings involving canonical Porta Admin permission definitions. */
347
+ async function guardCanonicalAdminPermissions(applicationId, permissions) {
348
+ if (!permissions.some((permission) => ADMIN_PERMISSION_SLUGS.has(permission.slug)))
349
+ return;
350
+ const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
351
+ if (adminApplication?.id === applicationId) {
352
+ throw new RbacValidationError('Canonical Porta Admin permissions cannot be modified');
353
+ }
354
+ }
355
+ /** Lock and validate every target in one application-scoped mapping request. */
356
+ async function requireRolePermissionTargets(applicationId, roleId, permissionIds) {
357
+ const requestedPermissionIds = [...new Set(permissionIds)].sort();
358
+ const targets = await lockRolePermissionTargets(applicationId, roleId, requestedPermissionIds);
359
+ if (!targets.role)
360
+ throw new RoleNotFoundError(roleId);
361
+ if (targets.permissions.length !== requestedPermissionIds.length) {
362
+ throw new RbacValidationError('Every permission must belong to the selected application');
363
+ }
364
+ return {
365
+ role: targets.role,
366
+ permissions: targets.permissions,
367
+ assignedPermissionIds: targets.assignedPermissionIds,
368
+ };
255
369
  }
256
370
  //# sourceMappingURL=role-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"role-service.js","sourceRoot":"","sources":["../../src/rbac/role-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"role-service.js","sourceRoot":"","sources":["../../src/rbac/role-service.ts"],"names":[],"mappings":"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"}
@@ -3,21 +3,19 @@
3
3
  *
4
4
  * Two types of slugs are used in the RBAC module:
5
5
  *
6
- * 1. **Role slugs** — kebab-case identifiers (e.g., "crm-editor").
7
- * Same format as organization/application slugs. Auto-generated
8
- * from role names or provided manually.
9
- *
10
- * 2. **Permission slugs** — colon-separated namespaced identifiers
11
- * following the `module:resource:action` format (e.g., "crm:contacts:read").
12
- * Each segment must be lowercase alphanumeric with hyphens.
13
- * Minimum 3 segments required.
6
+ * Role and permission slugs are exact external claim values. Explicit values keep their case and
7
+ * printable characters after surrounding whitespace is removed. Generated role slugs retain the
8
+ * familiar kebab-case default.
14
9
  *
15
10
  * This module provides:
16
11
  * - `generateRoleSlug(name)` — Derive a role slug from a role name
17
- * - `validateRoleSlug(slug)` — Check role slug format (kebab-case, 1-100 chars)
18
- * - `validatePermissionSlug(slug)` — Check permission slug follows module:resource:action
12
+ * - `normalizeRbacSlug(slug)` — Remove surrounding whitespace before storage and comparison
13
+ * - `validateRoleSlug(slug)` — Check the role claim value safety bounds
14
+ * - `validatePermissionSlug(slug)` — Check the permission claim value safety bounds
19
15
  * - `parsePermissionSlug(slug)` — Decompose a permission slug into its parts
20
16
  */
17
+ /** Removes surrounding whitespace while preserving the exact internal claim value. */
18
+ export declare function normalizeRbacSlug(slug: string): string;
21
19
  /**
22
20
  * Generate a URL-safe slug from a role name.
23
21
  *
@@ -43,11 +41,8 @@ export declare function generateRoleSlug(name: string): string;
43
41
  /**
44
42
  * Validate a role slug format.
45
43
  *
46
- * Rules:
47
- * - 1–100 characters long
48
- * - Lowercase alphanumeric characters and hyphens only
49
- * - Cannot start or end with a hyphen
50
- * - Empty strings are invalid
44
+ * The trimmed value must contain 1–100 printable characters. Case and internal characters are
45
+ * preserved because this value is emitted directly to external applications.
51
46
  *
52
47
  * Does NOT check uniqueness — that's the repository/service layer's job.
53
48
  *
@@ -57,19 +52,13 @@ export declare function generateRoleSlug(name: string): string;
57
52
  * @example
58
53
  * validateRoleSlug('crm-editor') // true
59
54
  * validateRoleSlug('admin') // true
60
- * validateRoleSlug('CRM Editor') // false (spaces, uppercase)
55
+ * validateRoleSlug('CRM Editor') // true
61
56
  * validateRoleSlug('') // false (empty)
62
57
  */
63
58
  export declare function validateRoleSlug(slug: string): boolean;
64
59
  /**
65
- * Validate a permission slug follows the module:resource:action format.
66
- *
67
- * Rules:
68
- * - Must have at least 3 segments separated by colons
69
- * - Each segment must be lowercase alphanumeric with hyphens
70
- * - Each segment must start and end with an alphanumeric character
71
- * - Empty segments are not allowed
72
- * - Total length must not exceed 150 characters (matches DB column)
60
+ * Validate a permission claim value. `module:resource:action` remains a useful convention, but is
61
+ * not mandatory for external applications that already use another identifier scheme.
73
62
  *
74
63
  * @param slug - Permission slug to validate
75
64
  * @returns true if the slug format is valid, false otherwise
@@ -78,8 +67,8 @@ export declare function validateRoleSlug(slug: string): boolean;
78
67
  * validatePermissionSlug('crm:contacts:read') // true
79
68
  * validatePermissionSlug('admin:system:manage') // true
80
69
  * validatePermissionSlug('crm:sub-module:items:write') // true (4+ segments OK)
81
- * validatePermissionSlug('contacts-read') // false (no colons)
82
- * validatePermissionSlug('a:b') // false (only 2 segments)
70
+ * validatePermissionSlug('CAN_ADD_ORDER') // true
71
+ * validatePermissionSlug('access-that-resource') // true
83
72
  * validatePermissionSlug('') // false (empty)
84
73
  */
85
74
  export declare function validatePermissionSlug(slug: string): boolean;
@@ -97,7 +86,7 @@ export interface ParsedPermissionSlug {
97
86
  * both 3-segment slugs (crm:contacts:read) and 4+ segment slugs
98
87
  * (crm:sub-module:items:write → module="crm", resource="sub-module:items", action="write").
99
88
  *
100
- * Returns null if the slug is invalid (fails validatePermissionSlug).
89
+ * Returns null when the claim value does not use the conventional three-or-more-part colon form.
101
90
  *
102
91
  * @param slug - Permission slug to parse
103
92
  * @returns Parsed components or null if invalid
@@ -1 +1 @@
1
- {"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../src/rbac/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA2BH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOtD;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB5D;AAMD,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAY7E"}
1
+ {"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../src/rbac/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAwBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAMD,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAW7E"}