@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
|
@@ -62,9 +62,9 @@ export declare class VwUserRoster {
|
|
|
62
62
|
phoenixId: string;
|
|
63
63
|
five9Id: string;
|
|
64
64
|
communityWfmId: string;
|
|
65
|
-
|
|
65
|
+
divisionId: string | null;
|
|
66
66
|
mainLine: string;
|
|
67
|
-
|
|
67
|
+
lobId: string | null;
|
|
68
68
|
employeeRole: string;
|
|
69
69
|
sector: string;
|
|
70
70
|
sprinklrId: string;
|
|
@@ -267,17 +267,17 @@ __decorate([
|
|
|
267
267
|
__metadata("design:type", String)
|
|
268
268
|
], VwUserRoster.prototype, "communityWfmId", void 0);
|
|
269
269
|
__decorate([
|
|
270
|
-
(0, typeorm_1.Column)({ name: '
|
|
270
|
+
(0, typeorm_1.Column)({ name: 'division_id', type: 'bigint', nullable: true }),
|
|
271
271
|
__metadata("design:type", String)
|
|
272
|
-
], VwUserRoster.prototype, "
|
|
272
|
+
], VwUserRoster.prototype, "divisionId", void 0);
|
|
273
273
|
__decorate([
|
|
274
274
|
(0, typeorm_1.Column)({ name: 'main_line', type: 'text' }),
|
|
275
275
|
__metadata("design:type", String)
|
|
276
276
|
], VwUserRoster.prototype, "mainLine", void 0);
|
|
277
277
|
__decorate([
|
|
278
|
-
(0, typeorm_1.Column)({ name: '
|
|
278
|
+
(0, typeorm_1.Column)({ name: 'lob_id', type: 'bigint', nullable: true }),
|
|
279
279
|
__metadata("design:type", String)
|
|
280
|
-
], VwUserRoster.prototype, "
|
|
280
|
+
], VwUserRoster.prototype, "lobId", void 0);
|
|
281
281
|
__decorate([
|
|
282
282
|
(0, typeorm_1.Column)({ name: 'employee_role', type: 'text' }),
|
|
283
283
|
__metadata("design:type", String)
|
|
@@ -0,0 +1,57 @@
|
|
|
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.UsersLobs = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const lob_entity_1 = require("./lob.entity");
|
|
15
|
+
const usr_entity_1 = require("./usr.entity");
|
|
16
|
+
let UsersLobs = class UsersLobs {
|
|
17
|
+
};
|
|
18
|
+
exports.UsersLobs = UsersLobs;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, typeorm_1.PrimaryColumn)({ name: 'client_id', type: 'integer' }),
|
|
21
|
+
__metadata("design:type", Number)
|
|
22
|
+
], UsersLobs.prototype, "clientId", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, typeorm_1.PrimaryColumn)({ name: 'user_id', type: 'numeric' }),
|
|
25
|
+
__metadata("design:type", Number)
|
|
26
|
+
], UsersLobs.prototype, "userId", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, typeorm_1.PrimaryColumn)({ name: 'lob_id', type: 'bigint' }),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], UsersLobs.prototype, "lobId", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, typeorm_1.CreateDateColumn)({ name: 'created_at', type: 'timestamptz' }),
|
|
33
|
+
__metadata("design:type", Date)
|
|
34
|
+
], UsersLobs.prototype, "createdAt", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, typeorm_1.UpdateDateColumn)({ name: 'updated_at', type: 'timestamptz' }),
|
|
37
|
+
__metadata("design:type", Date)
|
|
38
|
+
], UsersLobs.prototype, "updatedAt", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, typeorm_1.ManyToOne)(() => usr_entity_1.Users, (user) => user.usersLobs, { onDelete: 'CASCADE' }),
|
|
41
|
+
(0, typeorm_1.JoinColumn)([
|
|
42
|
+
{ name: 'user_id', referencedColumnName: 'id' },
|
|
43
|
+
{ name: 'client_id', referencedColumnName: 'clientId' },
|
|
44
|
+
]),
|
|
45
|
+
__metadata("design:type", usr_entity_1.Users)
|
|
46
|
+
], UsersLobs.prototype, "user", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, typeorm_1.ManyToOne)(() => lob_entity_1.Lob, (lob) => lob.userLobs),
|
|
49
|
+
(0, typeorm_1.JoinColumn)([
|
|
50
|
+
{ name: 'lob_id', referencedColumnName: 'id' },
|
|
51
|
+
{ name: 'client_id', referencedColumnName: 'clientId' },
|
|
52
|
+
]),
|
|
53
|
+
__metadata("design:type", lob_entity_1.Lob)
|
|
54
|
+
], UsersLobs.prototype, "lob", void 0);
|
|
55
|
+
exports.UsersLobs = UsersLobs = __decorate([
|
|
56
|
+
(0, typeorm_1.Entity)('users_lobs', { schema: 'stm' })
|
|
57
|
+
], UsersLobs);
|
|
@@ -2,8 +2,8 @@ import { Timestamp } from 'typeorm';
|
|
|
2
2
|
import { UserCampaign } from './user-campaign.entity';
|
|
3
3
|
import { UserRoles } from './user-roles.entity';
|
|
4
4
|
import { RawRoster } from './raw_roster.entity';
|
|
5
|
+
import { UsersLobs } from './users-lobs.entity';
|
|
5
6
|
export declare class Users {
|
|
6
|
-
clientId: number;
|
|
7
7
|
id: number;
|
|
8
8
|
username: string;
|
|
9
9
|
password: string;
|
|
@@ -25,6 +25,8 @@ export declare class Users {
|
|
|
25
25
|
reportsTo: Users;
|
|
26
26
|
userCampaigns: UserCampaign[];
|
|
27
27
|
rawRoster: RawRoster;
|
|
28
|
+
usersLobs: UsersLobs[];
|
|
28
29
|
fullName: string;
|
|
29
|
-
|
|
30
|
+
applyDerivedScope(): void;
|
|
31
|
+
private firstLobDivision;
|
|
30
32
|
}
|
|
@@ -14,16 +14,28 @@ const typeorm_1 = require("typeorm");
|
|
|
14
14
|
const user_campaign_entity_1 = require("./user-campaign.entity");
|
|
15
15
|
const user_roles_entity_1 = require("./user-roles.entity");
|
|
16
16
|
const raw_roster_entity_1 = require("./raw_roster.entity");
|
|
17
|
+
const users_lobs_entity_1 = require("./users-lobs.entity");
|
|
17
18
|
let Users = class Users {
|
|
18
|
-
|
|
19
|
+
applyDerivedScope() {
|
|
20
|
+
var _a;
|
|
19
21
|
this.fullName = `${this.first_name} ${this.last_name}`;
|
|
22
|
+
const lobNames = ((_a = this.usersLobs) !== null && _a !== void 0 ? _a : [])
|
|
23
|
+
.map((assignment) => { var _a; return (_a = assignment.lob) === null || _a === void 0 ? void 0 : _a.name; })
|
|
24
|
+
.filter((name) => Boolean(name))
|
|
25
|
+
.sort((a, b) => a.localeCompare(b));
|
|
26
|
+
this.lob = lobNames.join(',');
|
|
27
|
+
this.division = lobNames.length > 0 ? this.firstLobDivision() : '';
|
|
28
|
+
}
|
|
29
|
+
firstLobDivision() {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const divisions = ((_a = this.usersLobs) !== null && _a !== void 0 ? _a : [])
|
|
32
|
+
.map((assignment) => { var _a, _b; return (_b = (_a = assignment.lob) === null || _a === void 0 ? void 0 : _a.division) === null || _b === void 0 ? void 0 : _b.name; })
|
|
33
|
+
.filter((name) => Boolean(name))
|
|
34
|
+
.sort((a, b) => a.localeCompare(b));
|
|
35
|
+
return (_b = divisions[0]) !== null && _b !== void 0 ? _b : '';
|
|
20
36
|
}
|
|
21
37
|
};
|
|
22
38
|
exports.Users = Users;
|
|
23
|
-
__decorate([
|
|
24
|
-
(0, typeorm_1.Column)({ name: 'client_id', type: 'integer' }),
|
|
25
|
-
__metadata("design:type", Number)
|
|
26
|
-
], Users.prototype, "clientId", void 0);
|
|
27
39
|
__decorate([
|
|
28
40
|
(0, typeorm_1.PrimaryGeneratedColumn)({ name: 'ID' }),
|
|
29
41
|
__metadata("design:type", Number)
|
|
@@ -72,14 +84,6 @@ __decorate([
|
|
|
72
84
|
(0, typeorm_1.Column)({ length: 250, name: 'ntgid' }),
|
|
73
85
|
__metadata("design:type", String)
|
|
74
86
|
], Users.prototype, "ntgid", void 0);
|
|
75
|
-
__decorate([
|
|
76
|
-
(0, typeorm_1.Column)({ length: 250, name: 'lob' }),
|
|
77
|
-
__metadata("design:type", String)
|
|
78
|
-
], Users.prototype, "lob", void 0);
|
|
79
|
-
__decorate([
|
|
80
|
-
(0, typeorm_1.Column)({ length: 250, name: 'division' }),
|
|
81
|
-
__metadata("design:type", String)
|
|
82
|
-
], Users.prototype, "division", void 0);
|
|
83
87
|
__decorate([
|
|
84
88
|
(0, typeorm_1.Column)({ length: 250, name: 'profile' }),
|
|
85
89
|
__metadata("design:type", String)
|
|
@@ -114,12 +118,16 @@ __decorate([
|
|
|
114
118
|
(0, typeorm_1.OneToOne)(() => raw_roster_entity_1.RawRoster, (rawRoster) => rawRoster.user),
|
|
115
119
|
__metadata("design:type", raw_roster_entity_1.RawRoster)
|
|
116
120
|
], Users.prototype, "rawRoster", void 0);
|
|
121
|
+
__decorate([
|
|
122
|
+
(0, typeorm_1.OneToMany)(() => users_lobs_entity_1.UsersLobs, (usersLobs) => usersLobs.user),
|
|
123
|
+
__metadata("design:type", Array)
|
|
124
|
+
], Users.prototype, "usersLobs", void 0);
|
|
117
125
|
__decorate([
|
|
118
126
|
(0, typeorm_1.AfterLoad)(),
|
|
119
127
|
__metadata("design:type", Function),
|
|
120
128
|
__metadata("design:paramtypes", []),
|
|
121
129
|
__metadata("design:returntype", void 0)
|
|
122
|
-
], Users.prototype, "
|
|
130
|
+
], Users.prototype, "applyDerivedScope", null);
|
|
123
131
|
exports.Users = Users = __decorate([
|
|
124
132
|
(0, typeorm_1.Entity)('USERS')
|
|
125
133
|
], Users);
|
|
@@ -34,6 +34,14 @@ __decorate([
|
|
|
34
34
|
(0, typeorm_1.ViewColumn)(),
|
|
35
35
|
__metadata("design:type", String)
|
|
36
36
|
], VwEscalationAge.prototype, "lob", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, typeorm_1.ViewColumn)({ name: 'division_id' }),
|
|
39
|
+
__metadata("design:type", String)
|
|
40
|
+
], VwEscalationAge.prototype, "divisionId", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, typeorm_1.ViewColumn)({ name: 'lob_id' }),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], VwEscalationAge.prototype, "lobId", void 0);
|
|
37
45
|
__decorate([
|
|
38
46
|
(0, typeorm_1.ViewColumn)(),
|
|
39
47
|
__metadata("design:type", String)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './version-checker.middleware';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./version-checker.middleware"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
exports.versionChecker = versionChecker;
|
|
13
|
+
const fs = require("fs/promises");
|
|
14
|
+
const path = require("path");
|
|
15
|
+
function versionChecker(req, res, next) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const version = (yield fs.readFile(path.join(process.cwd(), 'app-version.txt')))
|
|
18
|
+
.toString()
|
|
19
|
+
.trim();
|
|
20
|
+
if (req.headers['app-version'] !== version)
|
|
21
|
+
return res.status(409).json({
|
|
22
|
+
message: `You need to update the application version to ${version}`,
|
|
23
|
+
status: 409,
|
|
24
|
+
});
|
|
25
|
+
next();
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -38,7 +38,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
38
38
|
var _a, _b, _c;
|
|
39
39
|
const signedUser = payload === null || payload === void 0 ? void 0 : payload.user;
|
|
40
40
|
const effectiveClientId = Number(signedUser === null || signedUser === void 0 ? void 0 : signedUser.clientId);
|
|
41
|
-
const homeClientId = Number(signedUser === null || signedUser === void 0 ? void 0 : signedUser.homeClientId);
|
|
42
41
|
const originalClientId = (_a = signedUser === null || signedUser === void 0 ? void 0 : signedUser.originalClientId) !== null && _a !== void 0 ? _a : null;
|
|
43
42
|
const now = Math.floor(Date.now() / 1000);
|
|
44
43
|
if ((payload === null || payload === void 0 ? void 0 : payload.type) !== 'access' ||
|
|
@@ -47,8 +46,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
47
46
|
String(signedUser.id) !== payload.sub ||
|
|
48
47
|
!Number.isInteger(effectiveClientId) ||
|
|
49
48
|
effectiveClientId <= 0 ||
|
|
50
|
-
!Number.isInteger(homeClientId) ||
|
|
51
|
-
homeClientId <= 0 ||
|
|
52
49
|
!Number.isInteger(payload.exp) ||
|
|
53
50
|
payload.exp <= now ||
|
|
54
51
|
!this.validTokenIdentifier(payload.jti) ||
|
|
@@ -62,7 +59,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
62
59
|
const impersonating = originalClientId !== null;
|
|
63
60
|
if ((impersonating &&
|
|
64
61
|
(originalClientId !== tenant_1.NEWTECH_CLIENT_ID ||
|
|
65
|
-
homeClientId !== tenant_1.NEWTECH_CLIENT_ID ||
|
|
66
62
|
effectiveClientId === tenant_1.NEWTECH_CLIENT_ID ||
|
|
67
63
|
!((_b = signedUser.roles) === null || _b === void 0 ? void 0 : _b.includes(tenant_1.TENANT_IMPERSONATOR_ROLE)) ||
|
|
68
64
|
!signedUser.impersonatedAt ||
|
|
@@ -71,13 +67,14 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
71
67
|
throw new common_1.UnauthorizedException();
|
|
72
68
|
}
|
|
73
69
|
const resolved = impersonating
|
|
74
|
-
? yield this.authorization.resolveImpersonation(signedUser.id,
|
|
75
|
-
: yield this.authorization.resolve(signedUser.id, effectiveClientId
|
|
70
|
+
? yield this.authorization.resolveImpersonation(signedUser.id, originalClientId, effectiveClientId)
|
|
71
|
+
: yield this.authorization.resolve(signedUser.id, effectiveClientId);
|
|
76
72
|
const { identity, snapshot } = resolved;
|
|
77
73
|
const isMasterTenantAdmin = !impersonating &&
|
|
78
74
|
snapshot.clientId === tenant_1.NEWTECH_CLIENT_ID &&
|
|
79
|
-
snapshot.
|
|
80
|
-
role.
|
|
75
|
+
(snapshot.permissions.includes('master.users.read') ||
|
|
76
|
+
snapshot.roles.some((role) => role.moduleName.toLowerCase() === 'root' &&
|
|
77
|
+
role.roleName.toLowerCase() === 'sysadmin'));
|
|
81
78
|
return {
|
|
82
79
|
id: identity.id,
|
|
83
80
|
first_name: identity.firstName,
|
|
@@ -91,7 +88,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
91
88
|
password_expired: identity.passwordExpired,
|
|
92
89
|
viewEvaluations: identity.viewEvaluations,
|
|
93
90
|
ern: identity.ern,
|
|
94
|
-
homeClientId: identity.homeClientId,
|
|
95
91
|
clientId: snapshot.clientId,
|
|
96
92
|
clientAlias: snapshot.clientAlias,
|
|
97
93
|
clientName: snapshot.clientName,
|
|
@@ -104,6 +100,9 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
104
100
|
: null,
|
|
105
101
|
roles: Array.from(new Set(snapshot.roles.map((role) => role.roleName))),
|
|
106
102
|
privileges: snapshot.privileges,
|
|
103
|
+
role: snapshot.accessRole,
|
|
104
|
+
permissions: snapshot.permissions,
|
|
105
|
+
authzVersion: snapshot.authzVersion,
|
|
107
106
|
isMasterTenantAdmin,
|
|
108
107
|
};
|
|
109
108
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
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_1 = require("../tenant");
|
|
14
|
+
const jwt_strategy_1 = require("./jwt.strategy");
|
|
15
|
+
describe('JwtStrategy impersonated sessions', () => {
|
|
16
|
+
process.env.JWT_SECRET = 'test-secret';
|
|
17
|
+
const authorization = { resolveImpersonation: jest.fn() };
|
|
18
|
+
const securityState = { isAccessTokenRevoked: jest.fn() };
|
|
19
|
+
const strategy = new jwt_strategy_1.JwtStrategy(authorization, securityState);
|
|
20
|
+
const payload = (overrides = {}) => {
|
|
21
|
+
const now = Math.floor(Date.now() / 1000);
|
|
22
|
+
const expiresAt = now + 900;
|
|
23
|
+
const user = Object.assign({ id: 1, homeClientId: 2, clientId: 2, clientName: 'Altera', clientAlias: 'altera', jti: 'impersonated-jti', tokenExpiresAt: expiresAt, originalClientId: tenant_1.NEWTECH_CLIENT_ID, impersonatedAt: new Date().toISOString(), impersonationReason: 'Investigate issue', roles: [tenant_1.TENANT_IMPERSONATOR_ROLE], privileges: [], role: {
|
|
24
|
+
id: 0,
|
|
25
|
+
code: tenant_1.TENANT_IMPERSONATOR_ROLE,
|
|
26
|
+
name: 'Tenant impersonator',
|
|
27
|
+
scope: 'GLOBAL',
|
|
28
|
+
clientId: null,
|
|
29
|
+
}, permissions: [], authzVersion: 1, isMasterTenantAdmin: false }, overrides);
|
|
30
|
+
return {
|
|
31
|
+
type: 'access',
|
|
32
|
+
user,
|
|
33
|
+
sub: '1',
|
|
34
|
+
iat: now - 10,
|
|
35
|
+
exp: expiresAt,
|
|
36
|
+
jti: 'impersonated-jti',
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
jest.clearAllMocks();
|
|
41
|
+
securityState.isAccessTokenRevoked.mockResolvedValue(false);
|
|
42
|
+
authorization.resolveImpersonation.mockResolvedValue({
|
|
43
|
+
identity: { id: 1, homeClientId: 2 },
|
|
44
|
+
snapshot: {
|
|
45
|
+
userId: 1,
|
|
46
|
+
homeClientId: 2,
|
|
47
|
+
clientId: 2,
|
|
48
|
+
clientName: 'Altera',
|
|
49
|
+
clientAlias: 'altera',
|
|
50
|
+
roles: [
|
|
51
|
+
{
|
|
52
|
+
roleId: 0,
|
|
53
|
+
roleName: tenant_1.TENANT_IMPERSONATOR_ROLE,
|
|
54
|
+
moduleId: 0,
|
|
55
|
+
moduleName: tenant_1.TENANT_IMPERSONATOR_ROLE,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
privileges: [],
|
|
59
|
+
accessRole: {
|
|
60
|
+
id: 0,
|
|
61
|
+
code: tenant_1.TENANT_IMPERSONATOR_ROLE,
|
|
62
|
+
name: 'Tenant impersonator',
|
|
63
|
+
scope: 'GLOBAL',
|
|
64
|
+
clientId: null,
|
|
65
|
+
},
|
|
66
|
+
permissions: [],
|
|
67
|
+
authzVersion: 1,
|
|
68
|
+
identity: { id: 1, homeClientId: 2 },
|
|
69
|
+
cachedAt: new Date().toISOString(),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('revalidates an impersonated token with an Altera home client through Newtech', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const validated = yield strategy.validate(payload());
|
|
75
|
+
expect(authorization.resolveImpersonation).toHaveBeenCalledWith(1, 1, 2, 2);
|
|
76
|
+
expect(validated.homeClientId).toBe(2);
|
|
77
|
+
expect(validated.clientId).toBe(2);
|
|
78
|
+
expect(validated.originalClientId).toBe(tenant_1.NEWTECH_CLIENT_ID);
|
|
79
|
+
}));
|
|
80
|
+
const invalidTokenCases = [
|
|
81
|
+
[{ originalClientId: 2 }, 'a non-Newtech origin'],
|
|
82
|
+
[{ roles: [] }, 'a token without the impersonator role'],
|
|
83
|
+
[{ impersonationReason: null }, 'a token without a support reason'],
|
|
84
|
+
];
|
|
85
|
+
it.each(invalidTokenCases)('rejects %s', (overrides) => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
yield expect(strategy.validate(payload(overrides))).rejects.toBeInstanceOf(common_1.UnauthorizedException);
|
|
87
|
+
expect(authorization.resolveImpersonation).not.toHaveBeenCalled();
|
|
88
|
+
}));
|
|
89
|
+
});
|
|
@@ -138,8 +138,6 @@ let RedisTenantStateStore = RedisTenantStateStore_1 = class RedisTenantStateStor
|
|
|
138
138
|
return Boolean(value &&
|
|
139
139
|
Number.isInteger(value.userId) &&
|
|
140
140
|
value.userId > 0 &&
|
|
141
|
-
Number.isInteger(value.homeClientId) &&
|
|
142
|
-
value.homeClientId > 0 &&
|
|
143
141
|
Number.isInteger(value.clientId) &&
|
|
144
142
|
value.clientId > 0 &&
|
|
145
143
|
typeof value.clientName === 'string' &&
|
|
@@ -154,8 +152,17 @@ let RedisTenantStateStore = RedisTenantStateStore_1 = class RedisTenantStateStor
|
|
|
154
152
|
typeof role.moduleName === 'string') &&
|
|
155
153
|
Array.isArray(value.privileges) &&
|
|
156
154
|
value.privileges.every((privilege) => typeof privilege === 'string') &&
|
|
155
|
+
value.accessRole &&
|
|
156
|
+
Number.isInteger(value.accessRole.id) &&
|
|
157
|
+
value.accessRole.id >= 0 &&
|
|
158
|
+
typeof value.accessRole.code === 'string' &&
|
|
159
|
+
typeof value.accessRole.name === 'string' &&
|
|
160
|
+
['GLOBAL', 'CLIENT'].includes(value.accessRole.scope) &&
|
|
161
|
+
Array.isArray(value.permissions) &&
|
|
162
|
+
value.permissions.every((permission) => typeof permission === 'string') &&
|
|
163
|
+
Number.isInteger(value.authzVersion) &&
|
|
164
|
+
value.authzVersion > 0 &&
|
|
157
165
|
((_a = value.identity) === null || _a === void 0 ? void 0 : _a.id) === value.userId &&
|
|
158
|
-
value.identity.homeClientId === value.homeClientId &&
|
|
159
166
|
typeof value.cachedAt === 'string');
|
|
160
167
|
}
|
|
161
168
|
};
|
|
@@ -12,8 +12,8 @@ export declare class TenantAuthorizationService {
|
|
|
12
12
|
private readonly userRoleRepository;
|
|
13
13
|
private readonly logger;
|
|
14
14
|
constructor(store: TenantAuthorizationStore, userRepository: Repository<Users>, clientRepository: Repository<Client>, userRoleRepository: Repository<UserRoles>);
|
|
15
|
-
resolve(userId: number, clientId: number,
|
|
16
|
-
resolveImpersonation(userId: number,
|
|
15
|
+
resolve(userId: number, clientId: number, _legacyOriginClientId?: number): Promise<ResolvedTenantAuthorization>;
|
|
16
|
+
resolveImpersonation(userId: number, originClientId: number, targetClientIdOrLegacyOriginClientId: number, legacyTargetClientId?: number): Promise<ResolvedTenantAuthorization>;
|
|
17
17
|
invalidate(userId: number, clientId: number): Promise<void>;
|
|
18
18
|
invalidateMany(clientId: number, userIds: readonly number[]): Promise<void>;
|
|
19
19
|
private loadFromDatabase;
|