@neohm/nestend 4.0.1 → 4.1.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 (267) hide show
  1. package/README.md +61 -12
  2. package/dist/admin/controllers/admin.api.key.controller.d.ts +3 -1
  3. package/dist/admin/controllers/admin.api.key.controller.d.ts.map +1 -1
  4. package/dist/admin/controllers/admin.api.key.controller.js +6 -3
  5. package/dist/admin/controllers/admin.api.key.controller.js.map +1 -1
  6. package/dist/admin/controllers/admin.scope.controller.d.ts +2 -0
  7. package/dist/admin/controllers/admin.scope.controller.d.ts.map +1 -1
  8. package/dist/admin/controllers/admin.scope.controller.js +45 -5
  9. package/dist/admin/controllers/admin.scope.controller.js.map +1 -1
  10. package/dist/admin/controllers/admin.tenant.user.controller.d.ts +8 -1
  11. package/dist/admin/controllers/admin.tenant.user.controller.d.ts.map +1 -1
  12. package/dist/admin/controllers/admin.tenant.user.controller.js +75 -7
  13. package/dist/admin/controllers/admin.tenant.user.controller.js.map +1 -1
  14. package/dist/admin/dtos/add.client.membership.dto.d.ts +6 -0
  15. package/dist/admin/dtos/add.client.membership.dto.d.ts.map +1 -0
  16. package/dist/admin/dtos/add.client.membership.dto.js +41 -0
  17. package/dist/admin/dtos/add.client.membership.dto.js.map +1 -0
  18. package/dist/admin/dtos/add.scope.dto.d.ts +1 -0
  19. package/dist/admin/dtos/add.scope.dto.d.ts.map +1 -1
  20. package/dist/admin/dtos/add.scope.dto.js +9 -0
  21. package/dist/admin/dtos/add.scope.dto.js.map +1 -1
  22. package/dist/admin/dtos/scope.list.dto.d.ts +1 -0
  23. package/dist/admin/dtos/scope.list.dto.d.ts.map +1 -1
  24. package/dist/admin/dtos/scope.list.dto.js +22 -0
  25. package/dist/admin/dtos/scope.list.dto.js.map +1 -1
  26. package/dist/admin/es6.classes.d.ts +5 -2
  27. package/dist/admin/es6.classes.d.ts.map +1 -1
  28. package/dist/admin/es6.classes.js +4 -0
  29. package/dist/admin/es6.classes.js.map +1 -1
  30. package/dist/admin/libraries/api.key.data.processor.d.ts +3 -1
  31. package/dist/admin/libraries/api.key.data.processor.d.ts.map +1 -1
  32. package/dist/admin/libraries/api.key.data.processor.js +3 -6
  33. package/dist/admin/libraries/api.key.data.processor.js.map +1 -1
  34. package/dist/admin/libraries/bulk.user.data.processor.d.ts.map +1 -1
  35. package/dist/admin/libraries/bulk.user.data.processor.js +13 -5
  36. package/dist/admin/libraries/bulk.user.data.processor.js.map +1 -1
  37. package/dist/admin/libraries/client.membership.data.processor.d.ts +14 -0
  38. package/dist/admin/libraries/client.membership.data.processor.d.ts.map +1 -0
  39. package/dist/admin/libraries/client.membership.data.processor.js +56 -0
  40. package/dist/admin/libraries/client.membership.data.processor.js.map +1 -0
  41. package/dist/admin/libraries/client.user.data.processor.d.ts +1 -2
  42. package/dist/admin/libraries/client.user.data.processor.d.ts.map +1 -1
  43. package/dist/admin/libraries/client.user.data.processor.js +24 -31
  44. package/dist/admin/libraries/client.user.data.processor.js.map +1 -1
  45. package/dist/admin/libraries/client.user.delete.processor.d.ts.map +1 -1
  46. package/dist/admin/libraries/client.user.delete.processor.js +4 -0
  47. package/dist/admin/libraries/client.user.delete.processor.js.map +1 -1
  48. package/dist/admin/libraries/client.user.list.processor.d.ts.map +1 -1
  49. package/dist/admin/libraries/client.user.list.processor.js +14 -2
  50. package/dist/admin/libraries/client.user.list.processor.js.map +1 -1
  51. package/dist/admin/libraries/scope.data.processor.d.ts +1 -0
  52. package/dist/admin/libraries/scope.data.processor.d.ts.map +1 -1
  53. package/dist/admin/libraries/scope.data.processor.js +20 -0
  54. package/dist/admin/libraries/scope.data.processor.js.map +1 -1
  55. package/dist/admin/libraries/scope.list.processor.d.ts +2 -0
  56. package/dist/admin/libraries/scope.list.processor.d.ts.map +1 -1
  57. package/dist/admin/libraries/scope.list.processor.js +23 -1
  58. package/dist/admin/libraries/scope.list.processor.js.map +1 -1
  59. package/dist/admin/libraries/tenant.delete.processor.d.ts.map +1 -1
  60. package/dist/admin/libraries/tenant.delete.processor.js +22 -9
  61. package/dist/admin/libraries/tenant.delete.processor.js.map +1 -1
  62. package/dist/admin/libraries/user.data.processor.d.ts.map +1 -1
  63. package/dist/admin/libraries/user.data.processor.js +4 -1
  64. package/dist/admin/libraries/user.data.processor.js.map +1 -1
  65. package/dist/auth/auth.module.d.ts.map +1 -1
  66. package/dist/auth/auth.module.js +28 -5
  67. package/dist/auth/auth.module.js.map +1 -1
  68. package/dist/auth/controllers/auth.controller.d.ts +8 -7
  69. package/dist/auth/controllers/auth.controller.d.ts.map +1 -1
  70. package/dist/auth/controllers/auth.controller.js +36 -12
  71. package/dist/auth/controllers/auth.controller.js.map +1 -1
  72. package/dist/auth/controllers/impersonation.controller.d.ts +2 -2
  73. package/dist/auth/controllers/impersonation.controller.d.ts.map +1 -1
  74. package/dist/auth/controllers/tenant.invitation.controller.d.ts +18 -0
  75. package/dist/auth/controllers/tenant.invitation.controller.d.ts.map +1 -0
  76. package/dist/auth/controllers/tenant.invitation.controller.js +120 -0
  77. package/dist/auth/controllers/tenant.invitation.controller.js.map +1 -0
  78. package/dist/auth/controllers/tenant.member.controller.d.ts +18 -0
  79. package/dist/auth/controllers/tenant.member.controller.d.ts.map +1 -0
  80. package/dist/auth/controllers/tenant.member.controller.js +129 -0
  81. package/dist/auth/controllers/tenant.member.controller.js.map +1 -0
  82. package/dist/auth/controllers/user.invitation.controller.d.ts +12 -0
  83. package/dist/auth/controllers/user.invitation.controller.d.ts.map +1 -0
  84. package/dist/auth/controllers/user.invitation.controller.js +76 -0
  85. package/dist/auth/controllers/user.invitation.controller.js.map +1 -0
  86. package/dist/auth/controllers/user.organization.controller.d.ts +17 -0
  87. package/dist/auth/controllers/user.organization.controller.d.ts.map +1 -0
  88. package/dist/auth/controllers/user.organization.controller.js +88 -0
  89. package/dist/auth/controllers/user.organization.controller.js.map +1 -0
  90. package/dist/auth/dtos/invite.tenant.user.dto.d.ts +6 -0
  91. package/dist/auth/dtos/invite.tenant.user.dto.d.ts.map +1 -0
  92. package/dist/auth/dtos/invite.tenant.user.dto.js +45 -0
  93. package/dist/auth/dtos/invite.tenant.user.dto.js.map +1 -0
  94. package/dist/auth/dtos/member.roles.dto.d.ts +4 -0
  95. package/dist/auth/dtos/member.roles.dto.d.ts.map +1 -0
  96. package/dist/auth/dtos/member.roles.dto.js +28 -0
  97. package/dist/auth/dtos/member.roles.dto.js.map +1 -0
  98. package/dist/auth/dtos/switch.organization.dto.d.ts +5 -0
  99. package/dist/auth/dtos/switch.organization.dto.d.ts.map +1 -0
  100. package/dist/auth/dtos/switch.organization.dto.js +25 -0
  101. package/dist/auth/dtos/switch.organization.dto.js.map +1 -0
  102. package/dist/auth/dtos/tenant.invitation.list.dto.d.ts +5 -0
  103. package/dist/auth/dtos/tenant.invitation.list.dto.d.ts.map +1 -0
  104. package/dist/auth/dtos/tenant.invitation.list.dto.js +27 -0
  105. package/dist/auth/dtos/tenant.invitation.list.dto.js.map +1 -0
  106. package/dist/auth/dtos/tenant.member.list.dto.d.ts +5 -0
  107. package/dist/auth/dtos/tenant.member.list.dto.d.ts.map +1 -0
  108. package/dist/auth/dtos/tenant.member.list.dto.js +27 -0
  109. package/dist/auth/dtos/tenant.member.list.dto.js.map +1 -0
  110. package/dist/auth/entities/scope.entity.d.ts +2 -0
  111. package/dist/auth/entities/scope.entity.d.ts.map +1 -1
  112. package/dist/auth/entities/scope.entity.js +9 -0
  113. package/dist/auth/entities/scope.entity.js.map +1 -1
  114. package/dist/auth/entities/tenant.invitation.entity.d.ts +13 -0
  115. package/dist/auth/entities/tenant.invitation.entity.d.ts.map +1 -0
  116. package/dist/auth/entities/tenant.invitation.entity.js +52 -0
  117. package/dist/auth/entities/tenant.invitation.entity.js.map +1 -0
  118. package/dist/auth/entities/tenant.user.entity.d.ts +8 -0
  119. package/dist/auth/entities/tenant.user.entity.d.ts.map +1 -0
  120. package/dist/auth/entities/tenant.user.entity.js +35 -0
  121. package/dist/auth/entities/tenant.user.entity.js.map +1 -0
  122. package/dist/auth/entities/user.entity.d.ts +5 -0
  123. package/dist/auth/entities/user.entity.d.ts.map +1 -1
  124. package/dist/auth/entities/user.entity.js +17 -0
  125. package/dist/auth/entities/user.entity.js.map +1 -1
  126. package/dist/auth/entities/user.role.entity.d.ts +2 -2
  127. package/dist/auth/entities/user.role.entity.d.ts.map +1 -1
  128. package/dist/auth/entities/user.role.entity.js +2 -2
  129. package/dist/auth/entities/user.role.entity.js.map +1 -1
  130. package/dist/auth/enums/auth.default.enum.d.ts +3 -1
  131. package/dist/auth/enums/auth.default.enum.d.ts.map +1 -1
  132. package/dist/auth/enums/auth.default.enum.js +2 -0
  133. package/dist/auth/enums/auth.default.enum.js.map +1 -1
  134. package/dist/auth/enums/tenant.invitation.default.enum.d.ts +4 -0
  135. package/dist/auth/enums/tenant.invitation.default.enum.d.ts.map +1 -0
  136. package/dist/auth/enums/tenant.invitation.default.enum.js +8 -0
  137. package/dist/auth/enums/tenant.invitation.default.enum.js.map +1 -0
  138. package/dist/auth/enums/tenant.invitation.status.enum.d.ts +7 -0
  139. package/dist/auth/enums/tenant.invitation.status.enum.d.ts.map +1 -0
  140. package/dist/auth/enums/tenant.invitation.status.enum.js +11 -0
  141. package/dist/auth/enums/tenant.invitation.status.enum.js.map +1 -0
  142. package/dist/auth/enums/user.type.enum.d.ts.map +1 -1
  143. package/dist/auth/enums/user.type.enum.js.map +1 -1
  144. package/dist/auth/es6.classes.d.ts +15 -4
  145. package/dist/auth/es6.classes.d.ts.map +1 -1
  146. package/dist/auth/es6.classes.js +35 -2
  147. package/dist/auth/es6.classes.js.map +1 -1
  148. package/dist/auth/helpers/auth.d.ts +1 -1
  149. package/dist/auth/helpers/auth.d.ts.map +1 -1
  150. package/dist/auth/helpers/auth.js +7 -4
  151. package/dist/auth/helpers/auth.js.map +1 -1
  152. package/dist/auth/processors/change.password.data.processor.d.ts.map +1 -1
  153. package/dist/auth/processors/change.password.data.processor.js +1 -0
  154. package/dist/auth/processors/change.password.data.processor.js.map +1 -1
  155. package/dist/auth/processors/google.user.data.processor.js +1 -1
  156. package/dist/auth/processors/google.user.data.processor.js.map +1 -1
  157. package/dist/auth/processors/register.user.data.processor.js +1 -1
  158. package/dist/auth/processors/register.user.data.processor.js.map +1 -1
  159. package/dist/auth/processors/tenant.invitation.data.processor.d.ts +20 -0
  160. package/dist/auth/processors/tenant.invitation.data.processor.d.ts.map +1 -0
  161. package/dist/auth/processors/tenant.invitation.data.processor.js +112 -0
  162. package/dist/auth/processors/tenant.invitation.data.processor.js.map +1 -0
  163. package/dist/auth/processors/tenant.invitation.list.processor.d.ts +13 -0
  164. package/dist/auth/processors/tenant.invitation.list.processor.d.ts.map +1 -0
  165. package/dist/auth/processors/tenant.invitation.list.processor.js +67 -0
  166. package/dist/auth/processors/tenant.invitation.list.processor.js.map +1 -0
  167. package/dist/auth/processors/tenant.member.list.processor.d.ts +13 -0
  168. package/dist/auth/processors/tenant.member.list.processor.d.ts.map +1 -0
  169. package/dist/auth/processors/tenant.member.list.processor.js +66 -0
  170. package/dist/auth/processors/tenant.member.list.processor.js.map +1 -0
  171. package/dist/auth/services/admin.auth.service.d.ts.map +1 -1
  172. package/dist/auth/services/admin.auth.service.js +2 -2
  173. package/dist/auth/services/admin.auth.service.js.map +1 -1
  174. package/dist/auth/services/api.key.service.d.ts +3 -1
  175. package/dist/auth/services/api.key.service.d.ts.map +1 -1
  176. package/dist/auth/services/api.key.service.js +6 -3
  177. package/dist/auth/services/api.key.service.js.map +1 -1
  178. package/dist/auth/services/auth.service.d.ts +5 -0
  179. package/dist/auth/services/auth.service.d.ts.map +1 -1
  180. package/dist/auth/services/auth.service.js +51 -13
  181. package/dist/auth/services/auth.service.js.map +1 -1
  182. package/dist/auth/services/impersonation.service.d.ts +2 -2
  183. package/dist/auth/services/impersonation.service.d.ts.map +1 -1
  184. package/dist/auth/services/impersonation.service.js +1 -1
  185. package/dist/auth/services/impersonation.service.js.map +1 -1
  186. package/dist/auth/services/scope.service.d.ts +6 -0
  187. package/dist/auth/services/scope.service.d.ts.map +1 -1
  188. package/dist/auth/services/scope.service.js +40 -9
  189. package/dist/auth/services/scope.service.js.map +1 -1
  190. package/dist/auth/services/tenant.invitation.service.d.ts +26 -0
  191. package/dist/auth/services/tenant.invitation.service.d.ts.map +1 -0
  192. package/dist/auth/services/tenant.invitation.service.js +212 -0
  193. package/dist/auth/services/tenant.invitation.service.js.map +1 -0
  194. package/dist/auth/services/tenant.membership.service.d.ts +29 -0
  195. package/dist/auth/services/tenant.membership.service.d.ts.map +1 -0
  196. package/dist/auth/services/tenant.membership.service.js +178 -0
  197. package/dist/auth/services/tenant.membership.service.js.map +1 -0
  198. package/dist/auth/types/auth.types.d.ts +24 -2
  199. package/dist/auth/types/auth.types.d.ts.map +1 -1
  200. package/dist/auth/utilities/access.revocation.d.ts +2 -0
  201. package/dist/auth/utilities/access.revocation.d.ts.map +1 -1
  202. package/dist/auth/utilities/access.revocation.js +12 -0
  203. package/dist/auth/utilities/access.revocation.js.map +1 -1
  204. package/dist/auth/utilities/auth.utilities.d.ts +1 -0
  205. package/dist/auth/utilities/auth.utilities.d.ts.map +1 -1
  206. package/dist/auth/utilities/auth.utilities.js +4 -0
  207. package/dist/auth/utilities/auth.utilities.js.map +1 -1
  208. package/dist/auth/utilities/tenant.access.d.ts +8 -0
  209. package/dist/auth/utilities/tenant.access.d.ts.map +1 -0
  210. package/dist/auth/utilities/tenant.access.js +61 -0
  211. package/dist/auth/utilities/tenant.access.js.map +1 -0
  212. package/dist/common/es6.classes.d.ts +2 -2
  213. package/dist/constants/entity.constants.d.ts +2 -0
  214. package/dist/constants/entity.constants.d.ts.map +1 -1
  215. package/dist/constants/entity.constants.js +2 -0
  216. package/dist/constants/entity.constants.js.map +1 -1
  217. package/dist/constants/entity.maps.d.ts +4 -0
  218. package/dist/constants/entity.maps.d.ts.map +1 -1
  219. package/dist/constants/entity.maps.js +4 -0
  220. package/dist/constants/entity.maps.js.map +1 -1
  221. package/dist/constants/job.constants.d.ts +1 -0
  222. package/dist/constants/job.constants.d.ts.map +1 -1
  223. package/dist/constants/job.constants.js +1 -0
  224. package/dist/constants/job.constants.js.map +1 -1
  225. package/dist/index.d.ts +6 -1
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.js +14 -3
  228. package/dist/index.js.map +1 -1
  229. package/dist/migrations/1749600000003.CreateSysUsersTable.d.ts.map +1 -1
  230. package/dist/migrations/1749600000003.CreateSysUsersTable.js +4 -0
  231. package/dist/migrations/1749600000003.CreateSysUsersTable.js.map +1 -1
  232. package/dist/migrations/1749600000006.CreateSysUserRolesJoinTable.d.ts.map +1 -1
  233. package/dist/migrations/1749600000006.CreateSysUserRolesJoinTable.js +8 -1
  234. package/dist/migrations/1749600000006.CreateSysUserRolesJoinTable.js.map +1 -1
  235. package/dist/migrations/1749600000025.CreateSysScopesTable.d.ts.map +1 -1
  236. package/dist/migrations/1749600000025.CreateSysScopesTable.js +7 -0
  237. package/dist/migrations/1749600000025.CreateSysScopesTable.js.map +1 -1
  238. package/dist/migrations/1749600000030.CreateSysTenantUsersTable.d.ts +6 -0
  239. package/dist/migrations/1749600000030.CreateSysTenantUsersTable.d.ts.map +1 -0
  240. package/dist/migrations/1749600000030.CreateSysTenantUsersTable.js +33 -0
  241. package/dist/migrations/1749600000030.CreateSysTenantUsersTable.js.map +1 -0
  242. package/dist/migrations/1749600000031.CreateSysTenantInvitationsTable.d.ts +6 -0
  243. package/dist/migrations/1749600000031.CreateSysTenantInvitationsTable.d.ts.map +1 -0
  244. package/dist/migrations/1749600000031.CreateSysTenantInvitationsTable.js +43 -0
  245. package/dist/migrations/1749600000031.CreateSysTenantInvitationsTable.js.map +1 -0
  246. package/dist/notification/enums/email.notification.default.enum.d.ts +1 -0
  247. package/dist/notification/enums/email.notification.default.enum.d.ts.map +1 -1
  248. package/dist/notification/enums/email.notification.default.enum.js +1 -0
  249. package/dist/notification/enums/email.notification.default.enum.js.map +1 -1
  250. package/dist/notification/enums/email.template.identifier.enum.d.ts +2 -1
  251. package/dist/notification/enums/email.template.identifier.enum.d.ts.map +1 -1
  252. package/dist/notification/enums/email.template.identifier.enum.js +1 -0
  253. package/dist/notification/enums/email.template.identifier.enum.js.map +1 -1
  254. package/dist/notification/es6.classes.d.ts +2 -1
  255. package/dist/notification/es6.classes.d.ts.map +1 -1
  256. package/dist/notification/es6.classes.js +6 -1
  257. package/dist/notification/es6.classes.js.map +1 -1
  258. package/dist/notification/jobs/tenant.user.invited.mail.job.d.ts +14 -0
  259. package/dist/notification/jobs/tenant.user.invited.mail.job.d.ts.map +1 -0
  260. package/dist/notification/jobs/tenant.user.invited.mail.job.js +57 -0
  261. package/dist/notification/jobs/tenant.user.invited.mail.job.js.map +1 -0
  262. package/dist/notification/notification.module.d.ts.map +1 -1
  263. package/dist/notification/notification.module.js +3 -1
  264. package/dist/notification/notification.module.js.map +1 -1
  265. package/dist/notification/types/email.notification.types.d.ts +9 -0
  266. package/dist/notification/types/email.notification.types.d.ts.map +1 -1
  267. package/package.json +1 -1
