@portaidentity/server 1.7.2 → 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 +10 -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
@@ -3,38 +3,38 @@
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
  */
21
17
  // ---------------------------------------------------------------------------
22
18
  // Role slug format
23
19
  // ---------------------------------------------------------------------------
24
- /**
25
- * Role slug format regex: 1–100 characters, lowercase alphanumeric + hyphens.
26
- * Must start and end with an alphanumeric character (no leading/trailing hyphens).
27
- * Single character slugs are allowed (unlike organization slugs which require 3+).
28
- */
29
- const ROLE_SLUG_REGEX = /^[a-z0-9]([a-z0-9-]{0,98}[a-z0-9])?$/;
30
- // ---------------------------------------------------------------------------
31
- // Permission slug format
32
- // ---------------------------------------------------------------------------
33
- /**
34
- * Each segment of a permission slug: lowercase alphanumeric + hyphens,
35
- * must start and end with an alphanumeric character.
36
- */
37
- const PERMISSION_SEGMENT_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
20
+ /** Removes surrounding whitespace while preserving the exact internal claim value. */
21
+ export function normalizeRbacSlug(slug) {
22
+ return slug.trim();
23
+ }
24
+ /** Returns whether text contains an ASCII or C1 control character. */
25
+ function containsControlCharacter(value) {
26
+ return [...value].some((character) => {
27
+ const codePoint = character.codePointAt(0) ?? 0;
28
+ return codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f);
29
+ });
30
+ }
31
+ /** Validates one normalized, bounded, control-free external claim value. */
32
+ function validateRbacSlug(slug, maximumLength) {
33
+ const normalized = normalizeRbacSlug(slug);
34
+ return (normalized.length > 0 &&
35
+ normalized.length <= maximumLength &&
36
+ !containsControlCharacter(normalized));
37
+ }
38
38
  // ---------------------------------------------------------------------------
39
39
  // Role slug generation
40
40
  // ---------------------------------------------------------------------------
