@mbc-cqrs-serverless/core 1.2.7-beta.0 → 1.3.1

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 (80) hide show
  1. package/README.md +37 -0
  2. package/dist/app.module.js +2 -0
  3. package/dist/app.module.js.map +1 -1
  4. package/dist/auth/auth.module.d.ts +2 -0
  5. package/dist/auth/auth.module.js +30 -0
  6. package/dist/auth/auth.module.js.map +1 -0
  7. package/dist/auth/authz-bootstrap.service.d.ts +11 -0
  8. package/dist/auth/authz-bootstrap.service.js +47 -0
  9. package/dist/auth/authz-bootstrap.service.js.map +1 -0
  10. package/dist/auth/group-role-resolver.interface.d.ts +13 -0
  11. package/dist/auth/group-role-resolver.interface.js +3 -0
  12. package/dist/auth/group-role-resolver.interface.js.map +1 -0
  13. package/dist/auth/group-role-resolver.registry.d.ts +6 -0
  14. package/dist/auth/group-role-resolver.registry.js +26 -0
  15. package/dist/auth/group-role-resolver.registry.js.map +1 -0
  16. package/dist/auth/index.d.ts +4 -0
  17. package/dist/auth/index.js +21 -0
  18. package/dist/auth/index.js.map +1 -0
  19. package/dist/context/invoke.d.ts +1 -0
  20. package/dist/context/invoke.js.map +1 -1
  21. package/dist/context/user.d.ts +4 -0
  22. package/dist/context/user.js +50 -0
  23. package/dist/context/user.js.map +1 -1
  24. package/dist/decorators/constants.d.ts +2 -0
  25. package/dist/decorators/constants.js +3 -1
  26. package/dist/decorators/constants.js.map +1 -1
  27. package/dist/decorators/group-role-resolver.decorator.d.ts +9 -0
  28. package/dist/decorators/group-role-resolver.decorator.js +17 -0
  29. package/dist/decorators/group-role-resolver.decorator.js.map +1 -0
  30. package/dist/decorators/index.d.ts +2 -0
  31. package/dist/decorators/index.js +2 -0
  32. package/dist/decorators/index.js.map +1 -1
  33. package/dist/decorators/notification-transport.decorator.d.ts +6 -0
  34. package/dist/decorators/notification-transport.decorator.js +14 -0
  35. package/dist/decorators/notification-transport.decorator.js.map +1 -0
  36. package/dist/env.validation.d.ts +19 -0
  37. package/dist/env.validation.js +22 -1
  38. package/dist/env.validation.js.map +1 -1
  39. package/dist/guard/roles.guard.d.ts +11 -1
  40. package/dist/guard/roles.guard.js +44 -8
  41. package/dist/guard/roles.guard.js.map +1 -1
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +1 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/notification-env.validation.d.ts +8 -0
  46. package/dist/notification-env.validation.js +36 -0
  47. package/dist/notification-env.validation.js.map +1 -0
  48. package/dist/notifications/appsync-events.service.d.ts +44 -0
  49. package/dist/notifications/appsync-events.service.js +147 -0
  50. package/dist/notifications/appsync-events.service.js.map +1 -0
  51. package/dist/notifications/appsync.service.d.ts +3 -2
  52. package/dist/notifications/appsync.service.js +20 -12
  53. package/dist/notifications/appsync.service.js.map +1 -1
  54. package/dist/notifications/enums/index.d.ts +1 -0
  55. package/dist/notifications/enums/index.js +18 -0
  56. package/dist/notifications/enums/index.js.map +1 -0
  57. package/dist/notifications/enums/notification-transport.enum.d.ts +4 -0
  58. package/dist/notifications/enums/notification-transport.enum.js +9 -0
  59. package/dist/notifications/enums/notification-transport.enum.js.map +1 -0
  60. package/dist/notifications/event/notification.event.handler.d.ts +13 -5
  61. package/dist/notifications/event/notification.event.handler.js +31 -7
  62. package/dist/notifications/event/notification.event.handler.js.map +1 -1
  63. package/dist/notifications/index.d.ts +3 -0
  64. package/dist/notifications/index.js +3 -0
  65. package/dist/notifications/index.js.map +1 -1
  66. package/dist/notifications/interfaces/index.d.ts +1 -0
  67. package/dist/notifications/interfaces/index.js +18 -0
  68. package/dist/notifications/interfaces/index.js.map +1 -0
  69. package/dist/notifications/interfaces/notification-transport.interface.d.ts +7 -0
  70. package/dist/notifications/interfaces/notification-transport.interface.js +5 -0
  71. package/dist/notifications/interfaces/notification-transport.interface.js.map +1 -0
  72. package/dist/notifications/notification.module.js +12 -2
  73. package/dist/notifications/notification.module.js.map +1 -1
  74. package/dist/services/explorer.service.d.ts +5 -0
  75. package/dist/services/explorer.service.js +9 -0
  76. package/dist/services/explorer.service.js.map +1 -1
  77. package/dist/services/mocks/group-role-resolver.mock.d.ts +4 -0
  78. package/dist/services/mocks/group-role-resolver.mock.js +20 -0
  79. package/dist/services/mocks/group-role-resolver.mock.js.map +1 -0
  80. package/package.json +2 -2
package/README.md CHANGED
@@ -215,6 +215,43 @@ export class TodoDataSyncHandler implements IDataSyncHandler {
215
215
  }
