@uniorganization/uni-lib 4.1.4 → 4.1.5
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/entities/bp-alerts.entity.d.ts +2 -2
- package/dist/entities/bp-alerts.entity.js +4 -4
- package/dist/entities/business-schedule.entity.d.ts +2 -2
- package/dist/entities/business-schedule.entity.js +4 -4
- package/dist/entities/call-driver-data.entity.d.ts +2 -2
- package/dist/entities/call-driver-data.entity.js +4 -4
- package/dist/entities/call-drivers.entity.d.ts +1 -1
- package/dist/entities/call-drivers.entity.js +2 -2
- package/dist/entities/cb-completed-reasons.entity.d.ts +1 -1
- package/dist/entities/cb-completed-reasons.entity.js +2 -2
- package/dist/entities/claim-report.entity.d.ts +2 -2
- package/dist/entities/claim-report.entity.js +4 -4
- package/dist/entities/daily-payment.entity.d.ts +58 -0
- package/dist/entities/daily-payment.entity.js +248 -0
- package/dist/entities/dispute-request.entity.d.ts +2 -2
- package/dist/entities/dispute-request.entity.js +4 -4
- package/dist/entities/division.entity.d.ts +11 -0
- package/dist/entities/division.entity.js +52 -0
- package/dist/entities/enr-inventory.entity.d.ts +2 -2
- package/dist/entities/enr-inventory.entity.js +4 -4
- package/dist/entities/enr-results.entity.d.ts +1 -1
- package/dist/entities/enr-results.entity.js +2 -2
- package/dist/entities/escalations.entity.d.ts +2 -2
- package/dist/entities/escalations.entity.js +4 -4
- package/dist/entities/evaluation-forms.entity.d.ts +4 -4
- package/dist/entities/evaluations.entity.d.ts +2 -2
- package/dist/entities/evaluations.entity.js +4 -4
- package/dist/entities/form-fields.entity.d.ts +2 -2
- package/dist/entities/form-fields.entity.js +4 -4
- package/dist/entities/form.entity.d.ts +2 -2
- package/dist/entities/form.entity.js +4 -4
- package/dist/entities/inbox/message-case.entity.d.ts +2 -2
- package/dist/entities/inbox/message-case.entity.js +6 -8
- package/dist/entities/inbox/sla-policy.entity.d.ts +2 -2
- package/dist/entities/inbox/sla-policy.entity.js +4 -4
- package/dist/entities/index.d.ts +3 -0
- package/dist/entities/index.js +3 -0
- package/dist/entities/inventory.entity.d.ts +1 -1
- package/dist/entities/inventory.entity.js +2 -2
- package/dist/entities/lob-assignment.entity.d.ts +1 -1
- package/dist/entities/lob-assignment.entity.js +2 -2
- package/dist/entities/lob-call-drivers.entity.d.ts +1 -1
- package/dist/entities/lob-call-drivers.entity.js +2 -2
- package/dist/entities/lob.entity.d.ts +14 -0
- package/dist/entities/lob.entity.js +65 -0
- package/dist/entities/offphone-activities.entity.d.ts +1 -1
- package/dist/entities/offphone-activities.entity.js +2 -2
- package/dist/entities/otwe-offers.entity.d.ts +1 -1
- package/dist/entities/otwe-offers.entity.js +2 -2
- package/dist/entities/outbound-ticket-history.entity.d.ts +2 -2
- package/dist/entities/outbound-ticket-history.entity.js +4 -4
- package/dist/entities/pending-ticket-history.entity.d.ts +2 -2
- package/dist/entities/pending-ticket-history.entity.js +4 -4
- package/dist/entities/raw_roster.entity.d.ts +2 -2
- package/dist/entities/raw_roster.entity.js +4 -4
- package/dist/entities/roster.entity.d.ts +2 -2
- package/dist/entities/roster.entity.js +4 -4
- package/dist/entities/skipped-ticket.entity.d.ts +2 -2
- package/dist/entities/skipped-ticket.entity.js +4 -4
- package/dist/entities/template.entity.d.ts +2 -2
- package/dist/entities/template.entity.js +4 -4
- package/dist/entities/ticket-queue.entity.d.ts +2 -2
- package/dist/entities/ticket-queue.entity.js +4 -4
- package/dist/entities/user-roster.view.d.ts +2 -2
- package/dist/entities/user-roster.view.js +4 -4
- package/dist/entities/users-lobs.entity.d.ts +11 -0
- package/dist/entities/users-lobs.entity.js +57 -0
- package/dist/entities/usr.entity.d.ts +4 -2
- package/dist/entities/usr.entity.js +22 -14
- package/dist/entities/vw-escalation-age.d.ts +2 -0
- package/dist/entities/vw-escalation-age.js +8 -0
- package/dist/middlewares/index.d.ts +1 -0
- package/dist/middlewares/index.js +17 -0
- package/dist/middlewares/version-checker.middleware.d.ts +2 -0
- package/dist/middlewares/version-checker.middleware.js +27 -0
- package/dist/modules/common/jwt.strategy.js +8 -9
- package/dist/modules/common/jwt.strategy.spec.d.ts +1 -0
- package/dist/modules/common/jwt.strategy.spec.js +89 -0
- package/dist/modules/tenant/redis-tenant-state.store.js +10 -3
- package/dist/modules/tenant/tenant-authorization.service.d.ts +2 -2
- package/dist/modules/tenant/tenant-authorization.service.js +105 -35
- package/dist/modules/tenant/tenant-authorization.service.spec.d.ts +1 -0
- package/dist/modules/tenant/tenant-authorization.service.spec.js +101 -0
- package/dist/modules/tenant/tenant-authorization.types.d.ts +12 -2
- package/dist/modules/tenant/tenant.types.d.ts +9 -1
- package/package.json +13 -12
- package/dist/entities/user-client-context.entity.d.ts +0 -10
- package/dist/entities/user-client-context.entity.js +0 -59
- package/dist/modules/tenant/master-users.guard.d.ts +0 -4
- package/dist/modules/tenant/master-users.guard.js +0 -35
|
@@ -41,38 +41,39 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
41
41
|
this.userRoleRepository = userRoleRepository;
|
|
42
42
|
this.logger = new common_1.Logger(TenantAuthorizationService_1.name);
|
|
43
43
|
}
|
|
44
|
-
resolve(userId, clientId,
|
|
44
|
+
resolve(userId, clientId, _legacyOriginClientId) {
|
|
45
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
-
var _a;
|
|
46
|
+
var _a, _b;
|
|
47
47
|
this.assertPositiveInteger(userId);
|
|
48
48
|
this.assertPositiveInteger(clientId);
|
|
49
|
-
this.assertPositiveInteger(expectedHomeClientId);
|
|
50
49
|
const key = (0, tenant_authorization_keys_1.tenantAuthorizationKey)(clientId, userId);
|
|
51
50
|
const cached = yield this.readCache(key);
|
|
52
51
|
if (cached &&
|
|
53
52
|
cached.userId === userId &&
|
|
54
53
|
cached.clientId === clientId &&
|
|
55
|
-
cached.homeClientId === expectedHomeClientId &&
|
|
56
54
|
((_a = cached.identity) === null || _a === void 0 ? void 0 : _a.id) === userId &&
|
|
57
|
-
cached.identity.homeClientId === expectedHomeClientId &&
|
|
58
55
|
this.isFresh(cached.cachedAt) &&
|
|
59
|
-
cached.roles.length > 0
|
|
56
|
+
cached.roles.length > 0 &&
|
|
57
|
+
Array.isArray(cached.permissions) &&
|
|
58
|
+
((_b = cached.accessRole) === null || _b === void 0 ? void 0 : _b.id)) {
|
|
60
59
|
return { identity: cached.identity, snapshot: cached };
|
|
61
60
|
}
|
|
62
|
-
const resolved = yield this.loadFromDatabase(userId, clientId
|
|
61
|
+
const resolved = yield this.loadFromDatabase(userId, clientId);
|
|
63
62
|
yield this.writeCache(key, resolved.snapshot);
|
|
64
63
|
return resolved;
|
|
65
64
|
});
|
|
66
65
|
}
|
|
67
|
-
resolveImpersonation(userId,
|
|
66
|
+
resolveImpersonation(userId, originClientId, targetClientIdOrLegacyOriginClientId, legacyTargetClientId) {
|
|
68
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
-
|
|
68
|
+
const targetClientId = legacyTargetClientId !== null && legacyTargetClientId !== void 0 ? legacyTargetClientId : targetClientIdOrLegacyOriginClientId;
|
|
69
|
+
if (originClientId !== tenant_constants_1.NEWTECH_CLIENT_ID ||
|
|
70
70
|
targetClientId === tenant_constants_1.NEWTECH_CLIENT_ID) {
|
|
71
71
|
throw new common_1.UnauthorizedException();
|
|
72
72
|
}
|
|
73
|
-
const origin = yield this.resolve(userId,
|
|
74
|
-
const isNewtechMaster = origin.snapshot.
|
|
75
|
-
role.
|
|
73
|
+
const origin = yield this.resolve(userId, originClientId);
|
|
74
|
+
const isNewtechMaster = origin.snapshot.permissions.includes('master.users.read') ||
|
|
75
|
+
origin.snapshot.roles.some((role) => role.moduleName.toLowerCase() === 'root' &&
|
|
76
|
+
role.roleName.toLowerCase() === 'sysadmin');
|
|
76
77
|
const targetClient = yield this.clientRepository.findOne({
|
|
77
78
|
where: { id: targetClientId, deletedAt: (0, typeorm_2.IsNull)() },
|
|
78
79
|
});
|
|
@@ -81,7 +82,6 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
81
82
|
}
|
|
82
83
|
const snapshot = {
|
|
83
84
|
userId,
|
|
84
|
-
homeClientId,
|
|
85
85
|
clientId: targetClientId,
|
|
86
86
|
clientName: targetClient.name,
|
|
87
87
|
clientAlias: targetClient.alias,
|
|
@@ -94,6 +94,15 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
94
94
|
},
|
|
95
95
|
],
|
|
96
96
|
privileges: [],
|
|
97
|
+
accessRole: {
|
|
98
|
+
id: 0,
|
|
99
|
+
code: tenant_constants_1.TENANT_IMPERSONATOR_ROLE,
|
|
100
|
+
name: 'Tenant impersonator',
|
|
101
|
+
scope: 'GLOBAL',
|
|
102
|
+
clientId: null,
|
|
103
|
+
},
|
|
104
|
+
permissions: [],
|
|
105
|
+
authzVersion: 1,
|
|
97
106
|
identity: origin.identity,
|
|
98
107
|
cachedAt: new Date().toISOString(),
|
|
99
108
|
};
|
|
@@ -113,10 +122,14 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
113
122
|
}
|
|
114
123
|
});
|
|
115
124
|
}
|
|
116
|
-
loadFromDatabase(userId, clientId
|
|
125
|
+
loadFromDatabase(userId, clientId) {
|
|
117
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
var _a, _b;
|
|
128
|
+
const [user, client, assignments, accessRows] = yield Promise.all([
|
|
129
|
+
this.userRepository.findOne({
|
|
130
|
+
where: { id: userId },
|
|
131
|
+
relations: ['usersLobs', 'usersLobs.lob', 'usersLobs.lob.division'],
|
|
132
|
+
}),
|
|
120
133
|
this.clientRepository.findOne({
|
|
121
134
|
where: { id: clientId, deletedAt: (0, typeorm_2.IsNull)() },
|
|
122
135
|
}),
|
|
@@ -129,23 +142,75 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
129
142
|
.where('assignment."USER_ID" = :userId', { userId })
|
|
130
143
|
.andWhere('assignment.client_id = :clientId', { clientId })
|
|
131
144
|
.getMany(),
|
|
145
|
+
this.userRoleRepository.manager.query(`SELECT
|
|
146
|
+
role.id,
|
|
147
|
+
role.code,
|
|
148
|
+
role.name,
|
|
149
|
+
role.scope,
|
|
150
|
+
role.client_id AS "roleClientId",
|
|
151
|
+
role.authz_version AS "authzVersion",
|
|
152
|
+
COALESCE(
|
|
153
|
+
jsonb_agg(permission.code ORDER BY permission.code)
|
|
154
|
+
FILTER (WHERE permission.id IS NOT NULL AND permission.is_active),
|
|
155
|
+
'[]'::jsonb
|
|
156
|
+
) AS permissions
|
|
157
|
+
FROM stm."USER_ACCESS_ROLES" membership
|
|
158
|
+
JOIN stm."ACCESS_ROLES" role
|
|
159
|
+
ON role.id = membership.role_id
|
|
160
|
+
AND role.is_active
|
|
161
|
+
LEFT JOIN stm."ACCESS_ROLE_PERMISSIONS" definition
|
|
162
|
+
ON definition.role_id = role.id
|
|
163
|
+
LEFT JOIN stm."ACCESS_PERMISSIONS" permission
|
|
164
|
+
ON permission.id = definition.permission_id
|
|
165
|
+
WHERE membership.user_id = $1
|
|
166
|
+
AND membership.client_id = $2
|
|
167
|
+
GROUP BY role.id`, [userId, clientId]),
|
|
132
168
|
]);
|
|
133
169
|
if (!user ||
|
|
134
170
|
!Number(user.is_active) ||
|
|
135
|
-
user.clientId !== expectedHomeClientId ||
|
|
136
171
|
!client ||
|
|
137
|
-
|
|
172
|
+
accessRows.length > 1 ||
|
|
173
|
+
(accessRows.length === 0 && assignments.length === 0)) {
|
|
138
174
|
throw new common_1.UnauthorizedException();
|
|
139
175
|
}
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
176
|
+
const accessRow = accessRows[0];
|
|
177
|
+
const usingLegacyCompatibility = accessRows.length === 0 || accessRow.code.startsWith('migrated-');
|
|
178
|
+
const legacyRole = (_a = assignments[0]) === null || _a === void 0 ? void 0 : _a.role;
|
|
179
|
+
const accessRole = accessRow
|
|
180
|
+
? {
|
|
181
|
+
id: Number(accessRow.id),
|
|
182
|
+
code: accessRow.code,
|
|
183
|
+
name: accessRow.name,
|
|
184
|
+
scope: accessRow.scope,
|
|
185
|
+
clientId: accessRow.roleClientId == null
|
|
186
|
+
? null
|
|
187
|
+
: Number(accessRow.roleClientId),
|
|
188
|
+
}
|
|
189
|
+
: {
|
|
190
|
+
id: Number(legacyRole === null || legacyRole === void 0 ? void 0 : legacyRole.id),
|
|
191
|
+
code: `legacy-${Number(legacyRole === null || legacyRole === void 0 ? void 0 : legacyRole.id)}`,
|
|
192
|
+
name: (_b = legacyRole === null || legacyRole === void 0 ? void 0 : legacyRole.roleName) !== null && _b !== void 0 ? _b : 'Legacy access',
|
|
193
|
+
scope: 'CLIENT',
|
|
194
|
+
clientId,
|
|
195
|
+
};
|
|
196
|
+
const roles = usingLegacyCompatibility && assignments.length
|
|
197
|
+
? assignments.map((assignment) => {
|
|
198
|
+
var _a, _b, _c, _d, _e, _f;
|
|
199
|
+
return ({
|
|
200
|
+
roleId: Number(assignment.roleId || ((_a = assignment.role) === null || _a === void 0 ? void 0 : _a.id)),
|
|
201
|
+
roleName: (_b = assignment.role) === null || _b === void 0 ? void 0 : _b.roleName,
|
|
202
|
+
moduleId: Number((_d = (_c = assignment.role) === null || _c === void 0 ? void 0 : _c.module) === null || _d === void 0 ? void 0 : _d.id),
|
|
203
|
+
moduleName: (_f = (_e = assignment.role) === null || _e === void 0 ? void 0 : _e.module) === null || _f === void 0 ? void 0 : _f.moduleName,
|
|
204
|
+
});
|
|
205
|
+
})
|
|
206
|
+
: [
|
|
207
|
+
{
|
|
208
|
+
roleId: accessRole.id,
|
|
209
|
+
roleName: accessRole.name,
|
|
210
|
+
moduleId: accessRole.id,
|
|
211
|
+
moduleName: 'access-control',
|
|
212
|
+
},
|
|
213
|
+
];
|
|
149
214
|
if (roles.some((role) => !Number.isInteger(role.roleId) ||
|
|
150
215
|
role.roleId <= 0 ||
|
|
151
216
|
!role.roleName ||
|
|
@@ -154,15 +219,16 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
154
219
|
!role.moduleName)) {
|
|
155
220
|
throw new common_1.UnauthorizedException();
|
|
156
221
|
}
|
|
157
|
-
const privileges =
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
222
|
+
const privileges = usingLegacyCompatibility
|
|
223
|
+
? Array.from(new Set(assignments.flatMap((assignment) => {
|
|
224
|
+
var _a;
|
|
225
|
+
return (((_a = assignment.role) === null || _a === void 0 ? void 0 : _a.privileges) || [])
|
|
226
|
+
.map((definition) => { var _a; return (_a = definition.privilege) === null || _a === void 0 ? void 0 : _a.privilege; })
|
|
227
|
+
.filter((privilege) => Boolean(privilege));
|
|
228
|
+
}))).sort()
|
|
229
|
+
: [];
|
|
163
230
|
const identity = {
|
|
164
231
|
id: user.id,
|
|
165
|
-
homeClientId: user.clientId,
|
|
166
232
|
firstName: user.first_name,
|
|
167
233
|
username: user.username,
|
|
168
234
|
lastName: user.last_name,
|
|
@@ -177,12 +243,16 @@ let TenantAuthorizationService = TenantAuthorizationService_1 = class TenantAuth
|
|
|
177
243
|
};
|
|
178
244
|
const snapshot = {
|
|
179
245
|
userId,
|
|
180
|
-
homeClientId: user.clientId,
|
|
181
246
|
clientId,
|
|
182
247
|
clientName: client.name,
|
|
183
248
|
clientAlias: client.alias,
|
|
184
249
|
roles,
|
|
185
250
|
privileges,
|
|
251
|
+
accessRole,
|
|
252
|
+
permissions: Array.isArray(accessRow.permissions)
|
|
253
|
+
? accessRow.permissions
|
|
254
|
+
: [],
|
|
255
|
+
authzVersion: accessRow ? Number(accessRow.authzVersion) : 1,
|
|
186
256
|
identity,
|
|
187
257
|
cachedAt: new Date().toISOString(),
|
|
188
258
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const common_1 = require("@nestjs/common");
|
|
13
|
+
const tenant_constants_1 = require("./tenant.constants");
|
|
14
|
+
const tenant_authorization_service_1 = require("./tenant-authorization.service");
|
|
15
|
+
describe('TenantAuthorizationService impersonation', () => {
|
|
16
|
+
const store = {
|
|
17
|
+
get: jest.fn(),
|
|
18
|
+
set: jest.fn(),
|
|
19
|
+
delete: jest.fn(),
|
|
20
|
+
deleteMany: jest.fn(),
|
|
21
|
+
};
|
|
22
|
+
const userRepository = {};
|
|
23
|
+
const clientRepository = { findOne: jest.fn() };
|
|
24
|
+
const userRoleRepository = {};
|
|
25
|
+
const service = new tenant_authorization_service_1.TenantAuthorizationService(store, userRepository, clientRepository, userRoleRepository);
|
|
26
|
+
const origin = (permissions) => ({
|
|
27
|
+
identity: {
|
|
28
|
+
id: 1,
|
|
29
|
+
homeClientId: 2,
|
|
30
|
+
firstName: 'Root',
|
|
31
|
+
lastName: 'User',
|
|
32
|
+
},
|
|
33
|
+
snapshot: {
|
|
34
|
+
userId: 1,
|
|
35
|
+
homeClientId: 2,
|
|
36
|
+
clientId: tenant_constants_1.NEWTECH_CLIENT_ID,
|
|
37
|
+
clientName: 'Newtech',
|
|
38
|
+
clientAlias: 'newtech',
|
|
39
|
+
roles: [
|
|
40
|
+
{
|
|
41
|
+
roleId: 8,
|
|
42
|
+
roleName: 'Master Root',
|
|
43
|
+
moduleId: 8,
|
|
44
|
+
moduleName: 'access-control',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
privileges: [],
|
|
48
|
+
accessRole: {
|
|
49
|
+
id: 8,
|
|
50
|
+
code: 'master-root',
|
|
51
|
+
name: 'Master Root',
|
|
52
|
+
scope: 'CLIENT',
|
|
53
|
+
clientId: tenant_constants_1.NEWTECH_CLIENT_ID,
|
|
54
|
+
},
|
|
55
|
+
permissions,
|
|
56
|
+
authzVersion: 3,
|
|
57
|
+
identity: {
|
|
58
|
+
id: 1,
|
|
59
|
+
homeClientId: 2,
|
|
60
|
+
firstName: 'Root',
|
|
61
|
+
lastName: 'User',
|
|
62
|
+
},
|
|
63
|
+
cachedAt: new Date().toISOString(),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
jest.clearAllMocks();
|
|
68
|
+
clientRepository.findOne.mockResolvedValue({
|
|
69
|
+
id: 2,
|
|
70
|
+
name: 'Altera',
|
|
71
|
+
alias: 'altera',
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('resolves support from active Newtech when the permanent home is Altera', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
+
jest
|
|
76
|
+
.spyOn(service, 'resolve')
|
|
77
|
+
.mockResolvedValue(origin(['master.users.read']));
|
|
78
|
+
const resolved = yield service.resolveImpersonation(1, tenant_constants_1.NEWTECH_CLIENT_ID, 2, 2);
|
|
79
|
+
expect(service.resolve).toHaveBeenCalledWith(1, tenant_constants_1.NEWTECH_CLIENT_ID, 2);
|
|
80
|
+
expect(resolved.snapshot.clientId).toBe(2);
|
|
81
|
+
expect(resolved.snapshot.homeClientId).toBe(2);
|
|
82
|
+
expect(resolved.snapshot.clientName).toBe('Altera');
|
|
83
|
+
}));
|
|
84
|
+
it('rejects an origin outside Newtech', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
+
yield expect(service.resolveImpersonation(1, 2, 2, 2)).rejects.toBeInstanceOf(common_1.UnauthorizedException);
|
|
86
|
+
}));
|
|
87
|
+
it('rejects Newtech as the target', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
+
yield expect(service.resolveImpersonation(1, tenant_constants_1.NEWTECH_CLIENT_ID, 2, tenant_constants_1.NEWTECH_CLIENT_ID)).rejects.toBeInstanceOf(common_1.UnauthorizedException);
|
|
89
|
+
}));
|
|
90
|
+
it('rejects an origin without master access', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
jest.spyOn(service, 'resolve').mockResolvedValue(origin([]));
|
|
92
|
+
yield expect(service.resolveImpersonation(1, tenant_constants_1.NEWTECH_CLIENT_ID, 2, 2)).rejects.toBeInstanceOf(common_1.UnauthorizedException);
|
|
93
|
+
}));
|
|
94
|
+
it('rejects an inactive or missing target client', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
jest
|
|
96
|
+
.spyOn(service, 'resolve')
|
|
97
|
+
.mockResolvedValue(origin(['master.users.read']));
|
|
98
|
+
clientRepository.findOne.mockResolvedValue(null);
|
|
99
|
+
yield expect(service.resolveImpersonation(1, tenant_constants_1.NEWTECH_CLIENT_ID, 2, 2)).rejects.toBeInstanceOf(common_1.UnauthorizedException);
|
|
100
|
+
}));
|
|
101
|
+
});
|
|
@@ -6,18 +6,27 @@ export interface TenantRoleAuthorization {
|
|
|
6
6
|
}
|
|
7
7
|
export interface TenantAuthorizationSnapshot {
|
|
8
8
|
userId: number;
|
|
9
|
-
homeClientId: number;
|
|
10
9
|
clientId: number;
|
|
11
10
|
clientName: string;
|
|
12
11
|
clientAlias: string;
|
|
13
12
|
roles: TenantRoleAuthorization[];
|
|
14
13
|
privileges: string[];
|
|
14
|
+
accessRole: TenantAccessRoleAuthorization;
|
|
15
|
+
permissions: string[];
|
|
16
|
+
authzVersion: number;
|
|
15
17
|
identity: TenantAuthorizationIdentity;
|
|
16
18
|
cachedAt: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface TenantAccessRoleAuthorization {
|
|
22
|
+
id: number;
|
|
23
|
+
code: string;
|
|
24
|
+
name: string;
|
|
25
|
+
scope: 'GLOBAL' | 'CLIENT';
|
|
26
|
+
clientId: number | null;
|
|
17
27
|
}
|
|
18
28
|
export interface TenantAuthorizationIdentity {
|
|
19
29
|
id: number;
|
|
20
|
-
homeClientId: number;
|
|
21
30
|
firstName?: string;
|
|
22
31
|
username?: string;
|
|
23
32
|
lastName?: string;
|
|
@@ -29,6 +38,7 @@ export interface TenantAuthorizationIdentity {
|
|
|
29
38
|
passwordExpired?: number;
|
|
30
39
|
viewEvaluations?: boolean;
|
|
31
40
|
ern?: string;
|
|
41
|
+
[key: string]: unknown;
|
|
32
42
|
}
|
|
33
43
|
export interface ResolvedTenantAuthorization {
|
|
34
44
|
identity: TenantAuthorizationIdentity;
|
|
@@ -12,7 +12,6 @@ export interface TenantContextState {
|
|
|
12
12
|
}
|
|
13
13
|
export interface AuthenticatedTenantUser {
|
|
14
14
|
id: number;
|
|
15
|
-
homeClientId: number;
|
|
16
15
|
clientId: number;
|
|
17
16
|
clientAlias?: string;
|
|
18
17
|
clientName?: string;
|
|
@@ -23,6 +22,15 @@ export interface AuthenticatedTenantUser {
|
|
|
23
22
|
impersonationReason: string | null;
|
|
24
23
|
roles: string[];
|
|
25
24
|
privileges: string[];
|
|
25
|
+
role: {
|
|
26
|
+
id: number;
|
|
27
|
+
code: string;
|
|
28
|
+
name: string;
|
|
29
|
+
scope: 'GLOBAL' | 'CLIENT';
|
|
30
|
+
clientId: number | null;
|
|
31
|
+
};
|
|
32
|
+
permissions: string[];
|
|
33
|
+
authzVersion: number;
|
|
26
34
|
isMasterTenantAdmin: boolean;
|
|
27
35
|
first_name?: string;
|
|
28
36
|
username?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniorganization/uni-lib",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.5",
|
|
4
4
|
"description": "UNI Library",
|
|
5
5
|
"author": "Jhomiguel",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,6 +9,17 @@
|
|
|
9
9
|
"dist/**/*",
|
|
10
10
|
"*.md"
|
|
11
11
|
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"start:dev": "tsc -w",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"prepublishOnly": "pnpm run build",
|
|
16
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
17
|
+
"lint": "tslint -p tsconfig.json -c tslint.json",
|
|
18
|
+
"test": "jest",
|
|
19
|
+
"test:watch": "jest --watch",
|
|
20
|
+
"test:cov": "jest --coverage",
|
|
21
|
+
"test:e2e": "jest --config ./test/jest-e2e.json"
|
|
22
|
+
},
|
|
12
23
|
"dependencies": {
|
|
13
24
|
"@googlemaps/google-maps-services-js": "^3.4.2",
|
|
14
25
|
"@aws-sdk/client-s3": "^3.833.0",
|
|
@@ -71,15 +82,5 @@
|
|
|
71
82
|
},
|
|
72
83
|
"coverageDirectory": "../coverage",
|
|
73
84
|
"testEnvironment": "node"
|
|
74
|
-
},
|
|
75
|
-
"scripts": {
|
|
76
|
-
"start:dev": "tsc -w",
|
|
77
|
-
"build": "tsc",
|
|
78
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
79
|
-
"lint": "tslint -p tsconfig.json -c tslint.json",
|
|
80
|
-
"test": "jest",
|
|
81
|
-
"test:watch": "jest --watch",
|
|
82
|
-
"test:cov": "jest --coverage",
|
|
83
|
-
"test:e2e": "jest --config ./test/jest-e2e.json"
|
|
84
85
|
}
|
|
85
|
-
}
|
|
86
|
+
}
|
|
@@ -1,59 +0,0 @@
|
|
|
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.UserClientContext = void 0;
|
|
13
|
-
const typeorm_1 = require("typeorm");
|
|
14
|
-
let UserClientContext = class UserClientContext {
|
|
15
|
-
};
|
|
16
|
-
exports.UserClientContext = UserClientContext;
|
|
17
|
-
__decorate([
|
|
18
|
-
(0, typeorm_1.PrimaryColumn)({ name: 'USER_ID', type: 'numeric' }),
|
|
19
|
-
__metadata("design:type", Number)
|
|
20
|
-
], UserClientContext.prototype, "userId", void 0);
|
|
21
|
-
__decorate([
|
|
22
|
-
(0, typeorm_1.PrimaryColumn)({ name: 'client_id', type: 'integer' }),
|
|
23
|
-
__metadata("design:type", Number)
|
|
24
|
-
], UserClientContext.prototype, "clientId", void 0);
|
|
25
|
-
__decorate([
|
|
26
|
-
(0, typeorm_1.Column)({ type: 'varchar', length: 250, default: '' }),
|
|
27
|
-
__metadata("design:type", String)
|
|
28
|
-
], UserClientContext.prototype, "profile", void 0);
|
|
29
|
-
__decorate([
|
|
30
|
-
(0, typeorm_1.Column)({ type: 'varchar', length: 250, default: '' }),
|
|
31
|
-
__metadata("design:type", String)
|
|
32
|
-
], UserClientContext.prototype, "division", void 0);
|
|
33
|
-
__decorate([
|
|
34
|
-
(0, typeorm_1.Column)({ type: 'varchar', length: 250, default: '' }),
|
|
35
|
-
__metadata("design:type", String)
|
|
36
|
-
], UserClientContext.prototype, "lob", void 0);
|
|
37
|
-
__decorate([
|
|
38
|
-
(0, typeorm_1.Column)({ name: 'REPORTS_TO', type: 'numeric', nullable: true }),
|
|
39
|
-
__metadata("design:type", Number)
|
|
40
|
-
], UserClientContext.prototype, "reportsToId", void 0);
|
|
41
|
-
__decorate([
|
|
42
|
-
(0, typeorm_1.CreateDateColumn)({
|
|
43
|
-
name: 'created_at',
|
|
44
|
-
type: 'timestamptz',
|
|
45
|
-
default: () => 'CURRENT_TIMESTAMP',
|
|
46
|
-
}),
|
|
47
|
-
__metadata("design:type", Date)
|
|
48
|
-
], UserClientContext.prototype, "createdAt", void 0);
|
|
49
|
-
__decorate([
|
|
50
|
-
(0, typeorm_1.UpdateDateColumn)({
|
|
51
|
-
name: 'updated_at',
|
|
52
|
-
type: 'timestamptz',
|
|
53
|
-
default: () => 'CURRENT_TIMESTAMP',
|
|
54
|
-
}),
|
|
55
|
-
__metadata("design:type", Date)
|
|
56
|
-
], UserClientContext.prototype, "updatedAt", void 0);
|
|
57
|
-
exports.UserClientContext = UserClientContext = __decorate([
|
|
58
|
-
(0, typeorm_1.Entity)('USER_CLIENT_CONTEXT', { schema: 'stm' })
|
|
59
|
-
], UserClientContext);
|
|
@@ -1,35 +0,0 @@
|
|
|
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.MasterUsersGuard = void 0;
|
|
10
|
-
const common_1 = require("@nestjs/common");
|
|
11
|
-
const tenant_constants_1 = require("./tenant.constants");
|
|
12
|
-
let MasterUsersGuard = class MasterUsersGuard {
|
|
13
|
-
canActivate(context) {
|
|
14
|
-
var _a, _b, _c, _d, _e;
|
|
15
|
-
const request = context.switchToHttp().getRequest();
|
|
16
|
-
const user = request.user;
|
|
17
|
-
if (!user || user === true) {
|
|
18
|
-
throw new common_1.UnauthorizedException();
|
|
19
|
-
}
|
|
20
|
-
const effectiveClientId = (_b = (_a = request.tenantContext) === null || _a === void 0 ? void 0 : _a.clientId) !== null && _b !== void 0 ? _b : user.clientId;
|
|
21
|
-
const originalClientId = (_e = (_d = (_c = request.tenantContext) === null || _c === void 0 ? void 0 : _c.originalClientId) !== null && _d !== void 0 ? _d : user.originalClientId) !== null && _e !== void 0 ? _e : null;
|
|
22
|
-
const hasCapability = (user.privileges || []).some((privilege) => privilege.trim().toUpperCase() === tenant_constants_1.MASTER_USERS_ADMIN_PRIVILEGE);
|
|
23
|
-
if (effectiveClientId !== tenant_constants_1.NEWTECH_CLIENT_ID ||
|
|
24
|
-
originalClientId !== null ||
|
|
25
|
-
!user.isMasterTenantAdmin ||
|
|
26
|
-
!hasCapability) {
|
|
27
|
-
throw new common_1.ForbiddenException();
|
|
28
|
-
}
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
exports.MasterUsersGuard = MasterUsersGuard;
|
|
33
|
-
exports.MasterUsersGuard = MasterUsersGuard = __decorate([
|
|
34
|
-
(0, common_1.Injectable)()
|
|
35
|
-
], MasterUsersGuard);
|