package/README.md CHANGED
@@ -104,13 +104,13 @@ these are free to change without a breaking release.
104
104
  | Area | Key exports | Notes |
105
105
  | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
106
106
  | Entities | `RootEntity`, `CommonEntity`, `CommonAdminEntity`, `UserEntity`, `AdminUserEntity`, `SystemRoleEntity`, `SystemAdminRoleEntity`, ... | uuid PK, soft deletes, `created_by`/`updated_by` (+ `creator`/`updater` relations), jsonb `attributes`; entity-level `findOneOrNew`, `hardDelete`, `restore`, `paginate` statics plus a row-wise `softDelete()` |
107
- | Migrations | `MigrationUtility`, `SeederUtility` (the 29 table migrations ship in `dist/migrations` — glob them, they are not barrel exports) | fluent `this.string()`, `this.numeric()`, `addRecord()` seeding |
107
+ | Migrations | `MigrationUtility`, `SeederUtility` (the 31 table migrations ship in `dist/migrations` — glob them, they are not barrel exports) | fluent `this.string()`, `this.numeric()`, `addRecord()` seeding |
108
108
  | Queue | `QueueModule`, `QueueModule.withConnection()`, `QueueService`, `CommonJob` | BullMQ `@Processor`/`WorkerHost` consumer; auto-discovered jobs, duplicate prevention, recurring schedulers, completed jobs cleared from Redis on success (1-day TTL on failures), `clearQueue()`, retries, failures persisted to `sys_failed_jobs`; connection from `BULL_REDIS_*` or supplied by the app — never register `BullModule.forRoot()` yourself, two roots race over the worker's connection |
