@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.
Files changed (90) hide show
  1. package/dist/entities/bp-alerts.entity.d.ts +2 -2
  2. package/dist/entities/bp-alerts.entity.js +4 -4
  3. package/dist/entities/business-schedule.entity.d.ts +2 -2
  4. package/dist/entities/business-schedule.entity.js +4 -4
  5. package/dist/entities/call-driver-data.entity.d.ts +2 -2
  6. package/dist/entities/call-driver-data.entity.js +4 -4
  7. package/dist/entities/call-drivers.entity.d.ts +1 -1
  8. package/dist/entities/call-drivers.entity.js +2 -2
  9. package/dist/entities/cb-completed-reasons.entity.d.ts +1 -1
  10. package/dist/entities/cb-completed-reasons.entity.js +2 -2
  11. package/dist/entities/claim-report.entity.d.ts +2 -2
  12. package/dist/entities/claim-report.entity.js +4 -4
  13. package/dist/entities/daily-payment.entity.d.ts +58 -0
  14. package/dist/entities/daily-payment.entity.js +248 -0
  15. package/dist/entities/dispute-request.entity.d.ts +2 -2
  16. package/dist/entities/dispute-request.entity.js +4 -4
  17. package/dist/entities/division.entity.d.ts +11 -0
  18. package/dist/entities/division.entity.js +52 -0
  19. package/dist/entities/enr-inventory.entity.d.ts +2 -2
  20. package/dist/entities/enr-inventory.entity.js +4 -4
  21. package/dist/entities/enr-results.entity.d.ts +1 -1
  22. package/dist/entities/enr-results.entity.js +2 -2
  23. package/dist/entities/escalations.entity.d.ts +2 -2
  24. package/dist/entities/escalations.entity.js +4 -4
  25. package/dist/entities/evaluation-forms.entity.d.ts +4 -4
  26. package/dist/entities/evaluations.entity.d.ts +2 -2
  27. package/dist/entities/evaluations.entity.js +4 -4
  28. package/dist/entities/form-fields.entity.d.ts +2 -2
  29. package/dist/entities/form-fields.entity.js +4 -4
  30. package/dist/entities/form.entity.d.ts +2 -2
  31. package/dist/entities/form.entity.js +4 -4
  32. package/dist/entities/inbox/message-case.entity.d.ts +2 -2
  33. package/dist/entities/inbox/message-case.entity.js +6 -8
  34. package/dist/entities/inbox/sla-policy.entity.d.ts +2 -2
  35. package/dist/entities/inbox/sla-policy.entity.js +4 -4
  36. package/dist/entities/index.d.ts +3 -0
  37. package/dist/entities/index.js +3 -0
  38. package/dist/entities/inventory.entity.d.ts +1 -1
  39. package/dist/entities/inventory.entity.js +2 -2
  40. package/dist/entities/lob-assignment.entity.d.ts +1 -1
  41. package/dist/entities/lob-assignment.entity.js +2 -2
  42. package/dist/entities/lob-call-drivers.entity.d.ts +1 -1
  43. package/dist/entities/lob-call-drivers.entity.js +2 -2
  44. package/dist/entities/lob.entity.d.ts +14 -0
  45. package/dist/entities/lob.entity.js +65 -0
  46. package/dist/entities/offphone-activities.entity.d.ts +1 -1
  47. package/dist/entities/offphone-activities.entity.js +2 -2
  48. package/dist/entities/otwe-offers.entity.d.ts +1 -1
  49. package/dist/entities/otwe-offers.entity.js +2 -2
  50. package/dist/entities/outbound-ticket-history.entity.d.ts +2 -2
  51. package/dist/entities/outbound-ticket-history.entity.js +4 -4
  52. package/dist/entities/pending-ticket-history.entity.d.ts +2 -2
  53. package/dist/entities/pending-ticket-history.entity.js +4 -4
  54. package/dist/entities/raw_roster.entity.d.ts +2 -2
  55. package/dist/entities/raw_roster.entity.js +4 -4
  56. package/dist/entities/roster.entity.d.ts +2 -2
  57. package/dist/entities/roster.entity.js +4 -4
  58. package/dist/entities/skipped-ticket.entity.d.ts +2 -2
  59. package/dist/entities/skipped-ticket.entity.js +4 -4
  60. package/dist/entities/template.entity.d.ts +2 -2
  61. package/dist/entities/template.entity.js +4 -4
  62. package/dist/entities/ticket-queue.entity.d.ts +2 -2
  63. package/dist/entities/ticket-queue.entity.js +4 -4
  64. package/dist/entities/user-roster.view.d.ts +2 -2
  65. package/dist/entities/user-roster.view.js +4 -4
  66. package/dist/entities/users-lobs.entity.d.ts +11 -0
  67. package/dist/entities/users-lobs.entity.js +57 -0
  68. package/dist/entities/usr.entity.d.ts +4 -2
  69. package/dist/entities/usr.entity.js +22 -14
  70. package/dist/entities/vw-escalation-age.d.ts +2 -0
  71. package/dist/entities/vw-escalation-age.js +8 -0
  72. package/dist/middlewares/index.d.ts +1 -0
  73. package/dist/middlewares/index.js +17 -0
  74. package/dist/middlewares/version-checker.middleware.d.ts +2 -0
  75. package/dist/middlewares/version-checker.middleware.js +27 -0
  76. package/dist/modules/common/jwt.strategy.js +8 -9
  77. package/dist/modules/common/jwt.strategy.spec.d.ts +1 -0
  78. package/dist/modules/common/jwt.strategy.spec.js +89 -0
  79. package/dist/modules/tenant/redis-tenant-state.store.js +10 -3
  80. package/dist/modules/tenant/tenant-authorization.service.d.ts +2 -2
  81. package/dist/modules/tenant/tenant-authorization.service.js +105 -35
  82. package/dist/modules/tenant/tenant-authorization.service.spec.d.ts +1 -0
  83. package/dist/modules/tenant/tenant-authorization.service.spec.js +101 -0
  84. package/dist/modules/tenant/tenant-authorization.types.d.ts +12 -2
  85. package/dist/modules/tenant/tenant.types.d.ts +9 -1
  86. package/package.json +13 -12
  87. package/dist/entities/user-client-context.entity.d.ts +0 -10
  88. package/dist/entities/user-client-context.entity.js +0 -59
  89. package/dist/modules/tenant/master-users.guard.d.ts +0 -4
  90. 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
