@rhino-dev/rhino-nestjs 4.0.0 → 4.2.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 (63) hide show
  1. package/README.md +52 -1
  2. package/dist/blueprint/blueprint-runner.js +32 -1
  3. package/dist/blueprint/blueprint-runner.js.map +1 -1
  4. package/dist/blueprint/blueprint-sorter.d.ts +54 -0
  5. package/dist/blueprint/blueprint-sorter.js +107 -0
  6. package/dist/blueprint/blueprint-sorter.js.map +1 -0
  7. package/dist/controllers/auth.controller.d.ts +34 -5
  8. package/dist/controllers/auth.controller.js +132 -12
  9. package/dist/controllers/auth.controller.js.map +1 -1
  10. package/dist/controllers/invitation.controller.d.ts +41 -2
  11. package/dist/controllers/invitation.controller.js +97 -12
  12. package/dist/controllers/invitation.controller.js.map +1 -1
  13. package/dist/errors/rhino-exception.d.ts +12 -1
  14. package/dist/errors/rhino-exception.js +19 -1
  15. package/dist/errors/rhino-exception.js.map +1 -1
  16. package/dist/guards/group-membership.guard.d.ts +25 -0
  17. package/dist/guards/group-membership.guard.js +70 -0
  18. package/dist/guards/group-membership.guard.js.map +1 -0
  19. package/dist/guards/jwt-auth.guard.js +23 -4
  20. package/dist/guards/jwt-auth.guard.js.map +1 -1
  21. package/dist/index.d.ts +7 -1
  22. package/dist/index.js +17 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/interfaces/rhino-config.interface.d.ts +71 -0
  25. package/dist/middleware/domain-route-resolver.d.ts +54 -0
  26. package/dist/middleware/domain-route-resolver.js +145 -0
  27. package/dist/middleware/domain-route-resolver.js.map +1 -0
  28. package/dist/middleware/route-group.middleware.d.ts +48 -4
  29. package/dist/middleware/route-group.middleware.js +274 -13
  30. package/dist/middleware/route-group.middleware.js.map +1 -1
  31. package/dist/rhino.config.d.ts +26 -1
  32. package/dist/rhino.config.js +56 -1
  33. package/dist/rhino.config.js.map +1 -1
  34. package/dist/rhino.module.d.ts +7 -0
  35. package/dist/rhino.module.js +23 -1
  36. package/dist/rhino.module.js.map +1 -1
  37. package/dist/services/auth-hooks.service.d.ts +27 -0
  38. package/dist/services/auth-hooks.service.js +85 -0
  39. package/dist/services/auth-hooks.service.js.map +1 -0
  40. package/dist/services/auth.service.d.ts +19 -0
  41. package/dist/services/auth.service.js +80 -5
  42. package/dist/services/auth.service.js.map +1 -1
  43. package/dist/services/invitation.service.d.ts +6 -0
  44. package/dist/services/invitation.service.js +45 -3
  45. package/dist/services/invitation.service.js.map +1 -1
  46. package/dist/services/membership.service.d.ts +56 -0
  47. package/dist/services/membership.service.js +113 -0
  48. package/dist/services/membership.service.js.map +1 -0
  49. package/dist/services/organization.service.js +8 -1
  50. package/dist/services/organization.service.js.map +1 -1
  51. package/dist/services/route-registration.service.d.ts +1 -0
  52. package/dist/services/route-registration.service.js +2 -0
  53. package/dist/services/route-registration.service.js.map +1 -1
  54. package/dist/tsconfig.build.tsbuildinfo +1 -1
  55. package/dist/utils/domain-pattern.d.ts +36 -0
  56. package/dist/utils/domain-pattern.js +77 -0
  57. package/dist/utils/domain-pattern.js.map +1 -0
  58. package/dist/utils/permission-matcher.js +8 -0
  59. package/dist/utils/permission-matcher.js.map +1 -1
  60. package/dist/utils/route-group-validator.d.ts +14 -0
  61. package/dist/utils/route-group-validator.js +124 -0
  62. package/dist/utils/route-group-validator.js.map +1 -0
  63. package/package.json +1 -1
@@ -1,15 +1,52 @@
1
1
  import { InvitationService } from '../services/invitation.service';