109
109
  | Scheduled events | `SystemScheduledTaskEntity`, `ScheduledEventEntity`, `ScheduleKind`, `ScheduleSpec`, `IsCronExpression` | schedule definitions in `sys_scheduled_tasks` → events in `sys_scheduled_events`; interval / cron / once specs with timezones, drift-free slots, horizon materialisation, catch-up + overlap policies, fire-once dispatch with backoff, cadence via `SCHEDULED_EVENT_MIN` |
110
- | Auth | `AuthModule`, `AuthService.validateRole()`, `RoleTier`, `TenantRole`, `Auth`, `JwtMiddleware` | imperative auth (open by default); `<module>.<tier>` role hierarchy (manager > writer > viewer), with `global.admin` overriding every role check; JwtMiddleware resolves the user into `Auth`'s AsyncLocalStorage context per request; access + rotating refresh tokens; session-based logout invalidation (`sys_auth_sessions`); Google SSO via ID token at `POST /auth/google`; impersonation — a tenantless `has_global_access` user signs into one organization at `POST /auth/impersonation/login` |
110
+ | Auth | `AuthModule`, `AuthService.validateRole()`, `RoleTier`, `TenantRole`, `Auth`, `JwtMiddleware` | imperative auth (open by default); `<module>.<tier>` role hierarchy (manager > writer > viewer), with `global.admin` overriding every role check; JwtMiddleware resolves the user into `Auth`'s AsyncLocalStorage context per request; access + rotating refresh tokens; session-based logout invalidation (`sys_auth_sessions`); Google SSO via ID token at `POST /auth/google`; impersonation — a tenantless `has_global_access` user signs into one organization at `POST /auth/impersonation/login`; multi-organization membership with per-organization roles, organization switching and `global.admin` invitations (`TenantMembershipService`, `TenantInvitationService`) |
111
111
  | Admin auth | `AdminAuthService.validateRole()`, `AdminAuth`, `AdminJwtMiddleware` (endpoints at `/admin/auth`) | fully separate stack for back-office admins — own users table (`sys_admin_users`), own roles (`sys_admin_roles`/`sys_auser_roles`), own sessions/refresh tokens (shared tables, `is_admin` flag) |
