@lenne.tech/nest-server 11.20.1 → 11.21.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.
- package/dist/core/common/decorators/restricted.decorator.d.ts +1 -0
- package/dist/core/common/decorators/restricted.decorator.js +4 -1
- package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +5 -1
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +4 -1
- package/dist/core/common/middleware/request-context.middleware.js +10 -6
- package/dist/core/common/middleware/request-context.middleware.js.map +1 -1
- package/dist/core/common/plugins/mongoose-tenant.plugin.js +40 -24
- package/dist/core/common/plugins/mongoose-tenant.plugin.js.map +1 -1
- package/dist/core/common/services/request-context.service.d.ts +3 -0
- package/dist/core/common/services/request-context.service.js.map +1 -1
- package/dist/core/modules/auth/guards/roles.guard.js +6 -10
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-roles.guard.js +5 -6
- package/dist/core/modules/better-auth/better-auth-roles.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant-member.model.d.ts +11 -0
- package/dist/core/modules/tenant/core-tenant-member.model.js +106 -0
- package/dist/core/modules/tenant/core-tenant-member.model.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.decorators.d.ts +3 -0
- package/dist/core/modules/tenant/core-tenant.decorators.js +12 -0
- package/dist/core/modules/tenant/core-tenant.decorators.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.enums.d.ts +13 -0
- package/dist/core/modules/tenant/core-tenant.enums.js +25 -0
- package/dist/core/modules/tenant/core-tenant.enums.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.guard.d.ts +13 -0
- package/dist/core/modules/tenant/core-tenant.guard.js +162 -0
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.helpers.d.ts +7 -0
- package/dist/core/modules/tenant/core-tenant.helpers.js +60 -0
- package/dist/core/modules/tenant/core-tenant.helpers.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.module.d.ts +12 -0
- package/dist/core/modules/tenant/core-tenant.module.js +58 -0
- package/dist/core/modules/tenant/core-tenant.module.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.service.d.ts +17 -0
- package/dist/core/modules/tenant/core-tenant.service.js +160 -0
- package/dist/core/modules/tenant/core-tenant.service.js.map +1 -0
- package/dist/core.module.js +11 -0
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +12 -10
- package/src/core/common/decorators/restricted.decorator.ts +12 -2
- package/src/core/common/interceptors/check-security.interceptor.ts +9 -2
- package/src/core/common/interfaces/server-options.interface.ts +63 -30
- package/src/core/common/middleware/request-context.middleware.ts +12 -5
- package/src/core/common/plugins/mongoose-tenant.plugin.ts +78 -45
- package/src/core/common/services/request-context.service.ts +7 -1
- package/src/core/modules/auth/guards/roles.guard.ts +10 -10
- package/src/core/modules/better-auth/better-auth-roles.guard.ts +9 -6
- package/src/core/modules/tenant/INTEGRATION-CHECKLIST.md +165 -0
- package/src/core/modules/tenant/README.md +232 -0
- package/src/core/modules/tenant/core-tenant-member.model.ts +121 -0
- package/src/core/modules/tenant/core-tenant.decorators.ts +46 -0
- package/src/core/modules/tenant/core-tenant.enums.ts +77 -0
- package/src/core/modules/tenant/core-tenant.guard.ts +240 -0
- package/src/core/modules/tenant/core-tenant.helpers.ts +103 -0
- package/src/core/modules/tenant/core-tenant.module.ts +102 -0
- package/src/core/modules/tenant/core-tenant.service.ts +235 -0
- package/src/core.module.ts +15 -0
- package/src/index.ts +12 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const TENANT_MEMBER_MODEL_TOKEN = "TenantMember";
|
|
2
|
+
export declare enum TenantMemberStatus {
|
|
3
|
+
ACTIVE = "ACTIVE",
|
|
4
|
+
INVITED = "INVITED",
|
|
5
|
+
SUSPENDED = "SUSPENDED"
|
|
6
|
+
}
|
|
7
|
+
export declare const DEFAULT_ROLE_HIERARCHY: Record<string, number>;
|
|
8
|
+
export declare function createHierarchyRoles<T extends Record<string, number>>(hierarchy: T): {
|
|
9
|
+
[K in keyof T as Uppercase<string & K>]: string & K;
|
|
10
|
+
};
|
|
11
|
+
export declare const DefaultHR: {
|
|
12
|
+
[x: Uppercase<string>]: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultHR = exports.DEFAULT_ROLE_HIERARCHY = exports.TenantMemberStatus = exports.TENANT_MEMBER_MODEL_TOKEN = void 0;
|
|
4
|
+
exports.createHierarchyRoles = createHierarchyRoles;
|
|
5
|
+
exports.TENANT_MEMBER_MODEL_TOKEN = 'TenantMember';
|
|
6
|
+
var TenantMemberStatus;
|
|
7
|
+
(function (TenantMemberStatus) {
|
|
8
|
+
TenantMemberStatus["ACTIVE"] = "ACTIVE";
|
|
9
|
+
TenantMemberStatus["INVITED"] = "INVITED";
|
|
10
|
+
TenantMemberStatus["SUSPENDED"] = "SUSPENDED";
|
|
11
|
+
})(TenantMemberStatus || (exports.TenantMemberStatus = TenantMemberStatus = {}));
|
|
12
|
+
exports.DEFAULT_ROLE_HIERARCHY = {
|
|
13
|
+
member: 1,
|
|
14
|
+
manager: 2,
|
|
15
|
+
owner: 3,
|
|
16
|
+
};
|
|
17
|
+
function createHierarchyRoles(hierarchy) {
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const key of Object.keys(hierarchy)) {
|
|
20
|
+
result[key.toUpperCase()] = key;
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
exports.DefaultHR = createHierarchyRoles(exports.DEFAULT_ROLE_HIERARCHY);
|
|
25
|
+
//# sourceMappingURL=core-tenant.enums.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-tenant.enums.js","sourceRoot":"","sources":["../../../../src/core/modules/tenant/core-tenant.enums.ts"],"names":[],"mappings":";;;AAuDA,oDAQC;AA3DY,QAAA,yBAAyB,GAAG,cAAc,CAAC;AAKxD,IAAY,kBAKX;AALD,WAAY,kBAAkB;IAC5B,uCAAiB,CAAA;IAEjB,yCAAmB,CAAA;IACnB,6CAAuB,CAAA;AACzB,CAAC,EALW,kBAAkB,kCAAlB,kBAAkB,QAK7B;AAmBY,QAAA,sBAAsB,GAA2B;IAC5D,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;CACT,CAAC;AAkBF,SAAgB,oBAAoB,CAClC,SAAY;IAEZ,MAAM,MAAM,GAAG,EAAS,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,GAAG,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAaY,QAAA,SAAS,GAAG,oBAAoB,CAAC,8BAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { Model } from 'mongoose';
|
|
4
|
+
import { CoreTenantMemberModel } from './core-tenant-member.model';
|
|
5
|
+
export declare class CoreTenantGuard implements CanActivate {
|
|
6
|
+
private readonly reflector;
|
|
7
|
+
private readonly memberModel;
|
|
8
|
+
private readonly logger;
|
|
9
|
+
constructor(reflector: Reflector, memberModel: Model<CoreTenantMemberModel>);
|
|
10
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
11
|
+
private resolveUserTenantIds;
|
|
12
|
+
private getRequest;
|
|
13
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var CoreTenantGuard_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.CoreTenantGuard = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const core_1 = require("@nestjs/core");
|
|
19
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
20
|
+
const mongoose_1 = require("@nestjs/mongoose");
|
|
21
|
+
const mongoose_2 = require("mongoose");
|
|
22
|
+
const role_enum_1 = require("../../common/enums/role.enum");
|
|
23
|
+
const config_service_1 = require("../../common/services/config.service");
|
|
24
|
+
const core_tenant_decorators_1 = require("./core-tenant.decorators");
|
|
25
|
+
const core_tenant_enums_1 = require("./core-tenant.enums");
|
|
26
|
+
const core_tenant_helpers_1 = require("./core-tenant.helpers");
|
|
27
|
+
let CoreTenantGuard = CoreTenantGuard_1 = class CoreTenantGuard {
|
|
28
|
+
reflector;
|
|
29
|
+
memberModel;
|
|
30
|
+
logger = new common_1.Logger(CoreTenantGuard_1.name);
|
|
31
|
+
constructor(reflector, memberModel) {
|
|
32
|
+
this.reflector = reflector;
|
|
33
|
+
this.memberModel = memberModel;
|
|
34
|
+
}
|
|
35
|
+
async canActivate(context) {
|
|
36
|
+
const config = config_service_1.ConfigService.configFastButReadOnly?.multiTenancy;
|
|
37
|
+
if (!config || config.enabled === false) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const request = this.getRequest(context);
|
|
41
|
+
if (!request) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const headerName = (config.headerName ?? 'x-tenant-id').toLowerCase();
|
|
45
|
+
const rawHeader = request.headers?.[headerName];
|
|
46
|
+
const headerTenantId = rawHeader && typeof rawHeader === 'string' && rawHeader.length <= 128 ? rawHeader.trim() : undefined;
|
|
47
|
+
const rolesMetadata = this.reflector.getAll('roles', [context.getHandler(), context.getClass()]);
|
|
48
|
+
const roles = (0, core_tenant_helpers_1.mergeRolesMetadata)(rolesMetadata);
|
|
49
|
+
const checkableRoles = roles.filter((r) => !(0, core_tenant_helpers_1.isSystemRole)(r));
|
|
50
|
+
const minRequiredLevel = (0, core_tenant_helpers_1.getMinRequiredLevel)(checkableRoles);
|
|
51
|
+
const user = request.user;
|
|
52
|
+
const adminBypass = config.adminBypass !== false;
|
|
53
|
+
const isAdmin = adminBypass && user?.roles?.includes(role_enum_1.RoleEnum.ADMIN);
|
|
54
|
+
const skipTenantCheck = this.reflector.getAllAndOverride(core_tenant_decorators_1.SKIP_TENANT_CHECK_KEY, [
|
|
55
|
+
context.getHandler(),
|
|
56
|
+
context.getClass(),
|
|
57
|
+
]);
|
|
58
|
+
if (skipTenantCheck) {
|
|
59
|
+
if (checkableRoles.length > 0 && user) {
|
|
60
|
+
if (!isAdmin && !(0, core_tenant_helpers_1.checkRoleAccess)(checkableRoles, user.roles, undefined)) {
|
|
61
|
+
throw new common_1.ForbiddenException('Insufficient role');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (headerTenantId) {
|
|
67
|
+
if (isAdmin) {
|
|
68
|
+
request.tenantId = headerTenantId;
|
|
69
|
+
request.isAdminBypass = true;
|
|
70
|
+
const requiredRole = checkableRoles.length > 0 ? checkableRoles.join(',') : 'none';
|
|
71
|
+
this.logger.log(`Admin bypass: user ${user.id} accessing tenant ${headerTenantId} (required: ${requiredRole})`);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if (!user) {
|
|
75
|
+
throw new common_1.ForbiddenException('Authentication required for tenant access');
|
|
76
|
+
}
|
|
77
|
+
const membership = await this.memberModel
|
|
78
|
+
.findOne({
|
|
79
|
+
status: core_tenant_enums_1.TenantMemberStatus.ACTIVE,
|
|
80
|
+
tenant: headerTenantId,
|
|
81
|
+
user: user.id,
|
|
82
|
+
})
|
|
83
|
+
.lean()
|
|
84
|
+
.exec();
|
|
85
|
+
if (!membership) {
|
|
86
|
+
throw new common_1.ForbiddenException('Not a member of this tenant');
|
|
87
|
+
}
|
|
88
|
+
const memberRole = membership.role;
|
|
89
|
+
if (checkableRoles.length > 0) {
|
|
90
|
+
if (!(0, core_tenant_helpers_1.checkRoleAccess)(checkableRoles, undefined, memberRole)) {
|
|
91
|
+
throw new common_1.ForbiddenException('Insufficient tenant role');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
request.tenantId = headerTenantId;
|
|
95
|
+
request.tenantRole = memberRole;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (isAdmin) {
|
|
99
|
+
request.isAdminBypass = true;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (checkableRoles.length > 0) {
|
|
103
|
+
if (!user) {
|
|
104
|
+
throw new common_1.ForbiddenException('Authentication required');
|
|
105
|
+
}
|
|
106
|
+
if (!(0, core_tenant_helpers_1.checkRoleAccess)(checkableRoles, user.roles, undefined)) {
|
|
107
|
+
throw new common_1.ForbiddenException('Insufficient role');
|
|
108
|
+
}
|
|
109
|
+
await this.resolveUserTenantIds(request, minRequiredLevel);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (user) {
|
|
113
|
+
await this.resolveUserTenantIds(request);
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
async resolveUserTenantIds(request, minLevel) {
|
|
118
|
+
if (request.tenantIds) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const memberships = await this.memberModel
|
|
122
|
+
.find({
|
|
123
|
+
status: core_tenant_enums_1.TenantMemberStatus.ACTIVE,
|
|
124
|
+
user: request.user.id,
|
|
125
|
+
})
|
|
126
|
+
.select('tenant role')
|
|
127
|
+
.lean()
|
|
128
|
+
.exec();
|
|
129
|
+
if (minLevel !== undefined) {
|
|
130
|
+
const hierarchy = (0, core_tenant_helpers_1.getRoleHierarchy)();
|
|
131
|
+
request.tenantIds = memberships
|
|
132
|
+
.filter((m) => {
|
|
133
|
+
const level = hierarchy[m.role] ?? 0;
|
|
134
|
+
return level >= minLevel;
|
|
135
|
+
})
|
|
136
|
+
.map((m) => m.tenant);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
request.tenantIds = memberships.map((m) => m.tenant);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
getRequest(context) {
|
|
143
|
+
if (context.getType() === 'graphql') {
|
|
144
|
+
const ctx = graphql_1.GqlExecutionContext.create(context);
|
|
145
|
+
return ctx.getContext()?.req;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
return context.switchToHttp().getRequest();
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
exports.CoreTenantGuard = CoreTenantGuard;
|
|
156
|
+
exports.CoreTenantGuard = CoreTenantGuard = CoreTenantGuard_1 = __decorate([
|
|
157
|
+
(0, common_1.Injectable)(),
|
|
158
|
+
__param(1, (0, mongoose_1.InjectModel)(core_tenant_enums_1.TENANT_MEMBER_MODEL_TOKEN)),
|
|
159
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
|
160
|
+
mongoose_2.Model])
|
|
161
|
+
], CoreTenantGuard);
|
|
162
|
+
//# sourceMappingURL=core-tenant.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-tenant.guard.js","sourceRoot":"","sources":["../../../../src/core/modules/tenant/core-tenant.guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function mergeRolesMetadata(meta: (string[] | undefined)[]): string[];
|
|
2
|
+
export declare function getRoleHierarchy(): Record<string, number>;
|
|
3
|
+
export declare function isSystemRole(role: string): boolean;
|
|
4
|
+
export declare function isMultiTenancyActive(): boolean;
|
|
5
|
+
export declare function isHierarchyRole(role: string): boolean;
|
|
6
|
+
export declare function getMinRequiredLevel(roles: string[]): number | undefined;
|
|
7
|
+
export declare function checkRoleAccess(requiredRoles: string[], userRoles?: string[], tenantRole?: string): boolean;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeRolesMetadata = mergeRolesMetadata;
|
|
4
|
+
exports.getRoleHierarchy = getRoleHierarchy;
|
|
5
|
+
exports.isSystemRole = isSystemRole;
|
|
6
|
+
exports.isMultiTenancyActive = isMultiTenancyActive;
|
|
7
|
+
exports.isHierarchyRole = isHierarchyRole;
|
|
8
|
+
exports.getMinRequiredLevel = getMinRequiredLevel;
|
|
9
|
+
exports.checkRoleAccess = checkRoleAccess;
|
|
10
|
+
const config_service_1 = require("../../common/services/config.service");
|
|
11
|
+
const core_tenant_enums_1 = require("./core-tenant.enums");
|
|
12
|
+
const SYSTEM_ROLE_PREFIX = 's_';
|
|
13
|
+
function mergeRolesMetadata(meta) {
|
|
14
|
+
return meta[0] ? (meta[1] ? [...meta[0], ...meta[1]] : meta[0]) : meta[1] || [];
|
|
15
|
+
}
|
|
16
|
+
function getRoleHierarchy() {
|
|
17
|
+
return config_service_1.ConfigService.configFastButReadOnly?.multiTenancy?.roleHierarchy ?? core_tenant_enums_1.DEFAULT_ROLE_HIERARCHY;
|
|
18
|
+
}
|
|
19
|
+
function isSystemRole(role) {
|
|
20
|
+
return role.startsWith(SYSTEM_ROLE_PREFIX);
|
|
21
|
+
}
|
|
22
|
+
function isMultiTenancyActive() {
|
|
23
|
+
const config = config_service_1.ConfigService.configFastButReadOnly?.multiTenancy;
|
|
24
|
+
return !!config && config.enabled !== false;
|
|
25
|
+
}
|
|
26
|
+
function isHierarchyRole(role) {
|
|
27
|
+
if (!isMultiTenancyActive())
|
|
28
|
+
return false;
|
|
29
|
+
const hierarchy = getRoleHierarchy();
|
|
30
|
+
return role in hierarchy;
|
|
31
|
+
}
|
|
32
|
+
function getMinRequiredLevel(roles) {
|
|
33
|
+
const hierarchy = getRoleHierarchy();
|
|
34
|
+
const levels = roles.filter((r) => r in hierarchy).map((r) => hierarchy[r]);
|
|
35
|
+
if (levels.length === 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
return Math.min(...levels);
|
|
38
|
+
}
|
|
39
|
+
function checkRoleAccess(requiredRoles, userRoles, tenantRole) {
|
|
40
|
+
const availableRoles = tenantRole ? [tenantRole] : (userRoles ?? []);
|
|
41
|
+
if (availableRoles.length === 0)
|
|
42
|
+
return false;
|
|
43
|
+
const multiTenancyActive = isMultiTenancyActive();
|
|
44
|
+
const hierarchy = multiTenancyActive ? getRoleHierarchy() : {};
|
|
45
|
+
const hierarchyRequired = requiredRoles.filter((r) => r in hierarchy);
|
|
46
|
+
const nonHierarchyRequired = requiredRoles.filter((r) => !(r in hierarchy));
|
|
47
|
+
if (hierarchyRequired.length === 0 && nonHierarchyRequired.length === 0)
|
|
48
|
+
return true;
|
|
49
|
+
if (hierarchyRequired.length > 0) {
|
|
50
|
+
const minRequired = Math.min(...hierarchyRequired.map((r) => hierarchy[r]));
|
|
51
|
+
if (availableRoles.some((r) => r in hierarchy && hierarchy[r] >= minRequired))
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (nonHierarchyRequired.length > 0) {
|
|
55
|
+
if (nonHierarchyRequired.some((r) => availableRoles.includes(r)))
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=core-tenant.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-tenant.helpers.js","sourceRoot":"","sources":["../../../../src/core/modules/tenant/core-tenant.helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CanActivate, DynamicModule, Type } from '@nestjs/common';
|
|
2
|
+
import { CoreTenantMemberModel } from './core-tenant-member.model';
|
|
3
|
+
import { CoreTenantService } from './core-tenant.service';
|
|
4
|
+
export interface CoreTenantModuleOptions {
|
|
5
|
+
memberModel?: Type<CoreTenantMemberModel>;
|
|
6
|
+
guard?: Type<CanActivate>;
|
|
7
|
+
service?: Type<CoreTenantService>;
|
|
8
|
+
modelName?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class CoreTenantModule {
|
|
11
|
+
static forRoot(options?: CoreTenantModuleOptions): DynamicModule;
|
|
12
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
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 CoreTenantModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CoreTenantModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@nestjs/core");
|
|
13
|
+
const mongoose_1 = require("@nestjs/mongoose");
|
|
14
|
+
const core_tenant_member_model_1 = require("./core-tenant-member.model");
|
|
15
|
+
const core_tenant_enums_1 = require("./core-tenant.enums");
|
|
16
|
+
const core_tenant_guard_1 = require("./core-tenant.guard");
|
|
17
|
+
const core_tenant_service_1 = require("./core-tenant.service");
|
|
18
|
+
let CoreTenantModule = CoreTenantModule_1 = class CoreTenantModule {
|
|
19
|
+
static forRoot(options = {}) {
|
|
20
|
+
const MemberModel = options.memberModel || core_tenant_member_model_1.CoreTenantMemberModel;
|
|
21
|
+
const Guard = options.guard || core_tenant_guard_1.CoreTenantGuard;
|
|
22
|
+
const Service = options.service || core_tenant_service_1.CoreTenantService;
|
|
23
|
+
const modelName = options.modelName || core_tenant_enums_1.TENANT_MEMBER_MODEL_TOKEN;
|
|
24
|
+
const memberSchema = mongoose_1.SchemaFactory.createForClass(MemberModel);
|
|
25
|
+
memberSchema.index({ user: 1, tenant: 1 }, { unique: true });
|
|
26
|
+
memberSchema.index({ user: 1, tenant: 1, status: 1 });
|
|
27
|
+
const providers = [
|
|
28
|
+
{
|
|
29
|
+
provide: core_tenant_service_1.CoreTenantService,
|
|
30
|
+
useClass: Service,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
provide: core_1.APP_GUARD,
|
|
34
|
+
useClass: Guard,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
if (modelName !== core_tenant_enums_1.TENANT_MEMBER_MODEL_TOKEN) {
|
|
38
|
+
providers.push({
|
|
39
|
+
provide: (0, mongoose_1.getModelToken)(core_tenant_enums_1.TENANT_MEMBER_MODEL_TOKEN),
|
|
40
|
+
useFactory: (model) => model,
|
|
41
|
+
inject: [(0, mongoose_1.getModelToken)(modelName)],
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
exports: [core_tenant_service_1.CoreTenantService],
|
|
46
|
+
global: true,
|
|
47
|
+
imports: [mongoose_1.MongooseModule.forFeature([{ name: modelName, schema: memberSchema }])],
|
|
48
|
+
module: CoreTenantModule_1,
|
|
49
|
+
providers,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.CoreTenantModule = CoreTenantModule;
|
|
54
|
+
exports.CoreTenantModule = CoreTenantModule = CoreTenantModule_1 = __decorate([
|
|
55
|
+
(0, common_1.Global)(),
|
|
56
|
+
(0, common_1.Module)({})
|
|
57
|
+
], CoreTenantModule);
|
|
58
|
+
//# sourceMappingURL=core-tenant.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-tenant.module.js","sourceRoot":"","sources":["../../../../src/core/modules/tenant/core-tenant.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAkF;AAClF,uCAAyC;AACzC,+CAAgF;AAGhF,yEAAmE;AACnE,2DAAgE;AAChE,2DAAsD;AACtD,+DAA0D;AAkDnD,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,UAAmC,EAAE;QAClD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,gDAAqB,CAAC;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,mCAAe,CAAC;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,uCAAiB,CAAC;QACrD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,6CAAyB,CAAC;QAEjE,MAAM,YAAY,GAAG,wBAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAG/D,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAEtD,MAAM,SAAS,GAAU;YACvB;gBACE,OAAO,EAAE,uCAAiB;gBAC1B,QAAQ,EAAE,OAAO;aAClB;YACD;gBACE,OAAO,EAAE,gBAAS;gBAClB,QAAQ,EAAE,KAAK;aAChB;SACF,CAAC;QAIF,IAAI,SAAS,KAAK,6CAAyB,EAAE,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO,EAAE,IAAA,wBAAa,EAAC,6CAAyB,CAAC;gBACjD,UAAU,EAAE,CAAC,KAAiB,EAAE,EAAE,CAAC,KAAK;gBACxC,MAAM,EAAE,CAAC,IAAA,wBAAa,EAAC,SAAS,CAAC,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,uCAAiB,CAAC;YAC5B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,CAAC,yBAAc,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YACjF,MAAM,EAAE,kBAAgB;YACxB,SAAS;SACV,CAAC;IACJ,CAAC;CACF,CAAA;AA3CY,4CAAgB;2BAAhB,gBAAgB;IAF5B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,gBAAgB,CA2C5B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Logger } from '@nestjs/common';
|
|
2
|
+
import { Model } from 'mongoose';
|
|
3
|
+
import { CoreTenantMemberModel } from './core-tenant-member.model';
|
|
4
|
+
export declare class CoreTenantService {
|
|
5
|
+
protected readonly memberModel: Model<CoreTenantMemberModel>;
|
|
6
|
+
protected readonly logger: Logger;
|
|
7
|
+
constructor(memberModel: Model<CoreTenantMemberModel>);
|
|
8
|
+
protected getHierarchy(): Record<string, number>;
|
|
9
|
+
protected getDefaultRole(): string;
|
|
10
|
+
protected getHighestRole(): string;
|
|
11
|
+
findMemberships(userId: string): Promise<CoreTenantMemberModel[]>;
|
|
12
|
+
getMembership(tenantId: string, userId: string): Promise<CoreTenantMemberModel | null>;
|
|
13
|
+
addMember(tenantId: string, userId: string, role?: string, invitedById?: string): Promise<CoreTenantMemberModel>;
|
|
14
|
+
removeMember(tenantId: string, userId: string): Promise<CoreTenantMemberModel>;
|
|
15
|
+
updateMemberRole(tenantId: string, userId: string, role: string): Promise<CoreTenantMemberModel>;
|
|
16
|
+
assertNotLastOwner(tenantId: string, userId: string): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var CoreTenantService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.CoreTenantService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const mongoose_1 = require("@nestjs/mongoose");
|
|
19
|
+
const mongoose_2 = require("mongoose");
|
|
20
|
+
const config_service_1 = require("../../common/services/config.service");
|
|
21
|
+
const request_context_service_1 = require("../../common/services/request-context.service");
|
|
22
|
+
const core_tenant_enums_1 = require("./core-tenant.enums");
|
|
23
|
+
let CoreTenantService = CoreTenantService_1 = class CoreTenantService {
|
|
24
|
+
memberModel;
|
|
25
|
+
logger = new common_1.Logger(CoreTenantService_1.name);
|
|
26
|
+
constructor(memberModel) {
|
|
27
|
+
this.memberModel = memberModel;
|
|
28
|
+
}
|
|
29
|
+
getHierarchy() {
|
|
30
|
+
return config_service_1.ConfigService.configFastButReadOnly?.multiTenancy?.roleHierarchy ?? core_tenant_enums_1.DEFAULT_ROLE_HIERARCHY;
|
|
31
|
+
}
|
|
32
|
+
getDefaultRole() {
|
|
33
|
+
const hierarchy = this.getHierarchy();
|
|
34
|
+
const entries = Object.entries(hierarchy);
|
|
35
|
+
if (entries.length === 0)
|
|
36
|
+
return 'member';
|
|
37
|
+
return entries.reduce((a, b) => (a[1] <= b[1] ? a : b))[0];
|
|
38
|
+
}
|
|
39
|
+
getHighestRole() {
|
|
40
|
+
const hierarchy = this.getHierarchy();
|
|
41
|
+
const entries = Object.entries(hierarchy);
|
|
42
|
+
if (entries.length === 0)
|
|
43
|
+
return 'owner';
|
|
44
|
+
return entries.reduce((a, b) => (a[1] >= b[1] ? a : b))[0];
|
|
45
|
+
}
|
|
46
|
+
async findMemberships(userId) {
|
|
47
|
+
return this.memberModel.find({ status: core_tenant_enums_1.TenantMemberStatus.ACTIVE, user: userId }).lean().exec();
|
|
48
|
+
}
|
|
49
|
+
async getMembership(tenantId, userId) {
|
|
50
|
+
return this.memberModel
|
|
51
|
+
.findOne({ tenant: tenantId, user: userId })
|
|
52
|
+
.lean()
|
|
53
|
+
.exec();
|
|
54
|
+
}
|
|
55
|
+
async addMember(tenantId, userId, role, invitedById) {
|
|
56
|
+
if (!tenantId?.trim()) {
|
|
57
|
+
throw new common_1.BadRequestException('tenantId must not be empty');
|
|
58
|
+
}
|
|
59
|
+
if (!userId?.trim()) {
|
|
60
|
+
throw new common_1.BadRequestException('userId must not be empty');
|
|
61
|
+
}
|
|
62
|
+
const effectiveRole = role ?? this.getDefaultRole();
|
|
63
|
+
const existing = await this.getMembership(tenantId, userId);
|
|
64
|
+
if (existing) {
|
|
65
|
+
if (existing.status === core_tenant_enums_1.TenantMemberStatus.ACTIVE) {
|
|
66
|
+
throw new common_1.BadRequestException('User is already an active member of this tenant');
|
|
67
|
+
}
|
|
68
|
+
return request_context_service_1.RequestContext.runWithBypassTenantGuard(async () => {
|
|
69
|
+
return this.memberModel
|
|
70
|
+
.findOneAndUpdate({ tenant: tenantId, user: userId }, {
|
|
71
|
+
invitedBy: invitedById,
|
|
72
|
+
joinedAt: new Date(),
|
|
73
|
+
role: effectiveRole,
|
|
74
|
+
status: core_tenant_enums_1.TenantMemberStatus.ACTIVE,
|
|
75
|
+
}, { new: true })
|
|
76
|
+
.lean()
|
|
77
|
+
.exec();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return request_context_service_1.RequestContext.runWithBypassTenantGuard(async () => {
|
|
81
|
+
const doc = await this.memberModel.create({
|
|
82
|
+
invitedBy: invitedById,
|
|
83
|
+
joinedAt: new Date(),
|
|
84
|
+
role: effectiveRole,
|
|
85
|
+
status: core_tenant_enums_1.TenantMemberStatus.ACTIVE,
|
|
86
|
+
tenant: tenantId,
|
|
87
|
+
user: userId,
|
|
88
|
+
});
|
|
89
|
+
return doc.toObject();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async removeMember(tenantId, userId) {
|
|
93
|
+
if (!tenantId?.trim()) {
|
|
94
|
+
throw new common_1.BadRequestException('tenantId must not be empty');
|
|
95
|
+
}
|
|
96
|
+
if (!userId?.trim()) {
|
|
97
|
+
throw new common_1.BadRequestException('userId must not be empty');
|
|
98
|
+
}
|
|
99
|
+
await this.assertNotLastOwner(tenantId, userId);
|
|
100
|
+
return request_context_service_1.RequestContext.runWithBypassTenantGuard(async () => {
|
|
101
|
+
const result = await this.memberModel
|
|
102
|
+
.findOneAndUpdate({ status: core_tenant_enums_1.TenantMemberStatus.ACTIVE, tenant: tenantId, user: userId }, { status: core_tenant_enums_1.TenantMemberStatus.SUSPENDED }, { new: true })
|
|
103
|
+
.lean()
|
|
104
|
+
.exec();
|
|
105
|
+
if (!result) {
|
|
106
|
+
throw new common_1.NotFoundException('Membership not found');
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async updateMemberRole(tenantId, userId, role) {
|
|
112
|
+
if (!tenantId?.trim()) {
|
|
113
|
+
throw new common_1.BadRequestException('tenantId must not be empty');
|
|
114
|
+
}
|
|
115
|
+
if (!userId?.trim()) {
|
|
116
|
+
throw new common_1.BadRequestException('userId must not be empty');
|
|
117
|
+
}
|
|
118
|
+
if (!role?.trim()) {
|
|
119
|
+
throw new common_1.BadRequestException('role must not be empty');
|
|
120
|
+
}
|
|
121
|
+
const highestRole = this.getHighestRole();
|
|
122
|
+
const existing = await this.getMembership(tenantId, userId);
|
|
123
|
+
if (existing?.role === highestRole && role !== highestRole) {
|
|
124
|
+
await this.assertNotLastOwner(tenantId, userId);
|
|
125
|
+
}
|
|
126
|
+
return request_context_service_1.RequestContext.runWithBypassTenantGuard(async () => {
|
|
127
|
+
const result = await this.memberModel
|
|
128
|
+
.findOneAndUpdate({ status: core_tenant_enums_1.TenantMemberStatus.ACTIVE, tenant: tenantId, user: userId }, { role }, { new: true })
|
|
129
|
+
.lean()
|
|
130
|
+
.exec();
|
|
131
|
+
if (!result) {
|
|
132
|
+
throw new common_1.NotFoundException('Active membership not found');
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
async assertNotLastOwner(tenantId, userId) {
|
|
138
|
+
const highestRole = this.getHighestRole();
|
|
139
|
+
return request_context_service_1.RequestContext.runWithBypassTenantGuard(async () => {
|
|
140
|
+
const ownerCount = await this.memberModel.countDocuments({
|
|
141
|
+
role: highestRole,
|
|
142
|
+
status: core_tenant_enums_1.TenantMemberStatus.ACTIVE,
|
|
143
|
+
tenant: tenantId,
|
|
144
|
+
});
|
|
145
|
+
if (ownerCount <= 1) {
|
|
146
|
+
const membership = await this.getMembership(tenantId, userId);
|
|
147
|
+
if (membership?.role === highestRole) {
|
|
148
|
+
throw new common_1.BadRequestException('Cannot remove or demote the last owner of a tenant');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
exports.CoreTenantService = CoreTenantService;
|
|
155
|
+
exports.CoreTenantService = CoreTenantService = CoreTenantService_1 = __decorate([
|
|
156
|
+
(0, common_1.Injectable)(),
|
|
157
|
+
__param(0, (0, mongoose_1.InjectModel)(core_tenant_enums_1.TENANT_MEMBER_MODEL_TOKEN)),
|
|
158
|
+
__metadata("design:paramtypes", [mongoose_2.Model])
|
|
159
|
+
], CoreTenantService);
|
|
160
|
+
//# sourceMappingURL=core-tenant.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-tenant.service.js","sourceRoot":"","sources":["../../../../src/core/modules/tenant/core-tenant.service.ts"],"names":[],"mappings":"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"}
|
package/dist/core.module.js
CHANGED
|
@@ -40,6 +40,7 @@ const error_code_module_1 = require("./core/modules/error-code/error-code.module
|
|
|
40
40
|
const core_health_check_module_1 = require("./core/modules/health-check/core-health-check.module");
|
|
41
41
|
const core_permissions_module_1 = require("./core/modules/permissions/core-permissions.module");
|
|
42
42
|
const core_system_setup_module_1 = require("./core/modules/system-setup/core-system-setup.module");
|
|
43
|
+
const core_tenant_module_1 = require("./core/modules/tenant/core-tenant.module");
|
|
43
44
|
let CoreModule = class CoreModule {
|
|
44
45
|
static { CoreModule_1 = this; }
|
|
45
46
|
static graphQlEnabled = true;
|
|
@@ -218,6 +219,16 @@ let CoreModule = class CoreModule {
|
|
|
218
219
|
if (isBetterAuthEnabled && config.systemSetup?.enabled !== false) {
|
|
219
220
|
imports.push(core_system_setup_module_1.CoreSystemSetupModule);
|
|
220
221
|
}
|
|
222
|
+
if (config.multiTenancy && config.multiTenancy.enabled !== false) {
|
|
223
|
+
const membershipModelName = config.multiTenancy.membershipModel ?? 'TenantMember';
|
|
224
|
+
if (!config.multiTenancy.excludeSchemas) {
|
|
225
|
+
config.multiTenancy.excludeSchemas = [];
|
|
226
|
+
}
|
|
227
|
+
if (!config.multiTenancy.excludeSchemas.includes(membershipModelName)) {
|
|
228
|
+
config.multiTenancy.excludeSchemas.push(membershipModelName);
|
|
229
|
+
}
|
|
230
|
+
imports.push(core_tenant_module_1.CoreTenantModule.forRoot({ modelName: membershipModelName }));
|
|
231
|
+
}
|
|
221
232
|
const exports = [config_service_1.ConfigService, email_service_1.EmailService, template_service_1.TemplateService, mailjet_service_1.MailjetService];
|
|
222
233
|
if (!process.env.VITEST && isGraphQlEnabled) {
|
|
223
234
|
exports.push(complexity_plugin_1.ComplexityPlugin);
|