- division: string;
65
+ divisionId: string | null;
66
66
  mainLine: string;
67
- lob: string;
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: 'division', type: 'text' }),
270
+ (0, typeorm_1.Column)({ name: 'division_id', type: 'bigint', nullable: true }),
271
271
  __metadata("design:type", String)
272
- ], VwUserRoster.prototype, "division", void 0);
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: 'lob', type: 'text' }),
278
+ (0, typeorm_1.Column)({ name: 'lob_id', type: 'bigint', nullable: true }),
279
279
  __metadata("design:type", String)
280
- ], VwUserRoster.prototype, "lob", void 0);
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,11 @@
1
+ import { Lob } from './lob.entity';
2
+ import { Users } from './usr.entity';
3
+ export declare class UsersLobs {
4
+ clientId: number;
5
+ userId: number;
6
+ lobId: string;
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ user: Users;
10
+ lob: Lob;
11
+ }
@@ -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
- calculateFullName(): void;
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
- calculateFullName() {
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, "calculateFullName", null);
130
+ ], Users.prototype, "applyDerivedScope", null);
123
131
  exports.Users = Users = __decorate([
124
132
  (0, typeorm_1.Entity)('USERS')
125
133
  ], Users);
@@ -4,6 +4,8 @@ export declare class VwEscalationAge {
4
4
  category: string;
5
5
  division: string;
6
6
  lob: string;
7
+ divisionId: string | null;
8
+ lobId: string | null;
7
9
  escalationStatus: string;
8
10
  zeroToThree: number;
9
11
  fourToSeven: number;
@@ -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,2 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare function versionChecker(req: Request, res: Response, next: NextFunction): Promise<Response<any, Record<string, any>>>;
@@ -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, homeClientId, effectiveClientId)
75
- : yield this.authorization.resolve(signedUser.id, effectiveClientId, homeClientId);
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.roles.some((role) => role.moduleName.toLowerCase() === 'root' &&
80
- role.roleName.toLowerCase() === 'sysadmin');
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, expectedHomeClientId: number): Promise<ResolvedTenantAuthorization>;
16
- resolveImpersonation(userId: number, homeClientId: number, targetClientId: number): Promise<ResolvedTenantAuthorization>;
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;