112
112
  | API keys | `ApiKeyService`, `ApiKeyGuard` / `ApiKeyMiddleware`, `@ApiKeyScopes()`, `ApiKeyContext` | hashed keys in `sys_api_keys` (admin-owned), one tenant per key, expiry/revocation, `x-api-key` header; `validateAccess(scope)` returns the tenant the key acts for |
113
- | Scopes | `ScopeService`, `AuthService.validateAccess()`, `ScopeEntity`, `TenantScopeEntity`, `ApiScopeEntity` | one feature named once in `sys_scopes`, then granted per organization (`sys_tenant_scopes`) or per API key (`sys_api_scopes`) — never an array on the principal |
113
+ | Scopes | `ScopeService`, `AuthService.validateAccess()`, `ScopeEntity`, `TenantScopeEntity`, `ApiScopeEntity` | one feature named once in `sys_scopes`, optionally with child scopes under it, then granted per organization (`sys_tenant_scopes`) or per API key (`sys_api_scopes`) — never an array on the principal |
114
114
  | Multi-tenancy | `TenantModule`, `TenantEntity`, `CommonTenantEntity`, `TenantContextService`, `TenantContextMiddleware` | AsyncLocalStorage tenant context; resolve by header, slug, or domain; tenants are onboarded by admins (`TenantEntity.creator` → `AdminUserEntity`) |
115
115
  | Admin | `AdminModule` (its controllers, DTOs and processors are internal — import the module and hit the endpoints), `GlobalAdminRoles` | back-office APIs: tenant onboarding, client/admin/system user registration (single + bulk), the `has_global_access` grant that enables impersonation, tenant + scheduled-task listing, the email/PDF template catalogues (read at content-reader, written at content-manager, deleted at global admin); 4-tier `GlobalAdminRoles` gate over `sys_admin_roles`; Swagger at `/docs` (hidden in production) |
116
116
  | Notifications | `NotificationModule`, `NotificationService`, `FcmPushNotificationService` | in-app rows + FCM push (optional `firebase-admin`); device token registry |
@@ -207,6 +207,12 @@ caller's tenant holds that scope (`sys_tenant_scopes` against the `sys_scopes`
207
207
  catalogue), then delegates to `validateRole()`. One call answers "is this feature
208
208
  sold to them?" and "is this person allowed to use it?" in that order.
209
209
 
210
+ A scope can be a parent of others (`parent_id` on `sys_scopes`), which is how part
211
+ of a feature is sold on its own. Granting the parent grants every child under it, so
212
+ a tenant enabled for `billing.invoices` clears `billing.invoices.refund` too;
213
+ granting children grants only those, and never the parent. The catalogue stops at two
214
+ levels — a child holds no children — so a grant expands in exactly one hop.
215
+
210
216
  ```ts
211
217
  const { user } = await this.authService.validateAccess('billing.invoices');
212
218
  const { user } = await this.authService.validateAccess(
@@ -217,7 +223,8 @@ const { user } = await this.authService.validateAccess(
217
223
 
218
224
  `AuthController` (mounted at `/auth`) exposes the ready-made flows: `POST