216
216
  ```
217
217
 
218
+ ## Group-based roles
219
+
220
+ `RolesGuard` checks direct roles from JWT `custom:roles` first, then roles from groups in `custom:groups` (tenant-scoped). Group → role mappings are **not** stored in the JWT; implement a resolver in your app.
221
+
222
+ **JWT example:**
223
+
224
+ ```json
225
+ {
226
+ "custom:roles": "[{\"tenant\":\"tenant-a\",\"role\":\"admin\"}]",
227
+ "custom:groups": "[{\"tenant\":\"tenant-a\",\"groups\":[\"sales-team\"]}]"
228
+ }
229
+ ```
230
+
231
+ **Resolver (one per app):**
232
+
233
+ ```typescript
234
+ import {
235
+ GroupRoleResolver,
236
+ IGroupRoleResolver,
237
+ } from '@mbc-cqrs-serverless/core';
238
+
239
+ // Do not add @Injectable() — @GroupRoleResolver() already registers the provider.
240
+ @GroupRoleResolver()
241
+ export class AppGroupRoleResolver implements IGroupRoleResolver {
242
+ async resolveRoles({ tenantCode, groupIds, claims }) {
243
+ // Load roles from DynamoDB, RDS, config, etc.
244
+ return ['viewer', 'reporter'];
245
+ }
246
+ }
247
+ ```
248
+
249
+ Register the class in your NestJS module `providers`. `AuthModule` is imported automatically via core `AppModule.forRoot()` and exports `GroupRoleResolverRegistry` globally for `@Auth()` / `RolesGuard`.
250
+
251
+ ### Extending authorization
252
+
253
+ `RolesGuard` evaluates `tenantRoles` from the JWT (not `getUserRole()`). The protected `getUserRole()` method is **deprecated** and not called by the default guard. Subclasses should override `verifyRole` or `resolveGroupRoles` for custom logic.
254
+
218
255
  ## Environment Variables
219
256
 
220
257
  | Variable | Description | Default |
@@ -13,6 +13,7 @@ const core_1 = require("@nestjs/core");
13
13
  const app_controller_1 = require("./app.controller");
14
14
  const app_module_definition_1 = require("./app.module-definition");
15
15
  const app_service_1 = require("./app.service");
16
+ const auth_1 = require("./auth");
16
17
  const data_sync_module_1 = require("./command-events/data-sync.module");
17
18
  const data_store_module_1 = require("./data-store/data-store.module");
18
19
  const env_validation_1 = require("./env.validation");
@@ -64,6 +65,7 @@ exports.AppModule = AppModule;
64
65
  exports.AppModule = AppModule = __decorate([
65
66
  (0, common_1.Module)({
66
67
  imports: [
68
+ auth_1.AuthModule,
67
69
  notification_module_1.NotificationModule,
68
70
  data_store_module_1.DataStoreModule,
69
71
  data_sync_module_1.DataSyncModule,
@@ -1 +1 @@
1
- {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAsD;AACtD,2CAA6C;AAC7C,uCAAmD;AAEnD,qDAAgD;AAChD,mEAA+E;AAC/E,+CAA0C;AAC1C,wEAAkE;AAClE,sEAAgE;AAChE,qDAAoD;AACpD,qCAAsC;AACtC,6EAAwE;AACxE,uDAAkD;AAClD,kEAA6D;AAC7D,2EAAqE;AAa9D,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,+CAAuB;IACpD,MAAM,CAAC,OAAO,CAAC,OAA4B;QACzC,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,CAAA;QAC5E,MAAM,OAAO,GAAW;YACtB;gBACE,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,OAAO,CAAC,UAAU;aAC3B;SACF,CAAA;QACD,iCAAiC;QACjC,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,oBAAW;aACpB,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3C,OAAO,CAAC,IAAI,CACV,qBAAY,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;YACX,eAAe,EAAE,IAAI;YACrB,iBAAiB,EAAE;gBACjB,YAAY,EAAE,KAAK;gBACnB,UAAU,EAAE,IAAI;aACjB;YACD,QAAQ,EAAE,IAAA,kCAAiB,EAAC,OAAO,CAAC,MAAM,CAAC;SAC5C,CAAC,CACH,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAChC,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,oBAAW,CAAC,CAAA;QAC3B,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,mBAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QAE5C,OAAO;YACL,GAAG,MAAM;YACT,OAAO;SACR,CAAA;IACH,CAAC;CACF,CAAA;AA1CY,8BAAS;oBAAT,SAAS;IAXrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,wCAAkB;YAClB,mCAAe;YACf,iCAAc;YACd,yCAAkB;YAClB,0BAAW;SACZ;QACD,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,wBAAU,EAAE,kCAAe,CAAC;KACzC,CAAC;GACW,SAAS,CA0CrB"}
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAsD;AACtD,2CAA6C;AAC7C,uCAAmD;AAEnD,qDAAgD;AAChD,mEAA+E;AAC/E,+CAA0C;AAC1C,iCAAmC;AACnC,wEAAkE;AAClE,sEAAgE;AAChE,qDAAoD;AACpD,qCAAsC;AACtC,6EAAwE;AACxE,uDAAkD;AAClD,kEAA6D;AAC7D,2EAAqE;AAc9D,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,+CAAuB;IACpD,MAAM,CAAC,OAAO,CAAC,OAA4B;QACzC,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,CAAA;QAC5E,MAAM,OAAO,GAAW;YACtB;gBACE,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,OAAO,CAAC,UAAU;aAC3B;SACF,CAAA;QACD,iCAAiC;QACjC,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,oBAAW;aACpB,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3C,OAAO,CAAC,IAAI,CACV,qBAAY,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;YACX,eAAe,EAAE,IAAI;YACrB,iBAAiB,EAAE;gBACjB,YAAY,EAAE,KAAK;gBACnB,UAAU,EAAE,IAAI;aACjB;YACD,QAAQ,EAAE,IAAA,kCAAiB,EAAC,OAAO,CAAC,MAAM,CAAC;SAC5C,CAAC,CACH,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAChC,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,oBAAW,CAAC,CAAA;QAC3B,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,mBAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;QAE5C,OAAO;YACL,GAAG,MAAM;YACT,OAAO;SACR,CAAA;IACH,CAAC;CACF,CAAA;AA1CY,8BAAS;oBAAT,SAAS;IAZrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,iBAAU;YACV,wCAAkB;YAClB,mCAAe;YACf,iCAAc;YACd,yCAAkB;YAClB,0BAAW;SACZ;QACD,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,wBAAU,EAAE,kCAAe,CAAC;KACzC,CAAC;GACW,SAAS,CA0CrB"}
@@ -0,0 +1,2 @@
1
+ export declare class AuthModule {
2
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AuthModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const roles_guard_1 = require("../guard/roles.guard");
12
+ const explorer_service_1 = require("../services/explorer.service");
13
+ const authz_bootstrap_service_1 = require("./authz-bootstrap.service");
14
+ const group_role_resolver_registry_1 = require("./group-role-resolver.registry");
15
+ let AuthModule = class AuthModule {
16
+ };
17
+ exports.AuthModule = AuthModule;
18
+ exports.AuthModule = AuthModule = __decorate([
19
+ (0, common_1.Global)(),
20
+ (0, common_1.Module)({
21
+ providers: [
22
+ explorer_service_1.ExplorerService,
23
+ group_role_resolver_registry_1.GroupRoleResolverRegistry,
24
+ authz_bootstrap_service_1.AuthzBootstrapService,
25
+ roles_guard_1.RolesGuard,
26
+ ],
27
+ exports: [group_role_resolver_registry_1.GroupRoleResolverRegistry, roles_guard_1.RolesGuard, explorer_service_1.ExplorerService],
28
+ })
29
+ ], AuthModule);
30
+ //# sourceMappingURL=auth.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA+C;AAE/C,sDAAiD;AACjD,mEAA8D;AAC9D,uEAAiE;AACjE,iFAA0E;AAYnE,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IAVtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,kCAAe;YACf,wDAAyB;YACzB,+CAAqB;YACrB,wBAAU;SACX;QACD,OAAO,EAAE,CAAC,wDAAyB,EAAE,wBAAU,EAAE,kCAAe,CAAC;KAClE,CAAC;GACW,UAAU,CAAG"}
@@ -0,0 +1,11 @@
1
+ import { OnApplicationBootstrap } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { ExplorerService } from '../services/explorer.service';
4
+ import { GroupRoleResolverRegistry } from './group-role-resolver.registry';
5
+ export declare class AuthzBootstrapService implements OnApplicationBootstrap {
6
+ private readonly explorerService;
7
+ private readonly moduleRef;
8
+ private readonly registry;
9
+ constructor(explorerService: ExplorerService, moduleRef: ModuleRef, registry: GroupRoleResolverRegistry);
10
+ onApplicationBootstrap(): void;
11
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AuthzBootstrapService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@nestjs/core");
15
+ const explorer_service_1 = require("../services/explorer.service");
16
+ const group_role_resolver_registry_1 = require("./group-role-resolver.registry");
17
+ let AuthzBootstrapService = class AuthzBootstrapService {
18
+ constructor(explorerService, moduleRef, registry) {
19
+ this.explorerService = explorerService;
20
+ this.moduleRef = moduleRef;
21
+ this.registry = registry;
22
+ }
23
+ onApplicationBootstrap() {
24
+ const types = this.explorerService.exploreGroupRoleResolvers();
25
+ if (types.length > 1) {
26
+ throw new Error('Only one @GroupRoleResolver() is allowed per application');
27
+ }
28
+ if (types.length === 0) {
29
+ return;
30
+ }
31
+ const instance = this.moduleRef.get(types[0], {
32
+ strict: false,
33
+ });
34
+ if (!instance) {
35
+ throw new Error(`GroupRoleResolver ${types[0].name} was discovered but could not be resolved from DI`);
36
+ }
37
+ this.registry.set(instance);
38
+ }
39
+ };
40
+ exports.AuthzBootstrapService = AuthzBootstrapService;
41
+ exports.AuthzBootstrapService = AuthzBootstrapService = __decorate([
42
+ (0, common_1.Injectable)(),
43
+ __metadata("design:paramtypes", [explorer_service_1.ExplorerService,
44
+ core_1.ModuleRef,
45
+ group_role_resolver_registry_1.GroupRoleResolverRegistry])
46
+ ], AuthzBootstrapService);
47
+ //# sourceMappingURL=authz-bootstrap.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authz-bootstrap.service.js","sourceRoot":"","sources":["../../src/auth/authz-bootstrap.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAmE;AACnE,uCAAwC;AAExC,mEAA8D;AAE9D,iFAA0E;AAGnE,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,YACmB,eAAgC,EAChC,SAAoB,EACpB,QAAmC;QAFnC,oBAAe,GAAf,eAAe,CAAiB;QAChC,cAAS,GAAT,SAAS,CAAW;QACpB,aAAQ,GAAR,QAAQ,CAA2B;IACnD,CAAC;IAEJ,sBAAsB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,yBAAyB,EAAE,CAAA;QAE9D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAA;QACH,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAqB,KAAK,CAAC,CAAC,CAAC,EAAE;YAChE,MAAM,EAAE,KAAK;SACd,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,qBAAqB,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,mDAAmD,CACtF,CAAA;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;CACF,CAAA;AAhCY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;qCAGyB,kCAAe;QACrB,gBAAS;QACV,wDAAyB;GAJ3C,qBAAqB,CAgCjC"}
@@ -0,0 +1,13 @@
1
+ import { JwtClaims } from '../context/invoke';
2
+ export interface TenantGroupMembership {
3
+ tenant: string;
4
+ groups: string[];
5
+ }
6
+ export interface ResolveGroupRolesInput {
7
+ tenantCode: string;
8
+ groupIds: string[];
9
+ claims?: JwtClaims;
10
+ }
11
+ export interface IGroupRoleResolver {
12
+ resolveRoles(input: ResolveGroupRolesInput): Promise<string[]>;
13
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=group-role-resolver.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-role-resolver.interface.js","sourceRoot":"","sources":["../../src/auth/group-role-resolver.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { IGroupRoleResolver } from './group-role-resolver.interface';
2
+ export declare class GroupRoleResolverRegistry {
3
+ private resolver?;
4
+ set(resolver: IGroupRoleResolver): void;
5
+ get(): IGroupRoleResolver | undefined;
6
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.GroupRoleResolverRegistry = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ let GroupRoleResolverRegistry = class GroupRoleResolverRegistry {
12
+ set(resolver) {
13
+ if (this.resolver) {
14
+ throw new Error('Only one @GroupRoleResolver() is allowed per application');
15
+ }
16
+ this.resolver = resolver;
17
+ }
18
+ get() {
19
+ return this.resolver;
20
+ }
21
+ };
22
+ exports.GroupRoleResolverRegistry = GroupRoleResolverRegistry;
23
+ exports.GroupRoleResolverRegistry = GroupRoleResolverRegistry = __decorate([
24
+ (0, common_1.Injectable)()
25
+ ], GroupRoleResolverRegistry);
26
+ //# sourceMappingURL=group-role-resolver.registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-role-resolver.registry.js","sourceRoot":"","sources":["../../src/auth/group-role-resolver.registry.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA2C;AAKpC,IAAM,yBAAyB,GAA/B,MAAM,yBAAyB;IAGpC,GAAG,CAAC,QAA4B;QAC9B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAA;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;CACF,CAAA;AAfY,8DAAyB;oCAAzB,yBAAyB;IADrC,IAAA,mBAAU,GAAE;GACA,yBAAyB,CAerC"}
@@ -0,0 +1,4 @@
1
+ export * from './auth.module';
2
+ export * from './authz-bootstrap.service';
3
+ export * from './group-role-resolver.interface';
4
+ export * from './group-role-resolver.registry';
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./auth.module"), exports);
18
+ __exportStar(require("./authz-bootstrap.service"), exports);
19
+ __exportStar(require("./group-role-resolver.interface"), exports);
20
+ __exportStar(require("./group-role-resolver.registry"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA6B;AAC7B,4DAAyC;AACzC,kEAA+C;AAC/C,iEAA8C"}
@@ -15,6 +15,7 @@ export interface JwtClaims {
15
15
  name: string;
16
16
  'custom:tenant'?: string;
17
17
  'custom:roles'?: string;
18
+ 'custom:groups'?: string;
18
19
  exp: number;
19
20
  email: string;
20
21
  email_verified?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/context/invoke.ts"],"names":[],"mappings":";;AAiFA,oDAoDC;AAED,kDAsBC;AA7JD,sEAAgE;AAChE,2CAAwE;AAExE,2CAAsC;AAEtC,wCAA8C;AA4E9C,SAAgB,oBAAoB,CAAC,GAAsB;IACzD,IAAI,2BAAiB,EAAE,CAAC;QACtB,OAAO,IAAA,qCAAgB,GAAE,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAA;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAiC,CAAA;IACzD,IAAI,UAAU,GAAuB,SAAS,CAAA;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YACxD,MAAM,MAAM,GAAG,IAAA,sBAAS,EAAY,KAAK,CAAC,CAAA;YAC1C,UAAU,GAAG;gBACX,GAAG,EAAE;oBACH,MAAM;oBACN,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;iBAClC;aACF,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAqB,CAC7B,0CAA0C,CAC3C,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE;YAC7C,OAAO,EAAE,OAAO,CAAC,WAAW;YAC5B,OAAO;YACP,cAAc,EAAE;gBACd,UAAU,EAAE,OAAO,CAAC,QAAQ;gBAC5B,IAAI,EAAE;oBACJ,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,EAAE;oBAClD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;iBACrC;gBACD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;gBACtC,UAAU;aACX;SACF;QACD,OAAO,EAAE;YACP,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;SAC9B;KACF,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,GAAY;IAC9C,OAAO,CACL,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,IAAK,EAAgB,CACzE,CAAA;IACD,IAAI;IACJ,mDAAmD;IACnD,mDAAmD;IACnD,kCAAkC;IAClC,kCAAkC;IAClC,0DAA0D;IAC1D,wCAAwC;IACxC,wDAAwD;IACxD,uBAAuB;IACvB,6BAA6B;IAC7B,sBAAsB;IACtB,6BAA6B;IAC7B,qDAAqD;IACrD,uBAAuB;IACvB,+BAA+B;IAC/B,uBAAuB;IACvB,kDAAkD;IAClD,IAAI;AACN,CAAC"}
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/context/invoke.ts"],"names":[],"mappings":";;AAkFA,oDAoDC;AAED,kDAsBC;AA9JD,sEAAgE;AAChE,2CAAwE;AAExE,2CAAsC;AAEtC,wCAA8C;AA6E9C,SAAgB,oBAAoB,CAAC,GAAsB;IACzD,IAAI,2BAAiB,EAAE,CAAC;QACtB,OAAO,IAAA,qCAAgB,GAAE,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAA;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAiC,CAAA;IACzD,IAAI,UAAU,GAAuB,SAAS,CAAA;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;YACxD,MAAM,MAAM,GAAG,IAAA,sBAAS,EAAY,KAAK,CAAC,CAAA;YAC1C,UAAU,GAAG;gBACX,GAAG,EAAE;oBACH,MAAM;oBACN,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;iBAClC;aACF,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAqB,CAC7B,0CAA0C,CAC3C,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE;YAC7C,OAAO,EAAE,OAAO,CAAC,WAAW;YAC5B,OAAO;YACP,cAAc,EAAE;gBACd,UAAU,EAAE,OAAO,CAAC,QAAQ;gBAC5B,IAAI,EAAE;oBACJ,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,EAAE;oBAClD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;iBACrC;gBACD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;gBACtC,UAAU;aACX;SACF;QACD,OAAO,EAAE;YACP,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;SAC9B;KACF,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,GAAY;IAC9C,OAAO,CACL,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,IAAK,EAAgB,CACzE,CAAA;IACD,IAAI;IACJ,mDAAmD;IACnD,mDAAmD;IACnD,kCAAkC;IAClC,kCAAkC;IAClC,0DAA0D;IAC1D,wCAAwC;IACxC,wDAAwD;IACxD,uBAAuB;IACvB,6BAA6B;IAC7B,sBAAsB;IACtB,6BAA6B;IAC7B,qDAAqD;IACrD,uBAAuB;IACvB,+BAA+B;IAC/B,uBAAuB;IACvB,kDAAkD;IAClD,IAAI;AACN,CAAC"}
@@ -8,6 +8,10 @@ export declare class UserContext {
8
8
  userId: string;
9
9
  tenantRole: string;
10
10
  tenantCode: string;
11
+ /** Direct roles from custom:roles for the active tenant (excludes group-derived roles). */
12
+ tenantRoles: string[];
13
+ /** Group IDs from custom:groups for the active tenant. */
14
+ tenantGroupIds: string[];
11
15
  constructor(partial: Partial<UserContext>);
12
16
  }
13
17
  /**
@@ -10,6 +10,52 @@ class UserContext {
10
10
  }
11
11
  }
12
12
  exports.UserContext = UserContext;
13
+ function parseTenantGroups(raw, tenantCode) {
14
+ if (!tenantCode) {
15
+ return [];
16
+ }
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(raw || '[]');
20
+ }
21
+ catch {
22
+ return [];
23
+ }
24
+ if (!Array.isArray(parsed)) {
25
+ return [];
26
+ }
27
+ const memberships = parsed.map((membership) => ({
28
+ ...membership,
29
+ tenant: (membership.tenant || '').toLowerCase(),
30
+ }));
31
+ const match = memberships.find((membership) => membership.tenant === tenantCode);
32
+ const groups = match?.groups;
33
+ return Array.isArray(groups) ? groups : [];
34
+ }
35
+ function collectTenantRoles(roles, tenantCode) {
36
+ if (!tenantCode) {
37
+ return [];
38
+ }
39
+ const seen = new Set();
40
+ const result = [];
41
+ const add = (role) => {
42
+ if (!seen.has(role)) {
43
+ seen.add(role);
44
+ result.push(role);
45
+ }
46
+ };
47
+ for (const { tenant, role } of roles) {
48
+ if (tenant === tenantCode) {
49
+ add(role);
50
+ }
51
+ }
52
+ for (const { tenant, role } of roles) {
53
+ if (tenant === '') {
54
+ add(role);
55
+ }
56
+ }
57
+ return result;
58
+ }
13
59
  /**
14
60
  * Extract user context from JWT claims and request headers.
15
61
  *
@@ -33,6 +79,8 @@ function getUserContext(ctx) {
33
79
  // 2. Otherwise, use header value (security check delegated to RolesGuard)
34
80
  // Note: tenantCode is normalized to lowercase for case-insensitive matching with role.tenant
35
81
  const tenantCode = (claims['custom:tenant'] || (ctx?.event?.headers || {})[constants_1.HEADER_TENANT_CODE])?.toLowerCase();
82
+ const tenantGroupIds = parseTenantGroups(claims['custom:groups'], tenantCode);
83
+ const tenantRoles = collectTenantRoles(roles, tenantCode);
36
84
  // Find tenantRole (case-insensitive matching - both tenantCode and role.tenant are lowercase)
37
85
  let tenantRole = '';
38
86
  for (const { tenant, role } of roles) {
@@ -47,6 +95,8 @@ function getUserContext(ctx) {
47
95
  userId,
48
96
  tenantRole,
49
97
  tenantCode,
98
+ tenantRoles,
99
+ tenantGroupIds,
50
100
  };
51
101
  }
52
102
  //# sourceMappingURL=user.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/context/user.ts"],"names":[],"mappings":";;;AA8BA,wCAqCC;AAjED,4CAAiD;AACjD,qCAA6E;AAO7E,MAAa,WAAW;IAKtB,YAAY,OAA6B;QACvC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC9B,CAAC;CACF;AARD,kCAQC;AAED;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAAC,GAA+B;IAC5D,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;QACxB,GAAG,GAAG,IAAA,6BAAoB,EAAC,GAAG,CAAC,CAAA;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,4BAAmB,EAAC,GAAG,CAAC,CAAA;IAEvC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;IAEzB,cAAc;IACd,MAAM,KAAK,GACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,IAAI,CAC1C,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;IAEzE,wBAAwB;IACxB,oDAAoD;IACpD,0EAA0E;IAC1E,6FAA6F;IAC7F,MAAM,UAAU,GAAG,CACjB,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,8BAAkB,CAAC,CAC3E,EAAE,WAAW,EAAE,CAAA;IAEhB,8FAA8F;IAC9F,IAAI,UAAU,GAAG,EAAE,CAAA;IACnB,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QACrC,IAAI,MAAM,KAAK,EAAE,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC3C,UAAU,GAAG,IAAI,CAAA;YACjB,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;gBAClB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM;QACN,UAAU;QACV,UAAU;KACX,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/context/user.ts"],"names":[],"mappings":"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"}
@@ -3,3 +3,5 @@ export declare const EVENT_HANDLER_METADATA = "__eventHandler__";
3
3
  export declare const EVENT_FACTORY_METADATA = "__eventFactory__";
4
4
  export declare const DATA_SYNC_HANDLER_METADATA = "__dataSyncHandler__";
5
5
  export declare const ROLE_METADATA = "__allowedRoles__";
6
+ export declare const NOTIFICATION_TRANSPORT_METADATA = "__notificationTransport__";
7
+ export declare const GROUP_ROLE_RESOLVER_METADATA = "__groupRoleResolver__";
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ROLE_METADATA = exports.DATA_SYNC_HANDLER_METADATA = exports.EVENT_FACTORY_METADATA = exports.EVENT_HANDLER_METADATA = exports.EVENT_METADATA = void 0;
3
+ exports.GROUP_ROLE_RESOLVER_METADATA = exports.NOTIFICATION_TRANSPORT_METADATA = exports.ROLE_METADATA = exports.DATA_SYNC_HANDLER_METADATA = exports.EVENT_FACTORY_METADATA = exports.EVENT_HANDLER_METADATA = exports.EVENT_METADATA = void 0;
4
4
  exports.EVENT_METADATA = '__event__';
5
5
  exports.EVENT_HANDLER_METADATA = '__eventHandler__';
6
6
  exports.EVENT_FACTORY_METADATA = '__eventFactory__';
7
7
  exports.DATA_SYNC_HANDLER_METADATA = '__dataSyncHandler__';
8
8
  exports.ROLE_METADATA = '__allowedRoles__';
9
+ exports.NOTIFICATION_TRANSPORT_METADATA = '__notificationTransport__';
10
+ exports.GROUP_ROLE_RESOLVER_METADATA = '__groupRoleResolver__';
9
11
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/decorators/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,WAAW,CAAA;AAC5B,QAAA,sBAAsB,GAAG,kBAAkB,CAAA;AAC3C,QAAA,sBAAsB,GAAG,kBAAkB,CAAA;AAC3C,QAAA,0BAA0B,GAAG,qBAAqB,CAAA;AAClD,QAAA,aAAa,GAAG,kBAAkB,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/decorators/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,WAAW,CAAA;AAC5B,QAAA,sBAAsB,GAAG,kBAAkB,CAAA;AAC3C,QAAA,sBAAsB,GAAG,kBAAkB,CAAA;AAC3C,QAAA,0BAA0B,GAAG,qBAAqB,CAAA;AAClD,QAAA,aAAa,GAAG,kBAAkB,CAAA;AAClC,QAAA,+BAA+B,GAAG,2BAA2B,CAAA;AAC7D,QAAA,4BAA4B,GAAG,uBAAuB,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Marks a class as the application's `IGroupRoleResolver` (exactly one per app).
3
+ * Discovered at bootstrap and registered in `GroupRoleResolverRegistry`.
4
+ *
5
+ * Applies `@Injectable()` with default (singleton) scope. Do **not** add `@Injectable()`
6
+ * on the same class — a second decorator can override scope (e.g. `REQUEST`) and break
7
+ * bootstrap, which resolves one instance at application startup.
8
+ */
9
+ export declare function GroupRoleResolver(): ClassDecorator;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupRoleResolver = GroupRoleResolver;
4
+ const common_1 = require("@nestjs/common");
5
+ const constants_1 = require("./constants");
6
+ /**
7
+ * Marks a class as the application's `IGroupRoleResolver` (exactly one per app).
8
+ * Discovered at bootstrap and registered in `GroupRoleResolverRegistry`.
9
+ *
10
+ * Applies `@Injectable()` with default (singleton) scope. Do **not** add `@Injectable()`
11
+ * on the same class — a second decorator can override scope (e.g. `REQUEST`) and break
12
+ * bootstrap, which resolves one instance at application startup.
13
+ */
14
+ function GroupRoleResolver() {
15
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(constants_1.GROUP_ROLE_RESOLVER_METADATA, true), (0, common_1.Injectable)());
16
+ }
17
+ //# sourceMappingURL=group-role-resolver.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-role-resolver.decorator.js","sourceRoot":"","sources":["../../src/decorators/group-role-resolver.decorator.ts"],"names":[],"mappings":";;AAYA,8CAKC;AAjBD,2CAAyE;AAEzE,2CAA0D;AAE1D;;;;;;;GAOG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,wCAA4B,EAAE,IAAI,CAAC,EAC/C,IAAA,mBAAU,GAAE,CACK,CAAA;AACrB,CAAC"}
@@ -4,5 +4,7 @@ export * from './context.decorator';
4
4
  export * from './data-sync-handler.decorator';
5
5
  export * from './event-factory.decorator';
6
6
  export * from './event-handler.decorator';
7
+ export * from './group-role-resolver.decorator';
8
+ export * from './notification-transport.decorator';
7
9
  export * from './roles.decorator';
8
10
  export * from './swagger-response.decorator';
@@ -20,6 +20,8 @@ __exportStar(require("./context.decorator"), exports);
20
20
  __exportStar(require("./data-sync-handler.decorator"), exports);
21
21
  __exportStar(require("./event-factory.decorator"), exports);
22
22
  __exportStar(require("./event-handler.decorator"), exports);
23
+ __exportStar(require("./group-role-resolver.decorator"), exports);
24
+ __exportStar(require("./notification-transport.decorator"), exports);
23
25
  __exportStar(require("./roles.decorator"), exports);
24
26
  __exportStar(require("./swagger-response.decorator"), exports);
25
27
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAgC;AAChC,8CAA2B;AAC3B,sDAAmC;AACnC,gEAA6C;AAC7C,4DAAyC;AACzC,4DAAyC;AACzC,oDAAiC;AACjC,+DAA4C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAgC;AAChC,8CAA2B;AAC3B,sDAAmC;AACnC,gEAA6C;AAC7C,4DAAyC;AACzC,4DAAyC;AACzC,kEAA+C;AAC/C,qEAAkD;AAClD,oDAAiC;AACjC,+DAA4C"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Decorator to register a class as a Notification Transport.
3
+ * Automatically marks the class as an @Injectable() provider.
4
+ * @param name The unique identifier for this transport (e.g., 'pusher', 'appsync-event')
5
+ */
6
+ export declare function NotificationTransport(name: string): ClassDecorator;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotificationTransport = NotificationTransport;
4
+ const common_1 = require("@nestjs/common");
5
+ const constants_1 = require("./constants");
6
+ /**
7
+ * Decorator to register a class as a Notification Transport.
8
+ * Automatically marks the class as an @Injectable() provider.
9
+ * @param name The unique identifier for this transport (e.g., 'pusher', 'appsync-event')
10
+ */
11
+ function NotificationTransport(name) {
12
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(constants_1.NOTIFICATION_TRANSPORT_METADATA, name), (0, common_1.Injectable)());
13
+ }
14
+ //# sourceMappingURL=notification-transport.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-transport.decorator.js","sourceRoot":"","sources":["../../src/decorators/notification-transport.decorator.ts"],"names":[],"mappings":";;AASA,sDAKC;AAdD,2CAAyE;AAEzE,2CAA6D;AAE7D;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,IAAY;IAChD,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,2CAA+B,EAAE,IAAI,CAAC,EAClD,IAAA,mBAAU,GAAE,CACK,CAAA;AACrB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { ClassConstructor } from 'class-transformer';
2
+ export { BUILTIN_NOTIFICATION_TRANSPORT_ENV, parseNotificationTransports, validateBuiltinNotificationTransportEnv, } from './notification-env.validation';
2
3
  export declare enum Environment {
3
4
  Local = "local",
4
5
  Development = "dev",
@@ -22,7 +23,25 @@ export declare class EnvironmentVariables {
22
23
  SFN_COMMAND_ARN: string;
23
24
  SNS_ENDPOINT: string;
24
25
  SNS_REGION: string;
26
+ /**
27
+ * Comma-separated list of active notification transport names.
28
+ * Supported built-in values: 'appsync-graphql' | 'appsync-event'
29
+ * Defaults to 'appsync-graphql' when not set.
30
+ *
31
+ * Examples:
32
+ * NOTIFICATION_TRANSPORTS=appsync-graphql
33
+ * NOTIFICATION_TRANSPORTS=appsync-event
34
+ * NOTIFICATION_TRANSPORTS=appsync-graphql,appsync-event
35
+ */
36
+ NOTIFICATION_TRANSPORTS: string;
25
37
  APPSYNC_ENDPOINT: string;
38
+ APPSYNC_EVENTS_ENDPOINT: string;
39
+ /**
40
+ * Channel namespace name — must match the pre-created namespace in the
41
+ * AppSync Event API (segment 1 of every channel path).
42
+ * Defaults to 'default'.
43
+ */
44
+ APPSYNC_EVENTS_NAMESPACE: string;
26
45
  SES_ENDPOINT: string;
27
46
  SES_REGION: string;
28
47
  SES_FROM_EMAIL: string;
@@ -9,10 +9,15 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.EnvironmentVariables = exports.Environment = void 0;
12
+ exports.EnvironmentVariables = exports.Environment = exports.validateBuiltinNotificationTransportEnv = exports.parseNotificationTransports = exports.BUILTIN_NOTIFICATION_TRANSPORT_ENV = void 0;
13
13
  exports.getValidateConfig = getValidateConfig;
14
14
  const class_transformer_1 = require("class-transformer");
15
15
  const class_validator_1 = require("class-validator");
16
+ const notification_env_validation_1 = require("./notification-env.validation");
17
+ var notification_env_validation_2 = require("./notification-env.validation");
18
+ Object.defineProperty(exports, "BUILTIN_NOTIFICATION_TRANSPORT_ENV", { enumerable: true, get: function () { return notification_env_validation_2.BUILTIN_NOTIFICATION_TRANSPORT_ENV; } });
19
+ Object.defineProperty(exports, "parseNotificationTransports", { enumerable: true, get: function () { return notification_env_validation_2.parseNotificationTransports; } });
20
+ Object.defineProperty(exports, "validateBuiltinNotificationTransportEnv", { enumerable: true, get: function () { return notification_env_validation_2.validateBuiltinNotificationTransportEnv; } });
16
21
  var Environment;
17
22
  (function (Environment) {
18
23
  Environment["Local"] = "local";
@@ -96,11 +101,26 @@ __decorate([
96
101
  (0, class_validator_1.IsOptional)(),
97
102
  __metadata("design:type", String)
98
103
  ], EnvironmentVariables.prototype, "SNS_REGION", void 0);
104
+ __decorate([
105
+ (0, class_validator_1.IsString)(),
106
+ (0, class_validator_1.IsOptional)(),
107
+ __metadata("design:type", String)
108
+ ], EnvironmentVariables.prototype, "NOTIFICATION_TRANSPORTS", void 0);
99
109
  __decorate([
100
110
  (0, class_validator_1.IsString)(),
101
111
  (0, class_validator_1.IsOptional)(),
102
112
  __metadata("design:type", String)
103
113
  ], EnvironmentVariables.prototype, "APPSYNC_ENDPOINT", void 0);
114
+ __decorate([
115
+ (0, class_validator_1.IsString)(),
116
+ (0, class_validator_1.IsOptional)(),
117
+ __metadata("design:type", String)
118
+ ], EnvironmentVariables.prototype, "APPSYNC_EVENTS_ENDPOINT", void 0);
119
+ __decorate([
120
+ (0, class_validator_1.IsString)(),
121
+ (0, class_validator_1.IsOptional)(),
122
+ __metadata("design:type", String)
123
+ ], EnvironmentVariables.prototype, "APPSYNC_EVENTS_NAMESPACE", void 0);
104
124
  __decorate([
105
125
  (0, class_validator_1.IsString)(),
106
126
  (0, class_validator_1.IsOptional)(),
@@ -136,6 +156,7 @@ function getValidateConfig(cls) {
136
156
  if (errors.length > 0) {
137
157
  throw new Error(errors.toString());
138
158
  }
159
+ (0, notification_env_validation_1.validateBuiltinNotificationTransportEnv)(validatedConfig);
139
160
  return validatedConfig;
140
161
  };
141
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"env.validation.js","sourceRoot":"","sources":["../src/env.validation.ts"],"names":[],"mappings":";;;;;;;;;;;;AAyFA,8CAoBC;AA7GD,yDAAqE;AACrE,qDAQwB;AAExB,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,8BAAe,CAAA;AACjB,CAAC,EALW,WAAW,2BAAX,WAAW,QAKtB;AAED,MAAa,oBAAoB;CAqEhC;AArED,oDAqEC;AAnEC;IADC,IAAA,wBAAM,EAAC,WAAW,CAAC;;sDACC;AAErB;IADC,IAAA,0BAAQ,GAAE;;sDACK;AAIhB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;sDACG;AAGhB;IADC,IAAA,2BAAS,GAAE;;mEACkB;AAG9B;IADC,IAAA,0BAAQ,GAAE;;uDACM;AAIjB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;+DACY;AAGzB;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;6DACY;AAEvB;IADC,IAAA,4BAAU,GAAE;;kEACe;AAG5B;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;yDACM;AAGnB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;uDACI;AAEjB;IADC,IAAA,0BAAQ,GAAE;;4DACW;AAItB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;0DACO;AAGpB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;wDACK;AAElB;IADC,IAAA,0BAAQ,GAAE;;6DACY;AAIvB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;0DACO;AAGpB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;wDACK;AAIlB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;8DACW;AAIxB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;0DACO;AAGpB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;wDACK;AAElB;IADC,IAAA,0BAAQ,GAAE;;4DACW;AAItB;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;qEACkB;AAI/B;IAFC,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;qEACkB;AAGjC,SAAgB,iBAAiB,CAC/B,GAAyB;IAEzB,OAAO,SAAS,QAAQ,CAAC,MAA+B;QACtD,MAAM,eAAe,GAAG,IAAA,mCAAe,EACrC,GAAG,IAAI,oBAAoB,EAC3B,MAAM,EACN;YACE,wBAAwB,EAAE,IAAI;SAC/B,CACF,CAAA;QACD,MAAM,MAAM,GAAG,IAAA,8BAAY,EAAC,eAAe,EAAE;YAC3C,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAA;QAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACpC,CAAC;QACD,OAAO,eAAe,CAAA;IACxB,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"env.validation.js","sourceRoot":"","sources":["../src/env.validation.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  import { CanActivate, ExecutionContext, Logger } from '@nestjs/common';
2
2
  import { Reflector } from '@nestjs/core';
3
+ import { GroupRoleResolverRegistry } from '../auth/group-role-resolver.registry';
3
4
  import { UserContext } from '../context';
4
5
  export declare class RolesGuard implements CanActivate {
5
6
  protected reflector: Reflector;
7
+ protected registry?: GroupRoleResolverRegistry;
6
8
  protected readonly logger: Logger;
7
- constructor(reflector: Reflector);
9
+ constructor(reflector: Reflector, registry?: GroupRoleResolverRegistry);
8
10
  canActivate(context: ExecutionContext): Promise<boolean>;
9
11
  /**
10
12
  * Verify tenant access.
@@ -59,6 +61,14 @@ export declare class RolesGuard implements CanActivate {
59
61
  * This is a helper method that can be used by subclasses.
60
62
  */
61
63
  protected getAuthorizerClaims(context: ExecutionContext): import("../context").JwtClaims;
64
+ protected hasAnyRole(requiredRoles: string[], userRoles: string[]): boolean;
65
+ protected resolveGroupRoles(context: ExecutionContext, groupIds: string[]): Promise<string[]>;
62
66
  protected verifyRole(context: ExecutionContext): Promise<boolean>;
67
+ /**
68
+ * Returns the primary direct role string from JWT context.
69
+ *
70
+ * @deprecated Not invoked by `verifyRole`. For custom authorization, override
71
+ * `verifyRole`, `resolveGroupRoles`, or `canOverrideTenant` instead.
72
+ */
63
73
  protected getUserRole(context: ExecutionContext): Promise<string>;
64
74
  }