2
+ import { RhinoConfigService } from '../rhino.config';
3
+ import { MembershipService } from '../services/membership.service';
2
4
  export declare class InvitationController {
3
5
  private readonly invitations;
4
- constructor(invitations: InvitationService);
5
- private assertInvitationPermission;
6
+ private readonly config;
7
+ private readonly membership;
8
+ constructor(invitations: InvitationService, config: RhinoConfigService, membership: MembershipService);
9
+ /**
10
+ * Authorize an invitation action.
11
+ *
12
+ * - Enforcement OFF (legacy): byte-for-byte the original check —
13
+ * `userHasPermission(user, invitations.{action}, org)`; 403 on failure.
14
+ * - Enforcement ON: a COARSE membership gate runs FIRST — the inviter must be
15
+ * a member of the target group (design §8 — "inviter must be a member of the
16
+ * group"). A non-member is a **403** for parity with Laravel/Rails
17
+ * (Decision 9.C), NOT a 400. A NULL/absent membership row is a wildcard and
18
+ * admits the inviter. The fine-grained permission check then runs (also 403
19
+ * on failure), resolving via the established heuristic (tenant groups → the
20
+ * org's user_roles permissions, non-tenant groups → top-level
21
+ * user.permissions). The two checks run in sequence and are never merged.
22
+ */
23
+ private assertCanInvite;
24
+ /** The `public` group (reserved name or any `skipAuth` group) has no auth, so it cannot be invited into. */
25
+ private isPublicGroup;
26
+ /**
27
+ * Reject a `routeGroup` that is neither a configured route group nor the
28
+ * reserved `public` name. A client could otherwise forge an arbitrary group
29
+ * value (overriding the resolved group) and create a dormant, unaudited grant
30
+ * that activates the day that group name is wired up. This guard runs
31
+ * regardless of enforcement. NULL (wildcard) is always allowed.
32
+ */
33
+ private assertKnownGroup;
6
34
  index(req: any, status?: string): Promise<{
7
35
  data: any;
8
36
  }>;
9
37
  store(req: any, body: {
10
38
  email: string;
11
39
  roleId: number;
40
+ routeGroup?: string | null;
12
41
  }): Promise<any>;
42
+ /**
43
+ * Whether this invite requires an organization context. We default to YES to
44
+ * preserve legacy behavior (store always required an org). An invite is only
45
+ * treated as non-tenant — and thus org-optional — when membership enforcement
46
+ * is on AND the resolved group is positively a non-tenant group. This keeps
47
+ * every flag-off code path byte-for-byte unchanged.
48
+ */
49
+ private isTenantInvite;
13
50
  resend(req: any, id: string): Promise<any>;
14
51
  cancel(req: any, id: string): Promise<any>;
15
52
  accept(body: {
@@ -19,10 +56,12 @@ export declare class InvitationController {
19
56
  organization: any;
20
57
  role: any;
21
58
  email: any;
59
+ routeGroup: any;
22
60
  accepted?: undefined;
23
61
  } | {
24
62
  accepted: boolean;
25
63
  organization: any;
64
+ routeGroup: any;
26
65
  requiresRegistration?: undefined;
27
66
  role?: undefined;
28
67
  email?: undefined;
@@ -15,46 +15,129 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.InvitationController = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const invitation_service_1 = require("../services/invitation.service");
18
+ const rhino_config_1 = require("../rhino.config");
19
+ const membership_service_1 = require("../services/membership.service");
18
20
  const permission_matcher_1 = require("../utils/permission-matcher");
21
+ const rhino_exception_1 = require("../errors/rhino-exception");
19
22
  let InvitationController = class InvitationController {
20
23
  invitations;
21
- constructor(invitations) {
24
+ config;
25
+ membership;
26
+ constructor(invitations, config, membership) {
22
27
  this.invitations = invitations;
28
+ this.config = config;
29
+ this.membership = membership;
23
30
  }
24
- assertInvitationPermission(req, action) {
31
+ /**
32
+ * Authorize an invitation action.
33
+ *
34
+ * - Enforcement OFF (legacy): byte-for-byte the original check —
35
+ * `userHasPermission(user, invitations.{action}, org)`; 403 on failure.
36
+ * - Enforcement ON: a COARSE membership gate runs FIRST — the inviter must be
37
+ * a member of the target group (design §8 — "inviter must be a member of the
38
+ * group"). A non-member is a **403** for parity with Laravel/Rails
39
+ * (Decision 9.C), NOT a 400. A NULL/absent membership row is a wildcard and
40
+ * admits the inviter. The fine-grained permission check then runs (also 403
41
+ * on failure), resolving via the established heuristic (tenant groups → the
42
+ * org's user_roles permissions, non-tenant groups → top-level
43
+ * user.permissions). The two checks run in sequence and are never merged.
44
+ */
45
+ assertCanInvite(req, routeGroup, action) {
46
+ if (this.membership.enabled()) {
47
+ const isTenant = this.config.isTenantGroup(routeGroup ?? undefined);
48
+ if (!this.membership.isMember(req.user, routeGroup ?? null, req.organization, isTenant)) {
49
+ throw rhino_exception_1.RhinoException.membershipDenied(`Inviter is not a member of group '${routeGroup ?? '(any)'}'`);
50
+ }
51
+ }
25
52
  if (!(0, permission_matcher_1.userHasPermission)(req.user, `invitations.${action}`, req.organization)) {
26
- const err = new Error('Forbidden');
27
- err.status = 403;
28
- throw err;
53
+ throw rhino_exception_1.RhinoException.forbidden();
29
54
  }
30
55
  }
56
+ /** The `public` group (reserved name or any `skipAuth` group) has no auth, so it cannot be invited into. */
57
+ isPublicGroup(routeGroup) {
58
+ if (routeGroup == null)
59
+ return false;
60
+ if (routeGroup === 'public')
61
+ return true;
62
+ return this.config.routeGroups()?.[routeGroup]?.skipAuth === true;
63
+ }
64
+ /**
65
+ * Reject a `routeGroup` that is neither a configured route group nor the
66
+ * reserved `public` name. A client could otherwise forge an arbitrary group
67
+ * value (overriding the resolved group) and create a dormant, unaudited grant
68
+ * that activates the day that group name is wired up. This guard runs
69
+ * regardless of enforcement. NULL (wildcard) is always allowed.
70
+ */
71
+ assertKnownGroup(routeGroup) {
72
+ if (routeGroup == null)
73
+ return; // NULL wildcard
74
+ if (routeGroup === 'public')
75
+ return; // reserved; rejected later by isPublicGroup
76
+ if (this.config.routeGroups()?.[routeGroup])
77
+ return; // a configured group
78
+ throw rhino_exception_1.RhinoException.validationFailed({
79
+ routeGroup: [`Unknown route group '${routeGroup}'`],
80
+ });
81
+ }
31
82
  async index(req, status) {
32
- this.assertInvitationPermission(req, 'index');
83
+ this.assertCanInvite(req, req.__routeGroup ?? null, 'index');
33
84
  if (!req.organization)
34
85
  throw new common_1.BadRequestException('Organization context required');
35
86
  const items = await this.invitations.list(req.organization.id, status);
36
87
  return { data: items };
37
88
  }
38
89
  async store(req, body) {
39
- this.assertInvitationPermission(req, 'store');
40
- if (!req.organization)
41
- throw new common_1.BadRequestException('Organization context required');
42
90
  if (!body?.email || !body?.roleId) {
43
91
  throw new common_1.BadRequestException('email and roleId required');
44
92
  }
93
+ // The invite's group: an explicit body value, else the request's resolved
94
+ // group (set by RouteGroupMiddleware), else NULL (wildcard).
95
+ const routeGroup = body.routeGroup !== undefined
96
+ ? body.routeGroup
97
+ : req.__routeGroup ?? null;
98
+ // Reject a forged/unknown route group (422) before any other processing so
99
+ // a client can never seed a dormant grant for an unconfigured group.
100
+ this.assertKnownGroup(routeGroup);
101
+ // The public group has no auth and cannot be invited into.
102
+ if (this.isPublicGroup(routeGroup)) {
103
+ throw new common_1.BadRequestException('Cannot invite into the public group');
104
+ }
105
+ // Tenant-group invites still require an org context; non-tenant invites
106
+ // (an explicit NULL/non-tenant group) may proceed without one. This is
107
+ // checked BEFORE authorization so the legacy "org required" 400 is returned
108
+ // for org-less tenant invites rather than a permission 403.
109
+ if (this.isTenantInvite(routeGroup) && !req.organization) {
110
+ throw new common_1.BadRequestException('Organization context required');
111
+ }
112
+ this.assertCanInvite(req, routeGroup, 'store');
45
113
  return this.invitations.create({
46
114
  email: body.email,
47
115
  roleId: body.roleId,
48
116
  organization: req.organization,
49
117
  invitedBy: req.user,
118
+ routeGroup,
50
119
  });
51
120
  }
121
+ /**
122
+ * Whether this invite requires an organization context. We default to YES to
123
+ * preserve legacy behavior (store always required an org). An invite is only
124
+ * treated as non-tenant — and thus org-optional — when membership enforcement
125
+ * is on AND the resolved group is positively a non-tenant group. This keeps
126
+ * every flag-off code path byte-for-byte unchanged.
127
+ */
128
+ isTenantInvite(routeGroup) {
129
+ if (!this.config.enforceGroupMembership())
130
+ return true;
131
+ if (routeGroup == null)
132
+ return true;
133
+ return this.config.isTenantGroup(routeGroup);
134
+ }
52
135
  async resend(req, id) {
53
- this.assertInvitationPermission(req, 'resend');
136
+ this.assertCanInvite(req, req.__routeGroup ?? null, 'resend');
54
137
  return this.invitations.resend(parseInt(id, 10));
55
138
  }
56
139
  async cancel(req, id) {
57
- this.assertInvitationPermission(req, 'cancel');
140
+ this.assertCanInvite(req, req.__routeGroup ?? null, 'cancel');
58
141
  return this.invitations.cancel(parseInt(id, 10));
59
142
  }
60
143
  async accept(body, req) {
@@ -106,6 +189,8 @@ __decorate([
106
189
  ], InvitationController.prototype, "accept", null);
107
190
  exports.InvitationController = InvitationController = __decorate([
108
191
  (0, common_1.Controller)('invitations'),
109
- __metadata("design:paramtypes", [invitation_service_1.InvitationService])
192
+ __metadata("design:paramtypes", [invitation_service_1.InvitationService,
193
+ rhino_config_1.RhinoConfigService,
194
+ membership_service_1.MembershipService])
110
195
  ], InvitationController);
111
196
  //# sourceMappingURL=invitation.controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"invitation.controller.js","sourceRoot":"","sources":["../../src/controllers/invitation.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"invitation.controller.js","sourceRoot":"","sources":["../../src/controllers/invitation.controller.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { HttpException } from '@nestjs/common';
2
- export type RhinoErrorCode = 'VALIDATION_FAILED' | 'FORBIDDEN_FIELDS' | 'CROSS_TENANT' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'ACTION_DISABLED' | 'UNKNOWN_RESOURCE' | 'INVITATION_EXPIRED' | 'INVITATION_USED' | 'INVITATION_INVALID_ROLE' | 'NESTED_OPERATION_FAILED' | 'INCLUDE_NOT_AUTHORIZED';
2
+ export type RhinoErrorCode = 'VALIDATION_FAILED' | 'FORBIDDEN_FIELDS' | 'CROSS_TENANT' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'NOT_FOUND' | 'ACTION_DISABLED' | 'UNKNOWN_RESOURCE' | 'INVITATION_EXPIRED' | 'INVITATION_USED' | 'INVITATION_INVALID_ROLE' | 'NESTED_OPERATION_FAILED' | 'INCLUDE_NOT_AUTHORIZED' | 'AUTH_REJECTED' | 'MEMBERSHIP_DENIED';
3
3
  export interface RhinoErrorBody {
4
4
  code: RhinoErrorCode;
5
5
  message: string;
@@ -21,4 +21,15 @@ export declare class RhinoException extends HttpException {
21
21
  static actionDisabled(action: string): RhinoException;
22
22
  static unknownResource(slug: string): RhinoException;
23
23
  static includeNotAuthorized(slug: string): RhinoException;
24
+ static authRejected(message?: string, status?: number): RhinoException;
25
+ static membershipDenied(message?: string): RhinoException;
26
+ }
27
+ /**
28
+ * Thrown by a lifecycle hook to reject an otherwise-successful auth action.
29
+ * The controller catches it: for token-issuing actions (login/register) the
30
+ * just-issued token is revoked; the configured `status` (default 403) is then
31
+ * returned to the client. A hook may also throw any other error.
32
+ */
33
+ export declare class RhinoAuthRejected extends RhinoException {
34
+ constructor(message?: string, status?: number);
24
35
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RhinoException = void 0;
3
+ exports.RhinoAuthRejected = exports.RhinoException = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  /**
6
6
  * Single exception shape surfaced by the library. Frontends can rely on the
@@ -42,6 +42,24 @@ class RhinoException extends common_1.HttpException {
42
42
  static includeNotAuthorized(slug) {
43
43
  return new RhinoException('INCLUDE_NOT_AUTHORIZED', `Include not authorized: ${slug}`, 403, { slug });
44
44
  }
45
+ static authRejected(message = 'Authentication rejected', status = 403) {
46
+ return new RhinoException('AUTH_REJECTED', message, status);
47
+ }
48
+ static membershipDenied(message = 'You are not a member of this group.') {
49
+ return new RhinoException('MEMBERSHIP_DENIED', message, 403);
50
+ }
45
51
  }
46
52
  exports.RhinoException = RhinoException;
53
+ /**
54
+ * Thrown by a lifecycle hook to reject an otherwise-successful auth action.
55
+ * The controller catches it: for token-issuing actions (login/register) the
56
+ * just-issued token is revoked; the configured `status` (default 403) is then
57
+ * returned to the client. A hook may also throw any other error.
58
+ */
59
+ class RhinoAuthRejected extends RhinoException {
60
+ constructor(message = 'Authentication rejected', status = 403) {
61
+ super('AUTH_REJECTED', message, status);
62
+ }
63
+ }
64
+ exports.RhinoAuthRejected = RhinoAuthRejected;
47
65
  //# sourceMappingURL=rhino-exception.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rhino-exception.js","sourceRoot":"","sources":["../../src/errors/rhino-exception.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAuB/C;;;GAGG;AACH,MAAa,cAAe,SAAQ,sBAAa;IACtC,IAAI,CAAiB;IAE9B,YAAY,IAAoB,EAAE,OAAe,EAAE,MAAc,EAAE,OAA6B;QAC9F,MAAM,IAAI,GAAmB,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAChF,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,MAAgC;QACtD,OAAO,IAAI,cAAc,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,MAAgB;QACrC,OAAO,IAAI,cAAc,CAAC,kBAAkB,EAAE,mDAAmD,EAAE,GAAG,EAAE;YACtG,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,MAAgC;QACjD,OAAO,IAAI,cAAc,CAAC,cAAc,EAAE,+CAA+C,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9G,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,cAAc;QAC1C,OAAO,IAAI,cAAc,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,8BAA8B;QACvD,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,WAAW;QACnC,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,cAAc,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,IAAY;QACjC,OAAO,IAAI,cAAc,CAAC,kBAAkB,EAAE,qBAAqB,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,IAAY;QACtC,OAAO,IAAI,cAAc,CAAC,wBAAwB,EAAE,2BAA2B,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxG,CAAC;CACF;AA9CD,wCA8CC"}
1
+ {"version":3,"file":"rhino-exception.js","sourceRoot":"","sources":["../../src/errors/rhino-exception.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAyB/C;;;GAGG;AACH,MAAa,cAAe,SAAQ,sBAAa;IACtC,IAAI,CAAiB;IAE9B,YAAY,IAAoB,EAAE,OAAe,EAAE,MAAc,EAAE,OAA6B;QAC9F,MAAM,IAAI,GAAmB,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAChF,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,MAAgC;QACtD,OAAO,IAAI,cAAc,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,MAAgB;QACrC,OAAO,IAAI,cAAc,CAAC,kBAAkB,EAAE,mDAAmD,EAAE,GAAG,EAAE;YACtG,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,MAAgC;QACjD,OAAO,IAAI,cAAc,CAAC,cAAc,EAAE,+CAA+C,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9G,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,cAAc;QAC1C,OAAO,IAAI,cAAc,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,8BAA8B;QACvD,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,WAAW;QACnC,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,cAAc,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,IAAY;QACjC,OAAO,IAAI,cAAc,CAAC,kBAAkB,EAAE,qBAAqB,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,IAAY;QACtC,OAAO,IAAI,cAAc,CAAC,wBAAwB,EAAE,2BAA2B,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,yBAAyB,EAAE,MAAM,GAAG,GAAG;QACnE,OAAO,IAAI,cAAc,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,OAAO,GAAG,qCAAqC;QACrE,OAAO,IAAI,cAAc,CAAC,mBAAmB,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;CACF;AAtDD,wCAsDC;AAED;;;;;GAKG;AACH,MAAa,iBAAkB,SAAQ,cAAc;IACnD,YAAY,OAAO,GAAG,yBAAyB,EAAE,MAAM,GAAG,GAAG;QAC3D,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;CACF;AAJD,8CAIC"}
@@ -0,0 +1,25 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { RhinoConfigService } from '../rhino.config';
3
+ import { MembershipService } from '../services/membership.service';
4
+ /**
5
+ * Coarse group-access gate (design §6), gated entirely by
6
+ * `auth.enforceGroupMembership`.
7
+ *
8
+ * When the flag is OFF this guard is a pure no-op: it returns `true`
9
+ * immediately and never inspects the request, so behavior is byte-for-byte
10
+ * unchanged. Install it AFTER `JwtAuthGuard` (needs `req.user`) and after
11
+ * `RouteGroupMiddleware` (needs `req.__routeGroup`).
12
+ *
13
+ * When ON:
14
+ * - `public`/skip-auth requests bypass the check (no auth).
15
+ * - the user must hold a membership row matching the resolved group (NULL row
16
+ * = wildcard) and, for tenant groups, the resolved org. No match → 403.
17
+ * - on success, the matched rows' permissions become the permission source
18
+ * for the downstream ResourcePolicy (attached as `__membershipPermissions`).
19
+ */
20
+ export declare class GroupMembershipGuard implements CanActivate {
21
+ private readonly config;
22
+ private readonly membership;
23
+ constructor(config: RhinoConfigService, membership: MembershipService);
24
+ canActivate(context: ExecutionContext): boolean;
25
+ }
@@ -0,0 +1,70 @@
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.GroupMembershipGuard = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const rhino_config_1 = require("../rhino.config");
15
+ const membership_service_1 = require("../services/membership.service");
16
+ const rhino_exception_1 = require("../errors/rhino-exception");
17
+ /**
18
+ * Coarse group-access gate (design §6), gated entirely by
19
+ * `auth.enforceGroupMembership`.
20
+ *
21
+ * When the flag is OFF this guard is a pure no-op: it returns `true`
22
+ * immediately and never inspects the request, so behavior is byte-for-byte
23
+ * unchanged. Install it AFTER `JwtAuthGuard` (needs `req.user`) and after
24
+ * `RouteGroupMiddleware` (needs `req.__routeGroup`).
25
+ *
26
+ * When ON:
27
+ * - `public`/skip-auth requests bypass the check (no auth).
28
+ * - the user must hold a membership row matching the resolved group (NULL row
29
+ * = wildcard) and, for tenant groups, the resolved org. No match → 403.
30
+ * - on success, the matched rows' permissions become the permission source
31
+ * for the downstream ResourcePolicy (attached as `__membershipPermissions`).
32
+ */
33
+ let GroupMembershipGuard = class GroupMembershipGuard {
34
+ config;
35
+ membership;
36
+ constructor(config, membership) {
37
+ this.config = config;
38
+ this.membership = membership;
39
+ }
40
+ canActivate(context) {
41
+ if (!this.membership.enabled())
42
+ return true;
43
+ const req = context.switchToHttp().getRequest();
44
+ if (req.__skipAuth)
45
+ return true;
46
+ const user = req.user;
47
+ if (!user)
48
+ return true; // unauthenticated handling is JwtAuthGuard's job
49
+ const routeGroup = req.__routeGroup ?? null;
50
+ // The `public` group never enforces membership (no auth).
51
+ if (routeGroup === 'public')
52
+ return true;
53
+ const org = req.organization ?? null;
54
+ const isTenant = this.config.isTenantGroup(routeGroup);
55
+ const rows = this.membership.matchingRows(user, routeGroup, org, isTenant);
56
+ if (rows.length === 0) {
57
+ throw rhino_exception_1.RhinoException.membershipDenied();
58
+ }
59
+ // Switch the permission source to the matched membership row(s).
60
+ user.__membershipPermissions = this.membership.permissionsFromRows(rows);
61
+ return true;
62
+ }
63
+ };
64
+ exports.GroupMembershipGuard = GroupMembershipGuard;
65
+ exports.GroupMembershipGuard = GroupMembershipGuard = __decorate([
66
+ (0, common_1.Injectable)(),
67
+ __metadata("design:paramtypes", [rhino_config_1.RhinoConfigService,
68
+ membership_service_1.MembershipService])
69
+ ], GroupMembershipGuard);
70
+ //# sourceMappingURL=group-membership.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-membership.guard.js","sourceRoot":"","sources":["../../src/guards/group-membership.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,kDAAqD;AACrD,uEAAmE;AACnE,+DAA2D;AAG3D;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IAFnB,YACmB,MAA0B,EAC1B,UAA6B;QAD7B,WAAM,GAAN,MAAM,CAAoB;QAC1B,eAAU,GAAV,UAAU,CAAmB;IAC7C,CAAC;IAEJ,WAAW,CAAC,OAAyB;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;YAAE,OAAO,IAAI,CAAC;QAE5C,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC,iDAAiD;QAEzE,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QAC5C,0DAA0D;QAC1D,IAAI,UAAU,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,gCAAc,CAAC,gBAAgB,EAAE,CAAC;QAC1C,CAAC;QAED,iEAAiE;QAChE,IAAY,CAAC,uBAAuB,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA9BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAGgB,iCAAkB;QACd,sCAAiB;GAHrC,oBAAoB,CA8BhC"}
@@ -39,12 +39,31 @@ let JwtAuthGuard = class JwtAuthGuard {
39
39
  throw rhino_exception_1.RhinoException.unauthorized('Missing bearer token');
40
40
  }
41
41
  const payload = this.auth.verifyToken(token);
42
+ if (await this.auth.isTokenRevoked(token)) {
43
+ throw rhino_exception_1.RhinoException.unauthorized('Token has been revoked');
44
+ }
42
45
  const userModel = this.config.authConfig().userModel;
43
46
  const delegate = this.prisma.model(userModel);
44
- const user = await delegate.findUnique({
45
- where: { id: payload.sub },
46
- include: { userRoles: { include: { role: true } } },
47
- });
47
+ // Only eager-load userRoles when multi-tenancy is configured. A
48
+ // single-tenant / org-less app's User model has no `userRoles` relation, so
49
+ // an unconditional include throws inside Prisma which would make every
50
+ // authenticated request fail with a 401 even though the token is valid.
51
+ // Gate the include and fall back to a plain lookup if it fails. Multi-tenant
52
+ // behavior is byte-for-byte unchanged.
53
+ let user = null;
54
+ if (this.config.multiTenantEnabled()) {
55
+ user = await delegate
56
+ .findUnique({
57
+ where: { id: payload.sub },
58
+ include: { userRoles: { include: { role: true } } },
59
+ })
60
+ .catch(() => null);
61
+ }
62
+ if (!user) {
63
+ user = await delegate
64
+ .findUnique({ where: { id: payload.sub } })
65
+ .catch(() => null);
66
+ }
48
67
  if (!user)
49
68
  throw rhino_exception_1.RhinoException.unauthorized('User not found');
50
69
  req.user = user;
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,2DAAuD;AACvD,6DAAyD;AACzD,kDAAqD;AACrD,+DAA2D;AAG3D;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEJ;IACA;IACA;IAHnB,YACmB,IAAiB,EACjB,MAAqB,EACrB,MAA0B;QAF1B,SAAI,GAAJ,IAAI,CAAa;QACjB,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAoB;IAC1C,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,gCAAc,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;YACrC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE;YAC1B,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI;YAAE,MAAM,gCAAc,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC/D,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA1BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAGc,0BAAW;QACT,8BAAa;QACb,iCAAkB;GAJlC,YAAY,CA0BxB"}
1
+ {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,2DAAuD;AACvD,6DAAyD;AACzD,kDAAqD;AACrD,+DAA2D;AAG3D;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEJ;IACA;IACA;IAHnB,YACmB,IAAiB,EACjB,MAAqB,EACrB,MAA0B;QAF1B,SAAI,GAAJ,IAAI,CAAa;QACjB,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAoB;IAC1C,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,gCAAc,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,gCAAc,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,gEAAgE;QAChE,4EAA4E;QAC5E,yEAAyE;QACzE,wEAAwE;QACxE,6EAA6E;QAC7E,uCAAuC;QACvC,IAAI,IAAI,GAAQ,IAAI,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,MAAM,QAAQ;iBAClB,UAAU,CAAC;gBACV,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE;gBAC1B,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;aACpD,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,MAAM,QAAQ;iBAClB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;iBAC1C,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,IAAI;YAAE,MAAM,gCAAc,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC/D,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA7CY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAGc,0BAAW;QACT,8BAAa;QACb,iCAAkB;GAJlC,YAAY,CA6CxB"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { RhinoModule, type RhinoModuleOptions } from './rhino.module';
2
- export { RhinoException, type RhinoErrorCode, type RhinoErrorBody, } from './errors/rhino-exception';
2
+ export { RhinoException, RhinoAuthRejected, type RhinoErrorCode, type RhinoErrorBody, } from './errors/rhino-exception';
3
3
  export type { RhinoRequest } from './interfaces/rhino-request.interface';
4
4
  export { RhinoConfigService, normalizeConfig, } from './rhino.config';
5
5
  export { RHINO_CONFIG, RHINO_PRISMA_CLIENT, RHINO_MODULE_OPTIONS, } from './constants/tokens';
@@ -7,11 +7,13 @@ export * from './interfaces/rhino-config.interface';
7
7
  export { ResourcePolicy } from './policies/resource-policy';
8
8
  export { JwtAuthGuard } from './guards/jwt-auth.guard';
9
9
  export { ResourcePolicyGuard } from './guards/resource-policy.guard';
10
+ export { GroupMembershipGuard } from './guards/group-membership.guard';
10
11
  export { ResponseInterceptor, paginated } from './interceptors/response.interceptor';
11
12
  export { HiddenColumnsInterceptor } from './interceptors/hidden-columns.interceptor';
12
13
  export { ResolveOrganizationMiddleware } from './middleware/resolve-organization.middleware';
13
14
  export { RouteGroupMiddleware } from './middleware/route-group.middleware';
14
15
  export { createTenantRouteRewrite, type TenantRouteRewriteOptions, } from './middleware/tenant-route-rewrite';
16
+ export { createDomainRouteResolver, type DomainRouteResolverOptions, } from './middleware/domain-route-resolver';
15
17
  export { GlobalController } from './controllers/global.controller';
16
18
  export { AuthController } from './controllers/auth.controller';
17
19
  export { InvitationController } from './controllers/invitation.controller';
@@ -24,6 +26,8 @@ export { ValidationService } from './services/validation.service';
24
26
  export { AuditService } from './services/audit.service';
25
27
  export { AuthService } from './services/auth.service';
26
28
  export { InvitationService } from './services/invitation.service';
29
+ export { AuthHooksService, type AuthHookEvent } from './services/auth-hooks.service';
30
+ export { MembershipService, type MembershipRow, } from './services/membership.service';
27
31
  export { NestedService } from './services/nested.service';
28
32
  export { OrganizationService } from './services/organization.service';
29
33
  export { ScopeService, type RhinoScope } from './services/scope.service';
@@ -33,6 +37,8 @@ export { withUuid } from './prisma/prisma-uuid.extension';
33
37
  export { RhinoModel, getRhinoModelMetadata, BelongsToOrganization, HasAuditTrail, HasUuid, HasSoftDeletes, ExceptActions, HidableColumns, PermittedAttrs, } from './decorators';
34
38
  export { coercePermissions, matchesPermission, resolveUserRoleSlug, resolveUserPermissions, userHasPermission, } from './utils/permission-matcher';
35
39
  export { formatPrice, type CurrencyCode } from './utils/format';
40
+ export { compileDomain, matchDomain, type CompiledDomain, type DomainMatch, } from './utils/domain-pattern';
41
+ export { validateRouteGroups, RouteGroupConflictError, } from './utils/route-group-validator';
36
42
  export { autoDiscoverScopes, type ScopeDiscoveryOptions } from './utils/scope-discovery';
37
43
  export { defineModel, type ModelDefinition } from './utils/model-builder';
38
44
  export { findOrganizationFkChain, type FkRelation, type FkChainStep, type WalkOptions, } from './utils/fk-chain-walker';
package/dist/index.js CHANGED
@@ -14,14 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.userHasPermission = exports.resolveUserPermissions = exports.resolveUserRoleSlug = exports.matchesPermission = exports.coercePermissions = exports.PermittedAttrs = exports.HidableColumns = exports.ExceptActions = exports.HasSoftDeletes = exports.HasUuid = exports.HasAuditTrail = exports.BelongsToOrganization = exports.getRhinoModelMetadata = exports.RhinoModel = exports.withUuid = exports.withSoftDelete = exports.describeRoutes = exports.applyRhinoRouting = exports.ScopeService = exports.OrganizationService = exports.NestedService = exports.InvitationService = exports.AuthService = exports.AuditService = exports.ValidationService = exports.BASE_HIDDEN_COLUMNS = exports.SerializerService = exports.QueryBuilderService = exports.ResourceService = exports.PrismaService = exports.NestedController = exports.InvitationController = exports.AuthController = exports.GlobalController = exports.createTenantRouteRewrite = exports.RouteGroupMiddleware = exports.ResolveOrganizationMiddleware = exports.HiddenColumnsInterceptor = exports.paginated = exports.ResponseInterceptor = exports.ResourcePolicyGuard = exports.JwtAuthGuard = exports.ResourcePolicy = exports.RHINO_MODULE_OPTIONS = exports.RHINO_PRISMA_CLIENT = exports.RHINO_CONFIG = exports.normalizeConfig = exports.RhinoConfigService = exports.RhinoException = exports.RhinoModule = void 0;
18
- exports.SeederGenerator = exports.TestGenerator = exports.PolicyGenerator = exports.ResourceDefinitionGenerator = exports.PrismaSchemaGenerator = exports.BlueprintRunner = exports.ManifestManager = exports.BlueprintValidator = exports.BlueprintParser = exports.appendIfMissing = exports.writeFileSafely = exports.fileExists = exports.createReadlineInterface = exports.selectFromList = exports.confirm = exports.ask = exports.runExportTypes = exports.runExportPostman = exports.runBlueprint = exports.runGenerate = exports.runInstall = exports.printHelp = exports.extractCommand = exports.parseFlags = exports.generateTypeScriptTypes = exports.generatePostmanCollection = exports.findOrganizationFkChain = exports.defineModel = exports.autoDiscoverScopes = exports.formatPrice = void 0;
17
+ exports.PermittedAttrs = exports.HidableColumns = exports.ExceptActions = exports.HasSoftDeletes = exports.HasUuid = exports.HasAuditTrail = exports.BelongsToOrganization = exports.getRhinoModelMetadata = exports.RhinoModel = exports.withUuid = exports.withSoftDelete = exports.describeRoutes = exports.applyRhinoRouting = exports.ScopeService = exports.OrganizationService = exports.NestedService = exports.MembershipService = exports.AuthHooksService = exports.InvitationService = exports.AuthService = exports.AuditService = exports.ValidationService = exports.BASE_HIDDEN_COLUMNS = exports.SerializerService = exports.QueryBuilderService = exports.ResourceService = exports.PrismaService = exports.NestedController = exports.InvitationController = exports.AuthController = exports.GlobalController = exports.createDomainRouteResolver = exports.createTenantRouteRewrite = exports.RouteGroupMiddleware = exports.ResolveOrganizationMiddleware = exports.HiddenColumnsInterceptor = exports.paginated = exports.ResponseInterceptor = exports.GroupMembershipGuard = exports.ResourcePolicyGuard = exports.JwtAuthGuard = exports.ResourcePolicy = exports.RHINO_MODULE_OPTIONS = exports.RHINO_PRISMA_CLIENT = exports.RHINO_CONFIG = exports.normalizeConfig = exports.RhinoConfigService = exports.RhinoAuthRejected = exports.RhinoException = exports.RhinoModule = void 0;
18
+ exports.SeederGenerator = exports.TestGenerator = exports.PolicyGenerator = exports.ResourceDefinitionGenerator = exports.PrismaSchemaGenerator = exports.BlueprintRunner = exports.ManifestManager = exports.BlueprintValidator = exports.BlueprintParser = exports.appendIfMissing = exports.writeFileSafely = exports.fileExists = exports.createReadlineInterface = exports.selectFromList = exports.confirm = exports.ask = exports.runExportTypes = exports.runExportPostman = exports.runBlueprint = exports.runGenerate = exports.runInstall = exports.printHelp = exports.extractCommand = exports.parseFlags = exports.generateTypeScriptTypes = exports.generatePostmanCollection = exports.findOrganizationFkChain = exports.defineModel = exports.autoDiscoverScopes = exports.RouteGroupConflictError = exports.validateRouteGroups = exports.matchDomain = exports.compileDomain = exports.formatPrice = exports.userHasPermission = exports.resolveUserPermissions = exports.resolveUserRoleSlug = exports.matchesPermission = exports.coercePermissions = void 0;
19
19
  // Module
20
20
  var rhino_module_1 = require("./rhino.module");
21
21
  Object.defineProperty(exports, "RhinoModule", { enumerable: true, get: function () { return rhino_module_1.RhinoModule; } });
22
22
  // Errors
23
23
  var rhino_exception_1 = require("./errors/rhino-exception");
24
24
  Object.defineProperty(exports, "RhinoException", { enumerable: true, get: function () { return rhino_exception_1.RhinoException; } });
25
+ Object.defineProperty(exports, "RhinoAuthRejected", { enumerable: true, get: function () { return rhino_exception_1.RhinoAuthRejected; } });
25
26
  var rhino_config_1 = require("./rhino.config");
26
27
  Object.defineProperty(exports, "RhinoConfigService", { enumerable: true, get: function () { return rhino_config_1.RhinoConfigService; } });
27
28
  Object.defineProperty(exports, "normalizeConfig", { enumerable: true, get: function () { return rhino_config_1.normalizeConfig; } });
@@ -40,6 +41,8 @@ var jwt_auth_guard_1 = require("./guards/jwt-auth.guard");
40
41
  Object.defineProperty(exports, "JwtAuthGuard", { enumerable: true, get: function () { return jwt_auth_guard_1.JwtAuthGuard; } });
41
42
  var resource_policy_guard_1 = require("./guards/resource-policy.guard");
42
43
  Object.defineProperty(exports, "ResourcePolicyGuard", { enumerable: true, get: function () { return resource_policy_guard_1.ResourcePolicyGuard; } });
44
+ var group_membership_guard_1 = require("./guards/group-membership.guard");
45
+ Object.defineProperty(exports, "GroupMembershipGuard", { enumerable: true, get: function () { return group_membership_guard_1.GroupMembershipGuard; } });
43
46
  // Interceptors
44
47
  var response_interceptor_1 = require("./interceptors/response.interceptor");
45
48
  Object.defineProperty(exports, "ResponseInterceptor", { enumerable: true, get: function () { return response_interceptor_1.ResponseInterceptor; } });
@@ -53,6 +56,8 @@ var route_group_middleware_1 = require("./middleware/route-group.middleware");
53
56
  Object.defineProperty(exports, "RouteGroupMiddleware", { enumerable: true, get: function () { return route_group_middleware_1.RouteGroupMiddleware; } });
54
57
  var tenant_route_rewrite_1 = require("./middleware/tenant-route-rewrite");
55
58
  Object.defineProperty(exports, "createTenantRouteRewrite", { enumerable: true, get: function () { return tenant_route_rewrite_1.createTenantRouteRewrite; } });
59
+ var domain_route_resolver_1 = require("./middleware/domain-route-resolver");
60
+ Object.defineProperty(exports, "createDomainRouteResolver", { enumerable: true, get: function () { return domain_route_resolver_1.createDomainRouteResolver; } });
56
61
  // Controllers (consuming apps can re-export under their own routes)
57
62
  var global_controller_1 = require("./controllers/global.controller");
58
63
  Object.defineProperty(exports, "GlobalController", { enumerable: true, get: function () { return global_controller_1.GlobalController; } });
@@ -80,6 +85,10 @@ var auth_service_1 = require("./services/auth.service");
80
85
  Object.defineProperty(exports, "AuthService", { enumerable: true, get: function () { return auth_service_1.AuthService; } });
81
86
  var invitation_service_1 = require("./services/invitation.service");
82
87
  Object.defineProperty(exports, "InvitationService", { enumerable: true, get: function () { return invitation_service_1.InvitationService; } });
88
+ var auth_hooks_service_1 = require("./services/auth-hooks.service");
89
+ Object.defineProperty(exports, "AuthHooksService", { enumerable: true, get: function () { return auth_hooks_service_1.AuthHooksService; } });
90
+ var membership_service_1 = require("./services/membership.service");
91
+ Object.defineProperty(exports, "MembershipService", { enumerable: true, get: function () { return membership_service_1.MembershipService; } });
83
92
  var nested_service_1 = require("./services/nested.service");
84
93
  Object.defineProperty(exports, "NestedService", { enumerable: true, get: function () { return nested_service_1.NestedService; } });
85
94
  var organization_service_1 = require("./services/organization.service");
@@ -114,6 +123,12 @@ Object.defineProperty(exports, "resolveUserPermissions", { enumerable: true, get
114
123
  Object.defineProperty(exports, "userHasPermission", { enumerable: true, get: function () { return permission_matcher_1.userHasPermission; } });
115
124
  var format_1 = require("./utils/format");
116
125
  Object.defineProperty(exports, "formatPrice", { enumerable: true, get: function () { return format_1.formatPrice; } });
126
+ var domain_pattern_1 = require("./utils/domain-pattern");
127
+ Object.defineProperty(exports, "compileDomain", { enumerable: true, get: function () { return domain_pattern_1.compileDomain; } });
128
+ Object.defineProperty(exports, "matchDomain", { enumerable: true, get: function () { return domain_pattern_1.matchDomain; } });
129
+ var route_group_validator_1 = require("./utils/route-group-validator");
130
+ Object.defineProperty(exports, "validateRouteGroups", { enumerable: true, get: function () { return route_group_validator_1.validateRouteGroups; } });
131
+ Object.defineProperty(exports, "RouteGroupConflictError", { enumerable: true, get: function () { return route_group_validator_1.RouteGroupConflictError; } });
117
132
  var scope_discovery_1 = require("./utils/scope-discovery");
118
133
  Object.defineProperty(exports, "autoDiscoverScopes", { enumerable: true, get: function () { return scope_discovery_1.autoDiscoverScopes; } });
119
134
  var model_builder_1 = require("./utils/model-builder");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}