219
225
  /auth/login`, `/auth/google`, `/auth/register`, `/auth/refresh`, `/auth/logout`,
220
- `/auth/change-password`, and `GET /auth/me`. Passwords are hashed/verified via
226
+ `/auth/change-password`, and `GET /auth/me` (user, roles in the session's
227
+ organization, `organizations` to switch to, pending `invitations`). Passwords are hashed/verified via
221
228
  `AuthUtility` (bcrypt); the write flows use the processor lifecycle. Credential
222
229
  misses spend the same bcrypt work as a wrong password
223
230
  (`AuthUtility.compareAgainstDummy()`), so response timing does not reveal
@@ -246,6 +253,35 @@ impersonated session, for an in-app switcher), each login writes an
246
253
  tenant from real membership with `Auth.isImpersonating()` /
247
254
  `Auth.impersonatedTenant()`.
248
255
 
256
+ **Multiple organizations** — a tenant user may belong to many organizations
257
+ (`sys_tenant_users`), with roles granted per organization (`sys_user_roles.tenant_id`).
258
+ Each session works in one, held on its `sys_auth_sessions` row and mirrored onto
259
+ `Auth.user().organization_id`, so role and scope checks only ever see that
260
+ organization's grants. Login lands in the last organization switched to (remembered in
261
+ `sys_users.organization_id`) or the first membership; a user with none gets a
262
+ tenantless session. `GET /auth/organizations` lists memberships and
263
+ `POST /auth/organizations/switch` (`{ tenant_id, refresh_token }`) retires the current
264
+ session and returns a pair bound to the chosen one; `POST /auth/organizations/:id/leave`
265
+ ends a membership and returns a fresh pair. A refresh re-checks the membership and
266
+ the tenant, so a removed member or a deactivated tenant drops the organization.
267
+
268
+ **Invitations** — an organization's `global.admin` invites an email with roles at
269
+ `POST /organization/invitations` (`{ email, role_ids }`; also `POST .../list`,
270
+ `DELETE .../:id` to revoke, `GET .../roles` for the picker). An address with no account gets one: a random one-time password is mailed through the
271
+ `tenant-user-invited` template and `password_change_required` is set, so every endpoint
272
+ except `GET /auth/me` and `POST /auth/change-password` (`AuthService.validateIdentity()`)
273
+ refuses until it is changed; resending the invitation re-issues it. The invitee
274
+ sees pending ones on `GET /auth/me` / `GET /auth/invitations` and answers with
275
+ `POST /auth/invitations/:id/accept` (membership + roles, then switch to use it) or
276
+ `.../decline`. Invitations expire after `TENANT_INVITATION_EXPIRY` (default `7d`).
277
+ Acceptance trusts the account's email — emails are unique case-insensitively, but
278
+ verify addresses if you allow open self-registration. The same `global.admin` manages
279
+ members at `/organization/members` (`POST list`, `POST :userId/roles`,
280
+ `POST :userId/deactivate` / `reactivate`, `DELETE :userId`) and resends invitations
281
+ (`POST /organization/invitations/:id/resend`). Deactivation suspends the membership,
282
+ not the account (which may belong elsewhere); an organization always keeps at least
283
+ one active `global.admin`. A deactivated account is refused on its next request.
284
+
249
285
  **Google SSO** — the client posts a Google ID token as `{ id_token }` to
250
286
  `POST /auth/google`. `GoogleAuthService` verifies it against Google's tokeninfo
251
287
  endpoint (audience must match `GOOGLE_CLIENT_ID`, issuer `accounts.google.com`,
@@ -634,6 +670,7 @@ Requires the optional peer dependency `puppeteer`.
634
670
  | Variable | Default | Description |
635
671
  | -------------------- | ------------- | ----------------------------------------------- |
636
672
  | `TENANT_HEADER_NAME` | `x-tenant-id` | Request header carrying the tenant UUID or slug |
673
+ | `TENANT_INVITATION_EXPIRY` | `7d` | How long an organization invitation stays answerable |
637
674
 
638
675
  ### API Keys
639
676
 
@@ -655,7 +692,8 @@ content reader.
655
692
 
656
693
  A key belongs to one tenant and holds its scopes as `sys_api_scopes` rows against
657
694
  the `sys_scopes` catalogue — there is no scopes array on the key, and a key grants
658
- nothing it was not given (a granted `*` is the only blanket). `ApiKeyMiddleware`
695
+ nothing it was not given (a granted `*` is the only blanket, and a granted parent
696
+ scope carries its children). `ApiKeyMiddleware`
659
697
  resolves the key, its tenant and its scope identifiers once per request into
660
698
  `ApiKeyContext`; enforce from there:
661
699
 
@@ -1060,6 +1098,9 @@ pass the actor to a processor.
1060
1098
  | `POST /admin/tenant-users/list` | content reader | `ClientUserListProcessor` |
1061
1099
  | `GET /admin/tenant-users/:id` | content reader | the row |
1062
1100
  | `DELETE /admin/tenant-users/:id` | admin | `ClientUserDeleteProcessor` |
1101
+ | `POST /admin/tenant-users/memberships` | admin | `ClientMembershipDataProcessor` — add an existing user to a tenant |
1102
+ | `DELETE /admin/tenant-users/:id/memberships/:tenantId` | admin | `TenantMembershipService.removeMember` |
1103
+ | `POST /admin/tenant-users/:id/memberships/:tenantId/deactivate` · `/reactivate` | admin | `TenantMembershipService.setMemberActive` |
1063
1104
  | `POST /admin/system-users` | super admin | `SystemUserDataProcessor` (upsert — send `id` to update) |
1064
1105
  | `POST /admin/system-users/list` | content reader | `SystemUserListProcessor` (scoped to `user_type = system.user`) |
1065
1106
  | `GET /admin/system-users/:id` | content reader | the row |
@@ -1088,8 +1129,10 @@ pass the actor to a processor.
1088
1129
  | `DELETE /admin/pdf-templates/:id` | **admin** | `TemplateService.deletePdfTemplate` |
1089
1130
  | `POST /admin/scopes` | content manager | `ScopeDataProcessor` (upsert — send `id` to update) |
1090
1131
  | `POST /admin/scopes/list` | content reader | `ScopeListProcessor` |
1132
+ | `POST /admin/scopes/:id/children` | content manager | `ScopeDataProcessor` (upsert — parent taken from the path) |
1133
+ | `POST /admin/scopes/:id/children/list` | content reader | `ScopeListProcessor` (`parent_id` taken from the path) |
1091
1134
  | `GET /admin/scopes/:id` | content reader | the row |
1092
- | `DELETE /admin/scopes/:id` | content manager | `ScopeService.deleteScope` (cascades to every grant) |
1135
+ | `DELETE /admin/scopes/:id` | content manager, **admin** for a child | `ScopeService.deleteScope` (cascades to children and every grant) |
1093
1136
  | `POST /admin/api-keys` | admin | `ApiKeyDataProcessor` — returns `{ raw_key, api_key }` |
1094
1137
  | `POST /admin/api-keys/list` | content reader | `ApiKeyListProcessor` |
1095
1138
  | `GET /admin/api-keys/:id` | content reader | the row, its `scopes`, and `key` from admin up |
@@ -1117,12 +1160,18 @@ remote template, every mail already sent and every document already generated ar
1117
1160
  exactly as they are.
1118
1161
 
1119
1162
  **Scopes and grants.** A scope is defined once in `sys_scopes` (content manager),
1120
- then granted to the principals that hold it. `AddTenantDto.scope_ids` carries the
1121
- tenant's whole scope set — `setScopes()` grants what is new and soft-removes what is
1122
- gone, so an omitted list revokes them all (a picker has no other way to clear its
1123
- last selection); every other optional field on that DTO still keeps its stored value.
1124
- An API key can only be granted scopes its tenant already holds, so a key never
1125
- out-ranks the organization it acts for. The key comes back in the issue response as
1163
+ then granted to the principals that hold it. A scope sent with a `parent_id` — or
1164
+ posted to `/admin/scopes/:id/children` — is a child of that scope, and granting the
1165
+ parent grants it. `ScopeDataProcessor` keeps the catalogue two levels deep: a child
1166
+ never takes children, and a scope that already has children can never be turned into
1167
+ one. `AddTenantDto.scope_ids` carries the tenant's whole scope set — `setScopes()`
1168
+ grants what is new and soft-removes what is gone, so an omitted list revokes them all
1169
+ (a picker has no other way to clear its last selection); every other optional field on
1170
+ that DTO still keeps its stored value. An API key can only be granted scopes its
1171
+ tenant already holds — children of a held parent included — so a key never out-ranks
1172
+ the organization it acts for. Deleting a scope takes its children with it, which is
1173
+ why removing a child sits at the admin bar rather than the content-manager one: it
1174
+ narrows access tenants already have. The key comes back in the issue response as
1126
1175
  `raw_key`, and afterwards from `GET /admin/api-keys/:id` as `key` — for a global
1127
1176
  admin only.
1128
1177
 
@@ -1,5 +1,6 @@
1
1
  import { ListFilterService } from '../../common/services/list.filter.service';
2
2
  import { ApiKeyService } from '../../auth/services/api.key.service';
3
+ import { ScopeService } from '../../auth/services/scope.service';
3
4
  import { AdminAccessService } from '../services/admin.access.service';
4
5
  import { CommonParamsDto } from '../../common/dtos/common.params.dto';
5
6
  import { AddApiKeyDto } from '../dtos/add.api.key.dto';
@@ -7,8 +8,9 @@ import { ApiKeyListDto } from '../dtos/api.key.list.dto';
7
8
  export declare class AdminApiKeyController {
8
9
  private readonly adminAccessService;
9
10
  private readonly apiKeyService;
11
+ private readonly scopeService;
10
12
  private readonly listFilterService;
11
- constructor(adminAccessService: AdminAccessService, apiKeyService: ApiKeyService, listFilterService: ListFilterService);
13
+ constructor(adminAccessService: AdminAccessService, apiKeyService: ApiKeyService, scopeService: ScopeService, listFilterService: ListFilterService);
12
14
  issue(dto: AddApiKeyDto): Promise<import("../types/admin.types").IssuedApiKey>;
13
15
  list(dto: ApiKeyListDto): Promise<import("../..").CommonListResult>;
14
16
  detail({ id }: CommonParamsDto): Promise<import("../..").ApiKeyDetail>;
@@ -1 +1 @@
1
- {"version":3,"file":"admin.api.key.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.api.key.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,qBAGa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,iBAAiB;IASjD,KAAK,CAAS,GAAG,EAAE,YAAY;IAW/B,IAAI,CAAS,GAAG,EAAE,aAAa;IAW/B,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAgBvC,OAAO,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAWxC,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;CAI9C"}
1
+ {"version":3,"file":"admin.api.key.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.api.key.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD,qBAGa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAHjB,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB;IASjD,KAAK,CAAS,GAAG,EAAE,YAAY;IAe/B,IAAI,CAAS,GAAG,EAAE,aAAa;IAW/B,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAgBvC,OAAO,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAWxC,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;CAI9C"}
@@ -17,6 +17,7 @@ const common_1 = require("@nestjs/common");
17
17
  const swagger_1 = require("@nestjs/swagger");
18
18
  const list_filter_service_1 = require("../../common/services/list.filter.service");
19
19
  const api_key_service_1 = require("../../auth/services/api.key.service");
20
+ const scope_service_1 = require("../../auth/services/scope.service");
20
21
  const global_admin_roles_enum_1 = require("../../auth/enums/global.admin.roles.enum");
21
22
  const admin_access_service_1 = require("../services/admin.access.service");
22
23
  const common_params_dto_1 = require("../../common/dtos/common.params.dto");
@@ -25,14 +26,15 @@ const api_key_list_processor_1 = require("../libraries/api.key.list.processor");
25
26
  const add_api_key_dto_1 = require("../dtos/add.api.key.dto");
26
27
  const api_key_list_dto_1 = require("../dtos/api.key.list.dto");
27
28
  let AdminApiKeyController = class AdminApiKeyController {
28
- constructor(adminAccessService, apiKeyService, listFilterService) {
29
+ constructor(adminAccessService, apiKeyService, scopeService, listFilterService) {
29
30
  this.adminAccessService = adminAccessService;
30
31
  this.apiKeyService = apiKeyService;
32
+ this.scopeService = scopeService;
31
33
  this.listFilterService = listFilterService;
32
34
  }
33
35
  async issue(dto) {
34
36
  const { user } = await this.adminAccessService.validateAdmin();
35
- return new api_key_data_processor_1.ApiKeyDataProcessor(user, this.apiKeyService).process(dto);
37
+ return new api_key_data_processor_1.ApiKeyDataProcessor(user, this.apiKeyService, this.scopeService).process(dto);
36
38
  }
37
39
  async list(dto) {
38
40
  await this.adminAccessService.validateContentReader();
@@ -57,7 +59,7 @@ __decorate([
57
59
  (0, common_1.Post)(),
58
60
  (0, swagger_1.ApiOperation)({
59
61
  summary: 'Issue an API key for a tenant.',
60
- description: 'Create-only — `raw_key` is the full key and is returned exactly once, since only its hash is stored. A key can only be granted scopes its tenant already holds. Requires at least the global admin role.',
62
+ description: 'Create-only — `raw_key` is the full key and is returned exactly once, since only its hash is stored. A key can only be granted scopes its tenant already holds, which includes the children of any parent scope the tenant is enabled for. Requires at least the global admin role.',
61
63
  }),
62
64
  __param(0, (0, common_1.Body)()),
63
65
  __metadata("design:type", Function),
@@ -114,6 +116,7 @@ exports.AdminApiKeyController = AdminApiKeyController = __decorate([
114
116
  (0, common_1.Controller)('api/admin/api-keys'),
115
117
  __metadata("design:paramtypes", [admin_access_service_1.AdminAccessService,
116
118
  api_key_service_1.ApiKeyService,
119
+ scope_service_1.ScopeService,
117
120
  list_filter_service_1.ListFilterService])
118
121
  ], AdminApiKeyController);
119
122
  //# sourceMappingURL=admin.api.key.controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin.api.key.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.api.key.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.api.key.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.api.key.controller.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@ export declare class AdminScopeController {
12
12
  constructor(adminAccessService: AdminAccessService, scopeService: ScopeService, listFilterService: ListFilterService);
13
13
  save(dto: AddScopeDto): Promise<ScopeEntity>;
14
14
  list(dto: ScopeListDto): Promise<import("../..").CommonListResult>;
15
+ saveChild({ id }: CommonParamsDto, dto: AddScopeDto): Promise<ScopeEntity>;
16
+ children({ id }: CommonParamsDto, dto: ScopeListDto): Promise<import("../..").CommonListResult>;
15
17
  detail({ id }: CommonParamsDto): Promise<ScopeEntity>;
16
18
  remove({ id }: CommonParamsDto): Promise<import("../..").DeleteResult>;
17
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"admin.scope.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scope.controller.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAQ/D,qBAGa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB;IASjD,IAAI,CAAS,GAAG,EAAE,WAAW;IAU7B,IAAI,CAAS,GAAG,EAAE,YAAY;IAU9B,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAevC,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;CAI9C"}
1
+ {"version":3,"file":"admin.scope.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scope.controller.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAQ/D,qBAGa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,iBAAiB,EAAE,iBAAiB;IASjD,IAAI,CAAS,GAAG,EAAE,WAAW;IAW7B,IAAI,CAAS,GAAG,EAAE,YAAY;IAW9B,SAAS,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe,EAAU,GAAG,EAAE,WAAW;IAWpE,QAAQ,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe,EAAU,GAAG,EAAE,YAAY;IAapE,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAevC,MAAM,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;CAgB9C"}
@@ -18,6 +18,8 @@ const swagger_1 = require("@nestjs/swagger");
18
18
  const list_filter_service_1 = require("../../common/services/list.filter.service");
19
19
  const admin_access_service_1 = require("../services/admin.access.service");
20
20
  const common_params_dto_1 = require("../../common/dtos/common.params.dto");
21
+ const global_admin_roles_enum_1 = require("../../auth/enums/global.admin.roles.enum");
22
+ const access_exception_1 = require("../../global/exceptions/access.exception");
21
23
  const scope_service_1 = require("../../auth/services/scope.service");
22
24
  const scope_data_processor_1 = require("../libraries/scope.data.processor");
23
25
  const scope_list_processor_1 = require("../libraries/scope.list.processor");
@@ -38,6 +40,17 @@ let AdminScopeController = class AdminScopeController {
38
40
  await this.adminAccessService.validateContentReader();
39
41
  return new scope_list_processor_1.ScopeListProcessor(this.listFilterService).process(dto);
40
42
  }
43
+ async saveChild({ id }, dto) {
44
+ const { user } = await this.adminAccessService.validateContentManager();
45
+ return new scope_data_processor_1.ScopeDataProcessor(user).process({ ...dto, parent_id: id });
46
+ }
47
+ async children({ id }, dto) {
48
+ await this.adminAccessService.validateContentReader();
49
+ return new scope_list_processor_1.ScopeListProcessor(this.listFilterService).process({
50
+ ...dto,
51
+ parent_id: id,
52
+ });
53
+ }
41
54
  async detail({ id }) {
42
55
  await this.adminAccessService.validateContentReader();
43
56
  const scope = await scope_entity_1.ScopeEntity.findOne({ where: { id } });
@@ -46,8 +59,11 @@ let AdminScopeController = class AdminScopeController {
46
59
  return scope;
47
60
  }
48
61
  async remove({ id }) {
49
- const { user } = await this.adminAccessService.validateContentManager();
50
- return this.scopeService.deleteScope(id, user.id);
62
+ const access = await this.adminAccessService.validateContentManager();
63
+ if ((await this.scopeService.isChildScope(id)) &&
64
+ !this.adminAccessService.holdsAtLeast(access, global_admin_roles_enum_1.GlobalAdminRoles.GLOBAL_ADMIN))
65
+ throw new access_exception_1.AccessException(`Deleting a child scope requires at least the "${global_admin_roles_enum_1.GlobalAdminRoles.GLOBAL_ADMIN}" role.`);
66
+ return this.scopeService.deleteScope(id, access.user.id);
51
67
  }
52
68
  };
53
69
  exports.AdminScopeController = AdminScopeController;
@@ -55,7 +71,7 @@ __decorate([
55
71
  (0, common_1.Post)(),
56
72
  (0, swagger_1.ApiOperation)({
57
73
  summary: 'Define a scope, or update an existing one.',
58
- description: 'Send an `id` to edit that scope; omit it to define a new one. `identifier` is what code checks and is unique across the catalogue. Requires at least the global content manager role.',
74
+ description: 'Send an `id` to edit that scope; omit it to define a new one. `identifier` is what code checks and is unique across the catalogue. `parent_id` files the scope under another one — a scope that already has children of its own cannot be given a parent. Requires at least the global content manager role.',
59
75
  }),
60
76
  __param(0, (0, common_1.Body)()),
61
77
  __metadata("design:type", Function),
@@ -66,13 +82,37 @@ __decorate([
66
82
  (0, common_1.Post)('list'),
67
83
  (0, swagger_1.ApiOperation)({
68
84
  summary: 'List, search and filter scopes.',
69
- description: 'Requires at least the global content reader role.',
85
+ description: 'Rows carry `parent_id`, the parent labels `parent_identifier` and `parent_name`, and `child_count` — so a parent and a child are told apart without a second read. Requires at least the global content reader role.',
70
86
  }),
71
87
  __param(0, (0, common_1.Body)()),
72
88
  __metadata("design:type", Function),
73
89
  __metadata("design:paramtypes", [scope_list_dto_1.ScopeListDto]),
74
90
  __metadata("design:returntype", Promise)
75
91
  ], AdminScopeController.prototype, "list", null);
92
+ __decorate([
93
+ (0, common_1.Post)(':id/children'),
94
+ (0, swagger_1.ApiOperation)({
95
+ summary: 'Add a child scope under this one, or update an existing child.',
96
+ description: 'The parent comes from the path, so the body is an ordinary scope — send an `id` to edit a child, omit it to define one. The parent has to be a parent itself: a child scope never holds children. Requires at least the global content manager role.',
97
+ }),
98
+ __param(0, (0, common_1.Param)()),
99
+ __param(1, (0, common_1.Body)()),
100
+ __metadata("design:type", Function),
101
+ __metadata("design:paramtypes", [common_params_dto_1.CommonParamsDto, add_scope_dto_1.AddScopeDto]),
102
+ __metadata("design:returntype", Promise)
103
+ ], AdminScopeController.prototype, "saveChild", null);
104
+ __decorate([
105
+ (0, common_1.Post)(':id/children/list'),
106
+ (0, swagger_1.ApiOperation)({
107
+ summary: 'List, search and filter the children of one scope.',
108
+ description: 'The same listing as `POST /list`, with `parent_id` taken from the path — so a body that names a different parent cannot widen it. Requires at least the global content reader role.',
109
+ }),
110
+ __param(0, (0, common_1.Param)()),
111
+ __param(1, (0, common_1.Body)()),
112
+ __metadata("design:type", Function),
113
+ __metadata("design:paramtypes", [common_params_dto_1.CommonParamsDto, scope_list_dto_1.ScopeListDto]),
114
+ __metadata("design:returntype", Promise)
115
+ ], AdminScopeController.prototype, "children", null);
76
116
  __decorate([
77
117
  (0, common_1.Get)(':id'),
78
118
  (0, swagger_1.ApiOperation)({
@@ -88,7 +128,7 @@ __decorate([
88
128
  (0, common_1.Delete)(':id'),
89
129
  (0, swagger_1.ApiOperation)({
90
130
  summary: 'Delete a scope.',
91
- description: 'Soft delete: the row keeps its data with `deleted_at` set and drops out of every listing. Every grant of it goes too — the tenant rows in `sys_tenant_scopes` and the API-key rows in `sys_api_scopes` — so no principal keeps a feature the catalogue no longer defines. Requires at least the global content manager role.',
131
+ description: 'Soft delete: the row keeps its data with `deleted_at` set and drops out of every listing. Its children go with it, and so does every grant of any of them — the tenant rows in `sys_tenant_scopes` and the API-key rows in `sys_api_scopes` — so no principal keeps a feature the catalogue no longer defines. Requires at least the global content manager role, and the global admin role to delete a child scope: a child is a slice of a feature tenants already hold, and removing it narrows their access rather than retiring the feature.',
92
132
  }),
93
133
  __param(0, (0, common_1.Param)()),
94
134
  __metadata("design:type", Function),
@@ -1 +1 @@
1
- {"version":3,"file":"admin.scope.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scope.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.scope.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scope.controller.ts"],"names":[],"mappings":"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"}
@@ -7,15 +7,22 @@ import { AdminAccessService } from '../services/admin.access.service';
7
7
  import { TenantService } from '../../tenant/services/tenant.service';
8
8
  import { TenantUserOnboardedMailJob } from '../../notification/jobs/tenant.user.onboarded.mail.job';
9
9
  import { ListFilterService } from '../../common/services/list.filter.service';
10
+ import { TenantMembershipService } from '../../auth/services/tenant.membership.service';
11
+ import { AddClientMembershipDto } from '../dtos/add.client.membership.dto';
10
12
  export declare class AdminTenantUserController {
11
13
  protected readonly adminAccessService: AdminAccessService;
12
14
  protected readonly tenantService: TenantService;
13
15
  protected readonly tenantUserOnboardedMailJob: TenantUserOnboardedMailJob;
14
16
  private readonly listFilterService;
15
- constructor(adminAccessService: AdminAccessService, tenantService: TenantService, tenantUserOnboardedMailJob: TenantUserOnboardedMailJob, listFilterService: ListFilterService);
17
+ private readonly tenantMembershipService;
18
+ constructor(adminAccessService: AdminAccessService, tenantService: TenantService, tenantUserOnboardedMailJob: TenantUserOnboardedMailJob, listFilterService: ListFilterService, tenantMembershipService: TenantMembershipService);
16
19
  clientUserDetail({ id }: CommonParamsDto): Promise<UserEntity>;
17
20
  addClientUser(dto: AddClientUserDto): Promise<UserEntity>;
18
21
  addClientUsersBulk(dto: AddBulkUsersDto): Promise<import("../types/admin.types").BulkUserResult>;
22
+ addMembership(dto: AddClientMembershipDto): Promise<import("../..").TenantUserEntity>;
23
+ deactivateMembership(id: string, tenantId: string): Promise<import("../..").TenantUserEntity>;
24
+ reactivateMembership(id: string, tenantId: string): Promise<import("../..").TenantUserEntity>;
25
+ removeMembership(id: string, tenantId: string): Promise<import("../..").DeleteResult>;
19
26
  listClientUsers(dto: ClientUserListDto): Promise<import("../..").CommonListResult>;
20
27
  removeClientUser(id: string): Promise<import("../..").DeleteResult>;
21
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"admin.tenant.user.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.user.controller.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAKjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,wDAAwD,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAE9E,qBACa,yBAAyB;IAElC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;IACzD,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa;IAC/C,SAAS,CAAC,QAAQ,CAAC,0BAA0B,EAAE,0BAA0B;IACzE,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAHf,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,0BAA0B,EAAE,0BAA0B,EACxD,iBAAiB,EAAE,iBAAiB;IASjD,gBAAgB,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAkBjD,aAAa,CAAS,GAAG,EAAE,gBAAgB;IAa3C,kBAAkB,CAAS,GAAG,EAAE,eAAe;IAW/C,eAAe,CAAS,GAAG,EAAE,iBAAiB;IAW9C,gBAAgB,CAA6B,EAAE,EAAE,MAAM;CAI9D"}
1
+ {"version":3,"file":"admin.tenant.user.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.user.controller.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAKjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,wDAAwD,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAG3E,qBACa,yBAAyB;IAElC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;IACzD,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa;IAC/C,SAAS,CAAC,QAAQ,CAAC,0BAA0B,EAAE,0BAA0B;IACzE,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBAJrB,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,0BAA0B,EAAE,0BAA0B,EACxD,iBAAiB,EAAE,iBAAiB,EACpC,uBAAuB,EAAE,uBAAuB;IAS7D,gBAAgB,CAAU,EAAE,EAAE,EAAE,EAAE,eAAe;IAkBjD,aAAa,CAAS,GAAG,EAAE,gBAAgB;IAa3C,kBAAkB,CAAS,GAAG,EAAE,eAAe;IAW/C,aAAa,CAAS,GAAG,EAAE,sBAAsB;IAWjD,oBAAoB,CACI,EAAE,EAAE,MAAM,EACJ,QAAQ,EAAE,MAAM;IAiB9C,oBAAoB,CACI,EAAE,EAAE,MAAM,EACJ,QAAQ,EAAE,MAAM;IAkB9C,gBAAgB,CACQ,EAAE,EAAE,MAAM,EACJ,QAAQ,EAAE,MAAM;IAiB9C,eAAe,CAAS,GAAG,EAAE,iBAAiB;IAW9C,gBAAgB,CAA6B,EAAE,EAAE,MAAM;CAI9D"}
@@ -29,18 +29,22 @@ const admin_access_service_1 = require("../services/admin.access.service");
29
29
  const tenant_service_1 = require("../../tenant/services/tenant.service");
30
30
  const tenant_user_onboarded_mail_job_1 = require("../../notification/jobs/tenant.user.onboarded.mail.job");
31
31
  const list_filter_service_1 = require("../../common/services/list.filter.service");
32
+ const tenant_membership_service_1 = require("../../auth/services/tenant.membership.service");
33
+ const add_client_membership_dto_1 = require("../dtos/add.client.membership.dto");
34
+ const client_membership_data_processor_1 = require("../libraries/client.membership.data.processor");
32
35
  let AdminTenantUserController = class AdminTenantUserController {
33
- constructor(adminAccessService, tenantService, tenantUserOnboardedMailJob, listFilterService) {
36
+ constructor(adminAccessService, tenantService, tenantUserOnboardedMailJob, listFilterService, tenantMembershipService) {
34
37
  this.adminAccessService = adminAccessService;
35
38
  this.tenantService = tenantService;
36
39
  this.tenantUserOnboardedMailJob = tenantUserOnboardedMailJob;
37
40
  this.listFilterService = listFilterService;
41
+ this.tenantMembershipService = tenantMembershipService;
38
42
  }
39
43
  async clientUserDetail({ id }) {
40
44
  await this.adminAccessService.validateContentReader();
41
45
  const user = await user_entity_1.UserEntity.findOne({
42
46
  where: { id, user_type: user_type_enum_1.UserType.TENANT_USER },
43
- relations: { organization: true, userRoles: { role: true } },
47
+ relations: { memberships: { tenant: true }, userRoles: { role: true } },
44
48
  });
45
49
  if (!user)
46
50
  throw new common_1.NotFoundException('No client user exists for this id');
@@ -54,6 +58,22 @@ let AdminTenantUserController = class AdminTenantUserController {
54
58
  await this.adminAccessService.validateAdmin();
55
59
  return new bulk_user_data_processor_1.BulkUserDataProcessor(this.tenantService).process(dto);
56
60
  }
61
+ async addMembership(dto) {
62
+ await this.adminAccessService.validateAdmin();
63
+ return new client_membership_data_processor_1.ClientMembershipDataProcessor(this.tenantService).process(dto);
64
+ }
65
+ async deactivateMembership(id, tenantId) {
66
+ await this.adminAccessService.validateAdmin();
67
+ return this.tenantMembershipService.setMemberActive(id, tenantId, false, undefined, false);
68
+ }
69
+ async reactivateMembership(id, tenantId) {
70
+ await this.adminAccessService.validateAdmin();
71
+ return this.tenantMembershipService.setMemberActive(id, tenantId, true, undefined, false);
72
+ }
73
+ async removeMembership(id, tenantId) {
74
+ const { user } = await this.adminAccessService.validateAdmin();
75
+ return this.tenantMembershipService.removeMember(id, tenantId, user.id, false);
76
+ }
57
77
  async listClientUsers(dto) {
58
78
  await this.adminAccessService.validateContentReader();
59
79
  return new client_user_list_processor_1.ClientUserListProcessor(this.listFilterService).process(dto);
@@ -68,7 +88,7 @@ __decorate([
68
88
  (0, common_1.Get)(':id'),
69
89
  (0, swagger_1.ApiOperation)({
70
90
  summary: 'One client (tenant-scoped) user, in full.',
71
- description: "Carries the user's tenant name and current role grants alongside everything the listing leaves out. The grants matter for editing: a save reconciles `role_ids` against them and revokes whatever the payload omits, so an edit form has to start from this list. Requires at least the global content reader role.",
91
+ description: "Carries the user's memberships (each with its tenant) and role grants (each with its `tenant_id`) alongside everything the listing leaves out. The grants matter for editing: a save reconciles one tenant's `role_ids` against them and revokes whatever the payload omits, so an edit form has to start from this list. Requires at least the global content reader role.",
72
92
  }),
73
93
  __param(0, (0, common_1.Param)()),
74
94
  __metadata("design:type", Function),
@@ -79,7 +99,7 @@ __decorate([
79
99
  (0, common_1.Post)(),
80
100
  (0, swagger_1.ApiOperation)({
81
101
  summary: 'Register a single client (tenant-scoped) user, or update one.',
82
- description: 'Send an `id` to edit that user; omit it to register a new one. `password` is required only when creating. `role_ids` replaces the current grants, so an edit must send the full set (read them from `GET :id`). `tenant_id` is not applied on an edit — a user does not move between tenants. Requires at least the global admin role.',
102
+ description: "Send an `id` to edit that user; omit it to register a new one as a member of `tenant_id`. `password` is required only when creating. `role_ids` replaces the grants held in `tenant_id`, so an edit must send that tenant's full set (read them from `GET :id`). On an edit `tenant_id` must be one of the user's memberships; others are untouched. Requires at least the global admin role.",
83
103
  }),
84
104
  __param(0, (0, common_1.Body)()),
85
105
  __metadata("design:type", Function),
@@ -97,11 +117,58 @@ __decorate([
97
117
  __metadata("design:paramtypes", [add_bulk_users_dto_1.AddBulkUsersDto]),
98
118
  __metadata("design:returntype", Promise)
99
119
  ], AdminTenantUserController.prototype, "addClientUsersBulk", null);
120
+ __decorate([
121
+ (0, common_1.Post)('memberships'),
122
+ (0, swagger_1.ApiOperation)({
123
+ summary: 'Add an existing client user to another tenant.',
124
+ description: 'Creates the membership and grants `role_ids` in that tenant. Refused when the user is already a member. Requires at least the global admin role.',
125
+ }),
126
+ __param(0, (0, common_1.Body)()),
127
+ __metadata("design:type", Function),
128
+ __metadata("design:paramtypes", [add_client_membership_dto_1.AddClientMembershipDto]),
129
+ __metadata("design:returntype", Promise)
130
+ ], AdminTenantUserController.prototype, "addMembership", null);
131
+ __decorate([
132
+ (0, common_1.Post)(':id/memberships/:tenantId/deactivate'),
133
+ (0, swagger_1.ApiOperation)({
134
+ summary: "Deactivate a client user's membership of one tenant.",
135
+ description: "Roles are kept; the user's credentials bound to the tenant are revoked and it can no longer be worked in. Reversible. Requires at least the global admin role.",
136
+ }),
137
+ __param(0, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
138
+ __param(1, (0, common_1.Param)('tenantId', common_1.ParseUUIDPipe)),
139
+ __metadata("design:type", Function),
140
+ __metadata("design:paramtypes", [String, String]),
141
+ __metadata("design:returntype", Promise)
142
+ ], AdminTenantUserController.prototype, "deactivateMembership", null);
143
+ __decorate([
144
+ (0, common_1.Post)(':id/memberships/:tenantId/reactivate'),
145
+ (0, swagger_1.ApiOperation)({
146
+ summary: "Reactivate a client user's membership of one tenant.",
147
+ description: 'Requires at least the global admin role.',
148
+ }),
149
+ __param(0, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
150
+ __param(1, (0, common_1.Param)('tenantId', common_1.ParseUUIDPipe)),
151
+ __metadata("design:type", Function),
152
+ __metadata("design:paramtypes", [String, String]),
153
+ __metadata("design:returntype", Promise)
154
+ ], AdminTenantUserController.prototype, "reactivateMembership", null);
155
+ __decorate([
156
+ (0, common_1.Delete)(':id/memberships/:tenantId'),
157
+ (0, swagger_1.ApiOperation)({
158
+ summary: 'Remove a client user from one tenant.',
159
+ description: "Ends that membership and its roles and revokes the user's credentials bound to the tenant; the account and its other memberships stay. Requires at least the global admin role.",
160
+ }),
161
+ __param(0, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
162
+ __param(1, (0, common_1.Param)('tenantId', common_1.ParseUUIDPipe)),
163
+ __metadata("design:type", Function),
164
+ __metadata("design:paramtypes", [String, String]),
165
+ __metadata("design:returntype", Promise)
166
+ ], AdminTenantUserController.prototype, "removeMembership", null);
100
167
  __decorate([
101
168
  (0, common_1.Post)('list'),
102
169
  (0, swagger_1.ApiOperation)({
103
170
  summary: 'List, search and filter client (tenant-scoped) users.',
104
- description: 'Scoped to tenant users and joined to their tenant, so rows carry `tenant_name` alongside `tenant_id`. Requires the global super admin role.',
171
+ description: 'Scoped to tenant users, one row per membership, joined to its tenant so rows carry `membership_id` and `tenant_name` alongside `tenant_id`. A user in no tenant appears once with no tenant. Requires the global super admin role.',
105
172
  }),
106
173
  __param(0, (0, common_1.Body)()),
107
174
  __metadata("design:type", Function),
@@ -112,7 +179,7 @@ __decorate([
112
179
  (0, common_1.Delete)(':id'),
113
180
  (0, swagger_1.ApiOperation)({
114
181
  summary: 'Delete a client user.',
115
- description: "Soft delete, with the user's sessions and refresh tokens revoked in the same transaction so tokens already issued stop working immediately. Requires the global admin role.",
182
+ description: "Soft delete of the user and every membership, with the user's sessions and refresh tokens revoked in the same transaction so tokens already issued stop working immediately. Requires the global admin role.",
116
183
  }),
117
184
  __param(0, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
118
185
  __metadata("design:type", Function),
@@ -124,6 +191,7 @@ exports.AdminTenantUserController = AdminTenantUserController = __decorate([
124
191
  __metadata("design:paramtypes", [admin_access_service_1.AdminAccessService,
125
192
  tenant_service_1.TenantService,
126
193
  tenant_user_onboarded_mail_job_1.TenantUserOnboardedMailJob,
127
- list_filter_service_1.ListFilterService])
194
+ list_filter_service_1.ListFilterService,
195
+ tenant_membership_service_1.TenantMembershipService])
128
196
  ], AdminTenantUserController);
129
197
  //# sourceMappingURL=admin.tenant.user.controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin.tenant.user.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.user.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin.tenant.user.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.user.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare class AddClientMembershipDto {
2
+ user_id: string;
3
+ tenant_id: string;
4
+ role_ids?: string[];
5
+ }
6
+ //# sourceMappingURL=add.client.membership.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.client.membership.dto.d.ts","sourceRoot":"","sources":["../../../src/admin/dtos/add.client.membership.dto.ts"],"names":[],"mappings":"AAIA,qBAAa,sBAAsB;IAIjC,OAAO,EAAE,MAAM,CAAC;IAKhB,SAAS,EAAE,MAAM,CAAC;IAUlB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}