@@ -80,11 +80,8 @@ export function generateRoleSlug(name) {
80
80
  /**
81
81
  * Validate a role slug format.
82
82
  *
83
- * Rules:
84
- * - 1–100 characters long
85
- * - Lowercase alphanumeric characters and hyphens only
86
- * - Cannot start or end with a hyphen
87
- * - Empty strings are invalid
83
+ * The trimmed value must contain 1–100 printable characters. Case and internal characters are
84
+ * preserved because this value is emitted directly to external applications.
88
85
  *
89
86
  * Does NOT check uniqueness — that's the repository/service layer's job.
90
87
  *
@@ -94,28 +91,18 @@ export function generateRoleSlug(name) {
94
91
  * @example
95
92
  * validateRoleSlug('crm-editor') // true
96
93
  * validateRoleSlug('admin') // true
97
- * validateRoleSlug('CRM Editor') // false (spaces, uppercase)
94
+ * validateRoleSlug('CRM Editor') // true
98
95
  * validateRoleSlug('') // false (empty)
99
96
  */
100
97
  export function validateRoleSlug(slug) {
101
- // Must be 1–100 characters
102
- if (!slug || slug.length > 100) {
103
- return false;
104
- }
105
- return ROLE_SLUG_REGEX.test(slug);
98
+ return validateRbacSlug(slug, 100);
106
99
  }
107
100
  // ---------------------------------------------------------------------------
108
101
  // Permission slug validation
109
102
  // ---------------------------------------------------------------------------
110
103
  /**
111
- * Validate a permission slug follows the module:resource:action format.
112
- *
113
- * Rules:
114
- * - Must have at least 3 segments separated by colons
115
- * - Each segment must be lowercase alphanumeric with hyphens
116
- * - Each segment must start and end with an alphanumeric character
117
- * - Empty segments are not allowed
118
- * - Total length must not exceed 150 characters (matches DB column)
104
+ * Validate a permission claim value. `module:resource:action` remains a useful convention, but is
105
+ * not mandatory for external applications that already use another identifier scheme.
119
106
  *
120
107
  * @param slug - Permission slug to validate
121
108
  * @returns true if the slug format is valid, false otherwise
@@ -124,22 +111,12 @@ export function validateRoleSlug(slug) {
124
111
  * validatePermissionSlug('crm:contacts:read') // true
125
112
  * validatePermissionSlug('admin:system:manage') // true
126
113
  * validatePermissionSlug('crm:sub-module:items:write') // true (4+ segments OK)
127
- * validatePermissionSlug('contacts-read') // false (no colons)
128
- * validatePermissionSlug('a:b') // false (only 2 segments)
114
+ * validatePermissionSlug('CAN_ADD_ORDER') // true
115
+ * validatePermissionSlug('access-that-resource') // true
129
116
  * validatePermissionSlug('') // false (empty)
130
117
  */
131
118
  export function validatePermissionSlug(slug) {
132
- // Must be non-empty and within DB column limit (VARCHAR(150))
133
- if (!slug || slug.length > 150) {
134
- return false;
135
- }
136
- // Split on colons — need at least 3 segments
137
- const segments = slug.split(':');
138
- if (segments.length < 3) {
139
- return false;
140
- }
141
- // Each segment must match the segment format
142
- return segments.every((segment) => segment.length > 0 && PERMISSION_SEGMENT_REGEX.test(segment));
119
+ return validateRbacSlug(slug, 150);
143
120
  }
144
121
  /**
145
122
  * Parse a permission slug into its module, resource, and action components.
@@ -149,7 +126,7 @@ export function validatePermissionSlug(slug) {
149
126
  * both 3-segment slugs (crm:contacts:read) and 4+ segment slugs
150
127
  * (crm:sub-module:items:write → module="crm", resource="sub-module:items", action="write").
151
128
  *
152
- * Returns null if the slug is invalid (fails validatePermissionSlug).
129
+ * Returns null when the claim value does not use the conventional three-or-more-part colon form.
153
130
  *
154
131
  * @param slug - Permission slug to parse
155
132
  * @returns Parsed components or null if invalid
@@ -165,10 +142,10 @@ export function validatePermissionSlug(slug) {
165
142
  * // null
166
143
  */
167
144
  export function parsePermissionSlug(slug) {
168
- if (!validatePermissionSlug(slug)) {
145
+ const segments = normalizeRbacSlug(slug).split(':');
146
+ if (!validatePermissionSlug(slug) || segments.length < 3 || segments.some((part) => !part)) {
169
147
  return null;
170
148
  }
171
- const segments = slug.split(':');
172
149
  // First segment = module, last = action, middle = resource
173
150
  const module = segments[0];
174
151
  const action = segments[segments.length - 1];
@@ -1 +1 @@
1
- {"version":3,"file":"slugs.js","sourceRoot":"","sources":["../../src/rbac/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAE/D,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,wBAAwB,GAAG,iCAAiC,CAAC;AAEnE,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI;SACd,WAAW,EAAE;QACd,qEAAqE;SACpE,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;QAC5B,oDAAoD;SACnD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,sCAAsC;SACrC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAE3B,iFAAiF;IACjF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,2BAA2B;IAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,8DAA8D;IAC9D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6CAA6C;IAC7C,OAAO,QAAQ,CAAC,KAAK,CACnB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAC1E,CAAC;AACJ,CAAC;AAaD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,2DAA2D;IAC3D,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"slugs.js","sourceRoot":"","sources":["../../src/rbac/slugs.ts"],"names":[],"mappings":"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"}
@@ -62,8 +62,7 @@ export interface UpdateRoleInput {
62
62
  * Full permission record as stored in the database.
63
63
  * Maps to the `permissions` table columns (see migration 006).
64
64
  * Permissions are defined globally per application, optionally scoped
65
- * to a module. The slug follows the module:resource:action format
66
- * (e.g., "crm:contacts:read").
65
+ * to a module. The slug is the exact permission value emitted to the application.
67
66
  */
68
67
  export interface Permission {
69
68
  id: string;
@@ -89,8 +88,7 @@ export interface PermissionRow {
89
88
  }
90
89
  /**
91
90
  * Input for creating a new permission.
92
- * The slug must follow the module:resource:action format and is
93
- * validated by the service layer before insert.
91
+ * The slug is an application-defined claim value validated by the service layer before insert.
94
92
  */
95
93
  export interface CreatePermissionInput {
96
94
  applicationId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiLH,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAkB;IACnD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAgB;IAC/C,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+KH,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAkB;IACnD,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAgB;IAC/C,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
@@ -5,14 +5,8 @@
5
5
  * roles and permissions, and building the claims arrays that get
6
6
  * injected into OIDC tokens.
7
7
  *
8
- * The claims-building functions (buildRoleClaims, buildPermissionClaims)
9
- * are the token hot path — they use cache-first resolution to minimize
10
- * database queries during token issuance.
11
- *
12
- * Cache strategy for claims:
13
- * 1. Check Redis for cached slug arrays
14
- * 2. On cache hit → return immediately (fast path)
15
- * 3. On cache miss → query DB, cache result, return
8
+ * Token claim construction reads PostgreSQL directly. This makes role and
9
+ * permission deletion authoritative even when an older Redis entry remains.
16
10
  *
17
11
  * @see mapping-repository.ts — Database operations for user-role join table
18
12
  * @see cache.ts — Redis cache for role/permission slug arrays
@@ -24,47 +18,57 @@ import type { Role, Permission, UserRole } from './types.js';
24
18
  * Uses ON CONFLICT DO NOTHING for idempotent assignment. Invalidates
25
19
  * the user's RBAC cache since their effective permissions may change.
26
20
  *
21
+ * @param organizationId - Authoritative organization UUID
27
22
  * @param userId - User UUID
28
23
  * @param roleIds - Array of role UUIDs to assign
29
- * @param assignedBy - Optional UUID of the admin performing the assignment
24
+ * @param assignedBy - UUID of the admin performing the assignment
30
25
  */
31
- export declare function assignRolesToUser(userId: string, roleIds: string[], assignedBy?: string): Promise<void>;
26
+ export declare function assignRolesToUser(organizationId: string, userId: string, roleIds: string[], assignedBy: string): Promise<void>;
32
27
  /**
33
28
  * Remove roles from a user (bulk).
34
29
  *
35
30
  * Invalidates the user's RBAC cache since their effective permissions
36
31
  * may change.
37
32
  *
33
+ * @param organizationId - Authoritative organization UUID
38
34
  * @param userId - User UUID
39
35
  * @param roleIds - Array of role UUIDs to remove
40
- * @param actorId - Optional UUID of the admin performing the action
36
+ * @param actorId - UUID of the admin performing the action
37
+ * @returns Whether the actor must authenticate again
41
38
  */
42
- export declare function removeRolesFromUser(userId: string, roleIds: string[], actorId?: string): Promise<void>;
39
+ export declare function removeRolesFromUser(organizationId: string, userId: string, roleIds: string[], actorId: string): Promise<{
40
+ reauthenticationRequired: boolean;
41
+ }>;
43
42
  /**
44
43
  * Get all roles assigned to a user.
45
44
  *
45
+ * @param organizationId - Authoritative organization UUID
46
46
  * @param userId - User UUID
47
47
  * @returns Array of Role objects
48
48
  */
49
- export declare function getUserRoles(userId: string): Promise<Role[]>;
49
+ export declare function getUserRoles(organizationId: string, userId: string): Promise<Role[]>;
50
+ /** Read all roles for internal authority resolution without a route parent. */
51
+ export declare function getUserRolesForAuthority(userId: string): Promise<Role[]>;
50
52
  /**
51
53
  * Get all permissions for a user (resolved through roles).
52
54
  *
55
+ * @param organizationId - Authoritative organization UUID
53
56
  * @param userId - User UUID
54
57
  * @returns Deduplicated array of Permission objects
55
58
  */
56
- export declare function getUserPermissions(userId: string): Promise<Permission[]>;
59
+ export declare function getUserPermissions(organizationId: string, userId: string): Promise<Permission[]>;
57
60
  /**
58
61
  * List users with a specific role within an organization.
59
62
  *
60
63
  * Supports pagination for admin UI views.
61
64
  *
65
+ * @param applicationId - Authoritative application UUID
62
66
  * @param roleId - Role UUID
63
67
  * @param orgId - Organization UUID
64
68
  * @param options - Pagination options
65
69
  * @returns Paginated user-role assignments and total count
66
70
  */
67
- export declare function getUsersWithRole(roleId: string, orgId: string, options?: {
71
+ export declare function getUsersWithRole(applicationId: string, roleId: string, orgId: string, options?: {
68
72
  page?: number;
69
73
  pageSize?: number;
70
74
  }): Promise<{
@@ -77,25 +81,20 @@ export declare function getUsersWithRole(roleId: string, orgId: string, options?
77
81
  * Returns an array of role slugs (e.g., ["crm-editor", "invoice-approver"])
78
82
  * for inclusion in the token's custom claims.
79
83
  *
80
- * Cache-first: checks Redis for cached role slugs. On cache miss,
81
- * resolves from DB and caches the result for future token issuances.
82
- *
83
84
  * @param userId - User UUID
85
+ * @param applicationId - Application UUID that owns the requested token authority
84
86
  * @returns Array of role slug strings
85
87
  */
86
- export declare function buildRoleClaims(userId: string): Promise<string[]>;
88
+ export declare function buildRoleClaims(userId: string, applicationId: string): Promise<string[]>;
87
89
  /**
88
90
  * Build permission claims for a user's token.
89
91
  *
90
92
  * Returns an array of permission slugs (e.g., ["crm:contacts:read",
91
93
  * "crm:deals:write"]) for inclusion in the token's custom claims.
92
94
  *
93
- * Cache-first: checks Redis for cached permission slugs. On cache miss,
94
- * resolves through the full user → roles → permissions chain from DB
95
- * and caches the result.
96
- *
97
95
  * @param userId - User UUID
96
+ * @param applicationId - Application UUID that owns the requested token authority
98
97
  * @returns Array of permission slug strings
99
98
  */
100
- export declare function buildPermissionClaims(userId: string): Promise<string[]>;
99
+ export declare function buildPermissionClaims(userId: string, applicationId: string): Promise<string[]>;
101
100
  //# sourceMappingURL=user-role-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-role-service.d.ts","sourceRoot":"","sources":["../../src/rbac/user-role-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiBH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM7D;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAgBf;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAElE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAE9E;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAK9C;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAevE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAe7E"}
1
+ {"version":3,"file":"user-role-service.d.ts","sourceRoot":"","sources":["../../src/rbac/user-role-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAwB7D;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,wBAAwB,EAAE,OAAO,CAAA;CAAE,CAAC,CAsChD;AAMD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAE1F;AAED,+EAA+E;AAC/E,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAE9E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAK9C;AA0DD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG9F;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
@@ -5,21 +5,24 @@
5
5
  * roles and permissions, and building the claims arrays that get
6
6
  * injected into OIDC tokens.
7
7
  *
8
- * The claims-building functions (buildRoleClaims, buildPermissionClaims)
9
- * are the token hot path — they use cache-first resolution to minimize
10
- * database queries during token issuance.
11
- *
12
- * Cache strategy for claims:
13
- * 1. Check Redis for cached slug arrays
14
- * 2. On cache hit → return immediately (fast path)
15
- * 3. On cache miss → query DB, cache result, return
8
+ * Token claim construction reads PostgreSQL directly. This makes role and
9
+ * permission deletion authoritative even when an older Redis entry remains.
16
10
  *
17
11
  * @see mapping-repository.ts — Database operations for user-role join table
18
12
  * @see cache.ts — Redis cache for role/permission slug arrays
19
13
  */
20
- import { assignRolesToUser as repoAssignRoles, removeRolesFromUser as repoRemoveRoles, getRolesForUser as repoGetRolesForUser, getPermissionsForUser as repoGetPermissionsForUser, getUsersWithRole as repoGetUsersWithRole, } from './mapping-repository.js';
21
- import { getCachedUserRoles, setCachedUserRoles, getCachedUserPermissions, setCachedUserPermissions, invalidateUserRbacCache, } from './cache.js';
14
+ import { assignRolesToUser as repoAssignRoles, removeRolesFromUser as repoRemoveRoles, getRolesForUser as repoGetRolesForUser, getPermissionsForUser as repoGetPermissionsForUser, getUsersWithRole as repoGetUsersWithRole, getRolesForOrganizationUser, getPermissionsForOrganizationUser, lockUserRoleTargets, } from './mapping-repository.js';
22
15
  import { writeAuditLog } from '../lib/audit-log.js';
16
+ import { getDatabaseTransactionClient } from '../lib/database.js';
17
+ import { writeAuditLogInTransaction } from '../lib/audit-log.js';
18
+ import { registerAuthorityCleanup } from '../lib/deletion-cleanup.js';
19
+ import { revokeAffectedAuthorityInTransaction } from '../lib/authority-revocation.js';
20
+ import { getApplicationBySlug } from '../applications/service.js';
21
+ import { ADMIN_ROLE_DEFINITIONS, getPermissionsForAdminRole, resolvePermissionsFromRoles, } from '../lib/admin-permissions.js';
22
+ import { RoleDelegationError, RoleNotFoundError } from './errors.js';
23
+ import { UserNotFoundError } from '../users/errors.js';
24
+ import { lockControlPlaneOrganization, requireActiveSuperAdminSurvivor, } from '../users/repository.js';
25
+ const ADMIN_APPLICATION_SLUG = 'porta-admin';
23
26
  // ---------------------------------------------------------------------------
24
27
  // Assignment management
25
28
  // ---------------------------------------------------------------------------
@@ -29,23 +32,35 @@ import { writeAuditLog } from '../lib/audit-log.js';
29
32
  * Uses ON CONFLICT DO NOTHING for idempotent assignment. Invalidates
30
33
  * the user's RBAC cache since their effective permissions may change.
31
34
  *
35
+ * @param organizationId - Authoritative organization UUID
32
36
  * @param userId - User UUID
33
37
  * @param roleIds - Array of role UUIDs to assign
34
- * @param assignedBy - Optional UUID of the admin performing the assignment
38
+ * @param assignedBy - UUID of the admin performing the assignment
35
39
  */
36
- export async function assignRolesToUser(userId, roleIds, assignedBy) {
40
+ export async function assignRolesToUser(organizationId, userId, roleIds, assignedBy) {
37
41
  if (roleIds.length === 0)
38
42
  return;
39
- await repoAssignRoles(userId, roleIds, assignedBy);
40
- // Invalidate user's cached roles and permissions
41
- await invalidateUserRbacCache(userId);
43
+ if (!getDatabaseTransactionClient()) {
44
+ throw new Error('User role assignment requires an active database transaction');
45
+ }
46
+ const targets = await requireUserRoleTargets(organizationId, userId, roleIds);
47
+ await requireDelegableRoles(targets.roles, assignedBy, targets.adminApplicationId);
48
+ const insertedRoleIds = await repoAssignRoles(organizationId, userId, roleIds, assignedBy);
49
+ if (insertedRoleIds.length === 0)
50
+ return;
51
+ await registerAuthorityCleanup({
52
+ userIds: [userId],
53
+ grantIds: [],
54
+ roleIds: [],
55
+ revokeOidcState: false,
56
+ });
42
57
  // Audit log (fire-and-forget)
43
58
  void writeAuditLog({
44
59
  eventType: 'user.roles.assigned',
45
60
  eventCategory: 'admin',
46
61
  userId,
47
62
  actorId: assignedBy,
48
- metadata: { roleIds },
63
+ metadata: { organizationId, roleIds: insertedRoleIds },
49
64
  });
50
65
  }
51
66
  /**
@@ -54,24 +69,47 @@ export async function assignRolesToUser(userId, roleIds, assignedBy) {
54
69
  * Invalidates the user's RBAC cache since their effective permissions
55
70
  * may change.
56
71
  *
72
+ * @param organizationId - Authoritative organization UUID
57
73
  * @param userId - User UUID
58
74
  * @param roleIds - Array of role UUIDs to remove
59
- * @param actorId - Optional UUID of the admin performing the action
75
+ * @param actorId - UUID of the admin performing the action
76
+ * @returns Whether the actor must authenticate again
60
77
  */
61
- export async function removeRolesFromUser(userId, roleIds, actorId) {
78
+ export async function removeRolesFromUser(organizationId, userId, roleIds, actorId) {
62
79
  if (roleIds.length === 0)
63
- return;
64
- await repoRemoveRoles(userId, roleIds);
65
- // Invalidate user's cached roles and permissions
66
- await invalidateUserRbacCache(userId);
67
- // Audit log (fire-and-forget)
68
- void writeAuditLog({
80
+ return { reauthenticationRequired: false };
81
+ const transaction = getDatabaseTransactionClient();
82
+ if (!transaction) {
83
+ throw new Error('User role removal requires an active database transaction');
84
+ }
85
+ await lockControlPlaneOrganization(organizationId);
86
+ const targets = await requireUserRoleTargets(organizationId, userId, roleIds);
87
+ if (targets.assignedRoleIds.length === 0)
88
+ return { reauthenticationRequired: false };
89
+ const removesExactSuperAdmin = targets.roles.some((role) => targets.assignedRoleIds.includes(role.id) &&
90
+ role.applicationId === targets.adminApplicationId &&
91
+ role.slug === ADMIN_ROLE_DEFINITIONS.SUPER_ADMIN.slug);
92
+ if (targets.user.status === 'active' && removesExactSuperAdmin) {
93
+ await requireActiveSuperAdminSurvivor(organizationId, userId);
94
+ }
95
+ const revoked = await revokeAffectedAuthorityInTransaction([userId]);
96
+ const removedRoleIds = await repoRemoveRoles(organizationId, userId, [
97
+ ...targets.assignedRoleIds,
98
+ ]);
99
+ await writeAuditLogInTransaction(transaction, {
69
100
  eventType: 'user.roles.removed',
70
101
  eventCategory: 'admin',
71
102
  userId,
72
103
  actorId,
73
- metadata: { roleIds },
104
+ metadata: { organizationId, roleIds: removedRoleIds },
74
105
  });
106
+ await registerAuthorityCleanup({
107
+ userIds: [userId],
108
+ grantIds: revoked.grantIds,
109
+ roleIds: [],
110
+ revokeOidcState: true,
111
+ });
112
+ return { reauthenticationRequired: actorId === userId };
75
113
  }
76
114
  // ---------------------------------------------------------------------------
77
115
  // Query operations
@@ -79,35 +117,76 @@ export async function removeRolesFromUser(userId, roleIds, actorId) {
79
117
  /**
80
118
  * Get all roles assigned to a user.
81
119
  *
120
+ * @param organizationId - Authoritative organization UUID
82
121
  * @param userId - User UUID
83
122
  * @returns Array of Role objects
84
123
  */
85
- export async function getUserRoles(userId) {
124
+ export async function getUserRoles(organizationId, userId) {
125
+ return getRolesForOrganizationUser(organizationId, userId);
126
+ }
127
+ /** Read all roles for internal authority resolution without a route parent. */
128
+ export async function getUserRolesForAuthority(userId) {
86
129
  return repoGetRolesForUser(userId);
87
130
  }
88
131
  /**
89
132
  * Get all permissions for a user (resolved through roles).
90
133
  *
134
+ * @param organizationId - Authoritative organization UUID
91
135
  * @param userId - User UUID
92
136
  * @returns Deduplicated array of Permission objects
93
137
  */
94
- export async function getUserPermissions(userId) {
95
- return repoGetPermissionsForUser(userId);
138
+ export async function getUserPermissions(organizationId, userId) {
139
+ return getPermissionsForOrganizationUser(organizationId, userId);
96
140
  }
97
141
  /**
98
142
  * List users with a specific role within an organization.
99
143
  *
100
144
  * Supports pagination for admin UI views.
101
145
  *
146
+ * @param applicationId - Authoritative application UUID
102
147
  * @param roleId - Role UUID
103
148
  * @param orgId - Organization UUID
104
149
  * @param options - Pagination options
105
150
  * @returns Paginated user-role assignments and total count
106
151
  */
107
- export async function getUsersWithRole(roleId, orgId, options) {
152
+ export async function getUsersWithRole(applicationId, roleId, orgId, options) {
108
153
  const page = options?.page ?? 1;
109
154
  const pageSize = options?.pageSize ?? 20;
110
- return repoGetUsersWithRole(roleId, orgId, page, pageSize);
155
+ return repoGetUsersWithRole(applicationId, roleId, orgId, page, pageSize);
156
+ }
157
+ /** Lock the target user and every requested role, then reject missing records. */
158
+ async function requireUserRoleTargets(organizationId, userId, roleIds) {
159
+ const requestedRoleIds = [...new Set(roleIds)].sort();
160
+ const targets = await lockUserRoleTargets(organizationId, userId, requestedRoleIds);
161
+ if (!targets.user)
162
+ throw new UserNotFoundError(userId);
163
+ if (targets.roles.length !== requestedRoleIds.length) {
164
+ const found = new Set(targets.roles.map((role) => role.id));
165
+ const missing = requestedRoleIds.find((roleId) => !found.has(roleId));
166
+ throw new RoleNotFoundError(missing ?? 'requested role');
167
+ }
168
+ const adminApplication = await getApplicationBySlug(ADMIN_APPLICATION_SLUG);
169
+ return {
170
+ user: targets.user,
171
+ roles: targets.roles,
172
+ assignedRoleIds: targets.assignedRoleIds,
173
+ adminApplicationId: adminApplication?.id ?? null,
174
+ };
175
+ }
176
+ /** Enforce the static capability ceiling for canonical Admin role assignments. */
177
+ async function requireDelegableRoles(roles, actorId, adminApplicationId) {
178
+ if (adminApplicationId === null)
179
+ return;
180
+ const requestedCapabilities = roles
181
+ .filter((role) => role.applicationId === adminApplicationId)
182
+ .flatMap((role) => getPermissionsForAdminRole(role.slug));
183
+ if (requestedCapabilities.length === 0)
184
+ return;
185
+ const actorRoles = await repoGetRolesForUser(actorId, adminApplicationId);
186
+ const actorCapabilities = new Set(resolvePermissionsFromRoles(actorRoles.map((role) => role.slug)));
187
+ if (requestedCapabilities.some((capability) => !actorCapabilities.has(capability))) {
188
+ throw new RoleDelegationError();
189
+ }
111
190
  }
112
191
  // ---------------------------------------------------------------------------
113
192
  // Token claims building (hot path)
@@ -118,24 +197,13 @@ export async function getUsersWithRole(roleId, orgId, options) {
118
197
  * Returns an array of role slugs (e.g., ["crm-editor", "invoice-approver"])
119
198
  * for inclusion in the token's custom claims.
120
199
  *
121
- * Cache-first: checks Redis for cached role slugs. On cache miss,
122
- * resolves from DB and caches the result for future token issuances.
123
- *
124
200
  * @param userId - User UUID
201
+ * @param applicationId - Application UUID that owns the requested token authority
125
202
  * @returns Array of role slug strings
126
203
  */
127
- export async function buildRoleClaims(userId) {
128
- // 1. Check cache for user role slugs
129
- const cached = await getCachedUserRoles(userId);
130
- if (cached !== null) {
131
- return cached;
132
- }
133
- // 2. Cache miss — resolve from DB
134
- const roles = await repoGetRolesForUser(userId);
135
- const slugs = roles.map((role) => role.slug);
136
- // 3. Cache the slugs for future requests
137
- await setCachedUserRoles(userId, slugs);
138
- return slugs;
204
+ export async function buildRoleClaims(userId, applicationId) {
205
+ const roles = await repoGetRolesForUser(userId, applicationId);
206
+ return [...new Set(roles.map((role) => role.slug))];
139
207
  }
140
208
  /**
141
209
  * Build permission claims for a user's token.
@@ -143,24 +211,12 @@ export async function buildRoleClaims(userId) {
143
211
  * Returns an array of permission slugs (e.g., ["crm:contacts:read",
144
212
  * "crm:deals:write"]) for inclusion in the token's custom claims.
145
213
  *
146
- * Cache-first: checks Redis for cached permission slugs. On cache miss,
147
- * resolves through the full user → roles → permissions chain from DB
148
- * and caches the result.
149
- *
150
214
  * @param userId - User UUID
215
+ * @param applicationId - Application UUID that owns the requested token authority
151
216
  * @returns Array of permission slug strings
152
217
  */
153
- export async function buildPermissionClaims(userId) {
154
- // 1. Check cache for user permission slugs
155
- const cached = await getCachedUserPermissions(userId);
156
- if (cached !== null) {
157
- return cached;
158
- }
159
- // 2. Cache miss — resolve from DB (through roles)
160
- const permissions = await repoGetPermissionsForUser(userId);
161
- const slugs = permissions.map((perm) => perm.slug);
162
- // 3. Cache the slugs for future requests
163
- await setCachedUserPermissions(userId, slugs);
164
- return slugs;
218
+ export async function buildPermissionClaims(userId, applicationId) {
219
+ const permissions = await repoGetPermissionsForUser(userId, applicationId);
220
+ return [...new Set(permissions.map((permission) => permission.slug))];
165
221
  }
166
222
  //# sourceMappingURL=user-role-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-role-service.js","sourceRoot":"","sources":["../../src/rbac/user-role-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-role-service.js","sourceRoot":"","sources":["../../src/rbac/user-role-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,iBAAiB,IAAI,eAAe,EACpC,mBAAmB,IAAI,eAAe,EACtC,eAAe,IAAI,mBAAmB,EACtC,qBAAqB,IAAI,yBAAyB,EAClD,gBAAgB,IAAI,oBAAoB,EACxC,2BAA2B,EAC3B,iCAAiC,EACjC,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,oCAAoC,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,wBAAwB,CAAC;AAEhC,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAE7C,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,cAAsB,EACtB,MAAc,EACd,OAAiB,EACjB,UAAkB;IAElB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,IAAI,CAAC,4BAA4B,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,MAAM,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEnF,MAAM,eAAe,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC3F,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACzC,MAAM,wBAAwB,CAAC;QAC7B,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IAEH,8BAA8B;IAC9B,KAAK,aAAa,CAAC;QACjB,SAAS,EAAE,qBAAqB;QAChC,aAAa,EAAE,OAAO;QACtB,MAAM;QACN,OAAO,EAAE,UAAU;QACnB,QAAQ,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE;KACvD,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,cAAsB,EACtB,MAAc,EACd,OAAiB,EACjB,OAAe;IAEf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC;IACrE,MAAM,WAAW,GAAG,4BAA4B,EAAE,CAAC;IACnD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,4BAA4B,CAAC,cAAc,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC;IAErF,MAAM,sBAAsB,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAC/C,CAAC,IAAI,EAAE,EAAE,CACP,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,aAAa,KAAK,OAAO,CAAC,kBAAkB;QACjD,IAAI,CAAC,IAAI,KAAK,sBAAsB,CAAC,WAAW,CAAC,IAAI,CACxD,CAAC;IACF,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC/D,MAAM,+BAA+B,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE;QACnE,GAAG,OAAO,CAAC,eAAe;KAC3B,CAAC,CAAC;IACH,MAAM,0BAA0B,CAAC,WAAW,EAAE;QAC5C,SAAS,EAAE,oBAAoB;QAC/B,aAAa,EAAE,OAAO;QACtB,MAAM;QACN,OAAO;QACP,QAAQ,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE;KACtD,CAAC,CAAC;IACH,MAAM,wBAAwB,CAAC;QAC7B,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE,EAAE;QACX,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;IACH,OAAO,EAAE,wBAAwB,EAAE,OAAO,KAAK,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,cAAsB,EAAE,MAAc;IACvE,OAAO,2BAA2B,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAc;IAC3D,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,cAAsB,EACtB,MAAc;IAEd,OAAO,iCAAiC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,aAAqB,EACrB,MAAc,EACd,KAAa,EACb,OAA8C;IAE9C,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;IAEzC,OAAO,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC5E,CAAC;AAUD,kFAAkF;AAClF,KAAK,UAAU,sBAAsB,CACnC,cAAsB,EACtB,MAAc,EACd,OAA0B;IAE1B,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpF,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,MAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACtE,MAAM,IAAI,iBAAiB,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;IAC5E,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,IAAI,IAAI;KACjD,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,KAAK,UAAU,qBAAqB,CAClC,KAAsB,EACtB,OAAe,EACf,kBAAiC;IAEjC,IAAI,kBAAkB,KAAK,IAAI;QAAE,OAAO;IACxC,MAAM,qBAAqB,GAAG,KAAK;SAChC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,KAAK,kBAAkB,CAAC;SAC3D,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE/C,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAC1E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,2BAA2B,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CACjE,CAAC;IACF,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,mBAAmB,EAAE,CAAC;IAClC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,aAAqB;IACzE,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,aAAqB;IAErB,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC"}