@tomei/sso 0.34.2 → 0.34.6

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.
@@ -0,0 +1,1617 @@
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.User = void 0;
13
+ const general_1 = require("@tomei/general");
14
+ const user_repository_1 = require("./user.repository");
15
+ const system_repository_1 = require("../system/system.repository");
16
+ const login_history_repository_1 = require("../login-history/login-history.repository");
17
+ const password_hash_service_1 = require("../password-hash/password-hash.service");
18
+ const user_group_repository_1 = require("../user-group/user-group.repository");
19
+ const staff_entity_1 = require("../../models/staff.entity");
20
+ const system_privilege_entity_1 = require("../../models/system-privilege.entity");
21
+ const yn_enum_1 = require("../../enum/yn.enum");
22
+ const enum_1 = require("../../enum");
23
+ const config_1 = require("@tomei/config");
24
+ const sequelize_1 = require("sequelize");
25
+ const activity_history_1 = require("@tomei/activity-history");
26
+ const user_entity_1 = require("../../models/user.entity");
27
+ const group_entity_1 = require("../../models/group.entity");
28
+ const group_system_access_repository_1 = require("../group-system-access/group-system-access.repository");
29
+ const group_repository_1 = require("../group/group.repository");
30
+ const system_entity_1 = require("../../models/system.entity");
31
+ const user_system_access_repository_1 = require("../user-system-access/user-system-access.repository");
32
+ const group_system_access_entity_1 = require("../../models/group-system-access.entity");
33
+ const user_privilege_repository_1 = require("../user-privilege/user-privilege.repository");
34
+ const user_object_privilege_repository_1 = require("../user-object-privilege/user-object-privilege.repository");
35
+ const group_privilege_entity_1 = require("../../models/group-privilege.entity");
36
+ const group_object_privilege_repository_1 = require("../group-object-privilege/group-object-privilege.repository");
37
+ const speakeasy = require("speakeasy");
38
+ const login_status_enum_1 = require("../../enum/login-status.enum");
39
+ const redis_service_1 = require("../../redis-client/redis.service");
40
+ const login_user_1 = require("./login-user");
41
+ class User extends general_1.UserBase {
42
+ get SessionService() {
43
+ return this._SessionService;
44
+ }
45
+ get UserId() {
46
+ return parseInt(this.ObjectId);
47
+ }
48
+ set UserId(value) {
49
+ this.ObjectId = value.toString();
50
+ }
51
+ get Password() {
52
+ return this._Password;
53
+ }
54
+ set Password(value) {
55
+ this._Password = value;
56
+ }
57
+ get Status() {
58
+ return this._Status;
59
+ }
60
+ set Status(value) {
61
+ this._Status = value;
62
+ }
63
+ get UserName() {
64
+ return this._UserName;
65
+ }
66
+ set UserName(value) {
67
+ this._UserName = value;
68
+ }
69
+ get DefaultPasswordChangedYN() {
70
+ return this._DefaultPasswordChangedYN;
71
+ }
72
+ set DefaultPasswordChangedYN(value) {
73
+ this._DefaultPasswordChangedYN = value;
74
+ }
75
+ get FirstLoginAt() {
76
+ return this._FirstLoginAt;
77
+ }
78
+ set FirstLoginAt(value) {
79
+ this._FirstLoginAt = value;
80
+ }
81
+ get LastLoginAt() {
82
+ return this._LastLoginAt;
83
+ }
84
+ set LastLoginAt(value) {
85
+ this._LastLoginAt = value;
86
+ }
87
+ get MFAEnabled() {
88
+ return this._MFAEnabled;
89
+ }
90
+ set MFAEnabled(value) {
91
+ this._MFAEnabled = value;
92
+ }
93
+ get MFAConfig() {
94
+ return this._MFAConfig;
95
+ }
96
+ set MFAConfig(value) {
97
+ this._MFAConfig = value;
98
+ }
99
+ get RecoveryEmail() {
100
+ return this._RecoveryEmail;
101
+ }
102
+ set RecoveryEmail(value) {
103
+ this._RecoveryEmail = value;
104
+ }
105
+ get FailedLoginAttemptCount() {
106
+ return this._FailedLoginAttemptCount;
107
+ }
108
+ set FailedLoginAttemptCount(value) {
109
+ this._FailedLoginAttemptCount = value;
110
+ }
111
+ get LastFailedLoginAt() {
112
+ return this._LastFailedLoginAt;
113
+ }
114
+ set LastFailedLoginAt(value) {
115
+ this._LastFailedLoginAt = value;
116
+ }
117
+ get LastPasswordChangedAt() {
118
+ return this._LastPasswordChangedAt;
119
+ }
120
+ set LastPasswordChangedAt(value) {
121
+ this._LastPasswordChangedAt = value;
122
+ }
123
+ get NeedToChangePasswordYN() {
124
+ return this._NeedToChangePasswordYN;
125
+ }
126
+ set NeedToChangePasswordYN(value) {
127
+ this._NeedToChangePasswordYN = value;
128
+ }
129
+ get CreatedById() {
130
+ return this._CreatedById;
131
+ }
132
+ set CreatedById(value) {
133
+ this._CreatedById = value;
134
+ }
135
+ get CreatedAt() {
136
+ return this._CreatedAt;
137
+ }
138
+ set CreatedAt(value) {
139
+ this._CreatedAt = value;
140
+ }
141
+ get UpdatedById() {
142
+ return this._UpdatedById;
143
+ }
144
+ set UpdatedById(value) {
145
+ this._UpdatedById = value;
146
+ }
147
+ get UpdatedAt() {
148
+ return this._UpdatedAt;
149
+ }
150
+ set UpdatedAt(value) {
151
+ this._UpdatedAt = value;
152
+ }
153
+ getDetails() {
154
+ return __awaiter(this, void 0, void 0, function* () {
155
+ return {
156
+ FullName: this.FullName,
157
+ UserName: this.UserName,
158
+ IDNo: this.IDNo,
159
+ IDType: this.IDType,
160
+ Email: this.Email,
161
+ ContactNo: this.ContactNo,
162
+ };
163
+ });
164
+ }
165
+ constructor(sessionService, dbTransaction, userInfo) {
166
+ super();
167
+ this.ObjectName = 'User';
168
+ this.TableName = 'sso_Users';
169
+ this.ObjectType = 'User';
170
+ this._SessionService = sessionService;
171
+ if (dbTransaction) {
172
+ this._dbTransaction = dbTransaction;
173
+ }
174
+ if (userInfo) {
175
+ this.UserId = userInfo.UserId;
176
+ this.UserName = userInfo.FullName;
177
+ this.FullName = userInfo.FullName;
178
+ this.IDNo = userInfo.IDNo;
179
+ this.Email = userInfo.Email;
180
+ this.ContactNo = userInfo.ContactNo;
181
+ this.Password = userInfo.Password;
182
+ this.staffs = userInfo.staffs;
183
+ this.Status = userInfo.Status;
184
+ this.DefaultPasswordChangedYN = userInfo.DefaultPasswordChangedYN;
185
+ this.FirstLoginAt = userInfo.FirstLoginAt;
186
+ this.LastLoginAt = userInfo.LastLoginAt;
187
+ this.MFAEnabled = userInfo.MFAEnabled;
188
+ this.MFAConfig = userInfo.MFAConfig;
189
+ this.RecoveryEmail = userInfo.RecoveryEmail;
190
+ this.FailedLoginAttemptCount = userInfo.FailedLoginAttemptCount;
191
+ this.LastFailedLoginAt = userInfo.LastFailedLoginAt;
192
+ this.LastPasswordChangedAt = userInfo.LastPasswordChangedAt;
193
+ this.NeedToChangePasswordYN = userInfo.NeedToChangePasswordYN;
194
+ this.CreatedById = userInfo.CreatedById;
195
+ this.CreatedAt = userInfo.CreatedAt;
196
+ this.UpdatedById = userInfo.UpdatedById;
197
+ this.UpdatedAt = userInfo.UpdatedAt;
198
+ }
199
+ }
200
+ static init(sessionService, userId, dbTransaction = null) {
201
+ var _a, _b, _c;
202
+ return __awaiter(this, void 0, void 0, function* () {
203
+ User._RedisService = yield redis_service_1.RedisService.init();
204
+ if (userId) {
205
+ if (dbTransaction) {
206
+ User._Repository = new user_repository_1.UserRepository();
207
+ }
208
+ const user = yield User._Repository.findOne({
209
+ where: {
210
+ UserId: userId,
211
+ },
212
+ include: [
213
+ {
214
+ model: staff_entity_1.default,
215
+ },
216
+ ],
217
+ transaction: dbTransaction,
218
+ });
219
+ if (!user) {
220
+ throw new Error('Invalid credentials.');
221
+ }
222
+ if (user) {
223
+ const userAttr = {
224
+ UserId: user.UserId,
225
+ UserName: user.UserName,
226
+ FullName: (_a = user === null || user === void 0 ? void 0 : user.Staff) === null || _a === void 0 ? void 0 : _a.FullName,
227
+ IDNo: (_b = user === null || user === void 0 ? void 0 : user.Staff) === null || _b === void 0 ? void 0 : _b.IdNo,
228
+ ContactNo: (_c = user === null || user === void 0 ? void 0 : user.Staff) === null || _c === void 0 ? void 0 : _c.Mobile,
229
+ Email: user.Email,
230
+ Password: user.Password,
231
+ Status: user.Status,
232
+ DefaultPasswordChangedYN: user.DefaultPasswordChangedYN,
233
+ FirstLoginAt: user.FirstLoginAt,
234
+ LastLoginAt: user.LastLoginAt,
235
+ MFAEnabled: user.MFAEnabled,
236
+ MFAConfig: user.MFAConfig,
237
+ RecoveryEmail: user.RecoveryEmail,
238
+ FailedLoginAttemptCount: user.FailedLoginAttemptCount,
239
+ LastFailedLoginAt: user.LastFailedLoginAt,
240
+ LastPasswordChangedAt: user.LastPasswordChangedAt,
241
+ NeedToChangePasswordYN: user.NeedToChangePasswordYN,
242
+ CreatedById: user.CreatedById,
243
+ CreatedAt: user.CreatedAt,
244
+ UpdatedById: user.UpdatedById,
245
+ UpdatedAt: user.UpdatedAt,
246
+ staffs: user === null || user === void 0 ? void 0 : user.Staff,
247
+ };
248
+ return new User(sessionService, dbTransaction, userAttr);
249
+ }
250
+ else {
251
+ throw new Error('User not found');
252
+ }
253
+ }
254
+ return new User(sessionService, dbTransaction);
255
+ });
256
+ }
257
+ setEmail(email, dbTransaction) {
258
+ return __awaiter(this, void 0, void 0, function* () {
259
+ try {
260
+ if (this.Email === email) {
261
+ return;
262
+ }
263
+ const user = yield User._Repository.findOne({
264
+ where: {
265
+ Email: email,
266
+ },
267
+ transaction: dbTransaction,
268
+ });
269
+ if (user) {
270
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Email already exists');
271
+ }
272
+ this.Email = email;
273
+ }
274
+ catch (error) {
275
+ throw error;
276
+ }
277
+ });
278
+ }
279
+ login(systemCode, email, password, ipAddress, dbTransaction) {
280
+ var _a, _b, _c;
281
+ return __awaiter(this, void 0, void 0, function* () {
282
+ try {
283
+ if (!this.ObjectId) {
284
+ const user = yield User._Repository.findOne({
285
+ transaction: dbTransaction,
286
+ where: {
287
+ Email: email,
288
+ Status: {
289
+ [sequelize_1.Op.or]: [enum_1.UserStatus.ACTIVE, enum_1.UserStatus.LOCKED],
290
+ },
291
+ },
292
+ include: [
293
+ {
294
+ model: staff_entity_1.default,
295
+ },
296
+ ],
297
+ });
298
+ if (user) {
299
+ const userAttr = {
300
+ UserId: user.UserId,
301
+ UserName: user.UserName,
302
+ FullName: ((_a = user === null || user === void 0 ? void 0 : user.Staff) === null || _a === void 0 ? void 0 : _a.FullName) || null,
303
+ IDNo: ((_b = user === null || user === void 0 ? void 0 : user.Staff) === null || _b === void 0 ? void 0 : _b.IdNo) || null,
304
+ ContactNo: ((_c = user === null || user === void 0 ? void 0 : user.Staff) === null || _c === void 0 ? void 0 : _c.Mobile) || null,
305
+ Email: user.Email,
306
+ Password: user.Password,
307
+ Status: user.Status,
308
+ DefaultPasswordChangedYN: user.DefaultPasswordChangedYN,
309
+ FirstLoginAt: user.FirstLoginAt,
310
+ LastLoginAt: user.LastLoginAt,
311
+ MFAEnabled: user.MFAEnabled,
312
+ MFAConfig: user.MFAConfig,
313
+ RecoveryEmail: user.RecoveryEmail,
314
+ FailedLoginAttemptCount: user.FailedLoginAttemptCount,
315
+ LastFailedLoginAt: user.LastFailedLoginAt,
316
+ LastPasswordChangedAt: user.LastPasswordChangedAt,
317
+ NeedToChangePasswordYN: user.NeedToChangePasswordYN,
318
+ CreatedById: user.CreatedById,
319
+ CreatedAt: user.CreatedAt,
320
+ UpdatedById: user.UpdatedById,
321
+ UpdatedAt: user.UpdatedAt,
322
+ staffs: (user === null || user === void 0 ? void 0 : user.Staff) || null,
323
+ };
324
+ this.UserId = userAttr.UserId;
325
+ this.FullName = userAttr.FullName;
326
+ this.IDNo = userAttr.IDNo;
327
+ this.Email = userAttr.Email;
328
+ this.ContactNo = userAttr.ContactNo;
329
+ this.Password = userAttr.Password;
330
+ this.Status = userAttr.Status;
331
+ this.DefaultPasswordChangedYN = userAttr.DefaultPasswordChangedYN;
332
+ this.FirstLoginAt = userAttr.FirstLoginAt;
333
+ this.LastLoginAt = userAttr.LastLoginAt;
334
+ this.MFAEnabled = userAttr.MFAEnabled;
335
+ this.MFAConfig = userAttr.MFAConfig;
336
+ this.RecoveryEmail = userAttr.RecoveryEmail;
337
+ this.FailedLoginAttemptCount = userAttr.FailedLoginAttemptCount;
338
+ this.LastFailedLoginAt = userAttr.LastFailedLoginAt;
339
+ this.LastPasswordChangedAt = userAttr.LastPasswordChangedAt;
340
+ this.NeedToChangePasswordYN = userAttr.NeedToChangePasswordYN;
341
+ this.CreatedById = userAttr.CreatedById;
342
+ this.CreatedAt = userAttr.CreatedAt;
343
+ this.UpdatedById = userAttr.UpdatedById;
344
+ this.UpdatedAt = userAttr.UpdatedAt;
345
+ this.staffs = userAttr.staffs;
346
+ }
347
+ else {
348
+ throw new general_1.ClassError('User', 'UserErrMsg0X', 'Invalid Credentials');
349
+ }
350
+ }
351
+ if (this.ObjectId && this.Email !== email) {
352
+ throw new Error('Invalid credentials.');
353
+ }
354
+ const check2FA = yield User.check2FA(this, dbTransaction);
355
+ try {
356
+ const system = yield User._SystemRepository.findOne({
357
+ where: {
358
+ SystemCode: systemCode,
359
+ Status: 'Active',
360
+ },
361
+ });
362
+ if (!system) {
363
+ throw new Error('Invalid credentials.');
364
+ }
365
+ const passwordHashService = new password_hash_service_1.PasswordHashService();
366
+ const isPasswordValid = yield passwordHashService.verify(password, this.Password);
367
+ if (!isPasswordValid) {
368
+ throw new Error('Invalid credentials.');
369
+ }
370
+ yield this.checkSystemAccess(this.UserId, system.SystemCode, dbTransaction);
371
+ if (this.Status === enum_1.UserStatus.LOCKED) {
372
+ const isReleaseLock = User.shouldReleaseLock(this.LastFailedLoginAt);
373
+ if (isReleaseLock) {
374
+ yield User.releaseLock(this.UserId, dbTransaction);
375
+ this.Status = enum_1.UserStatus.ACTIVE;
376
+ }
377
+ else {
378
+ throw new Error('Invalid credentials.');
379
+ }
380
+ }
381
+ }
382
+ catch (error) {
383
+ yield this.incrementFailedLoginAttemptCount(dbTransaction);
384
+ }
385
+ const system = yield User._SystemRepository.findOne({
386
+ where: {
387
+ SystemCode: systemCode,
388
+ },
389
+ });
390
+ yield this.alertNewLogin(this.ObjectId, system.SystemCode, ipAddress);
391
+ this.FailedLoginAttemptCount = 0;
392
+ this.LastLoginAt = new Date();
393
+ if (!this.FirstLoginAt) {
394
+ this.FirstLoginAt = new Date();
395
+ }
396
+ yield User._Repository.update({
397
+ FullName: this.FullName,
398
+ UserName: this.UserName,
399
+ IDNo: this.IDNo,
400
+ Email: this.Email,
401
+ ContactNo: this.ContactNo,
402
+ Password: this.Password,
403
+ Status: this.Status,
404
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
405
+ FirstLoginAt: this.FirstLoginAt,
406
+ LastLoginAt: this.LastLoginAt,
407
+ MFAEnabled: this.MFAEnabled,
408
+ MFAConfig: this.MFAConfig,
409
+ RecoveryEmail: this.RecoveryEmail,
410
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
411
+ LastFailedLoginAt: this.LastFailedLoginAt,
412
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
413
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
414
+ }, {
415
+ where: {
416
+ UserId: this.UserId,
417
+ },
418
+ transaction: dbTransaction,
419
+ });
420
+ const userSession = yield this._SessionService.retrieveUserSession(this.ObjectId);
421
+ let systemLogin = userSession.systemLogins.find((system) => system.code === systemCode);
422
+ const { randomUUID } = require('crypto');
423
+ const sessionId = randomUUID();
424
+ if (systemLogin) {
425
+ systemLogin = systemLogin.sessionId = sessionId;
426
+ userSession.systemLogins.map((system) => system.code === systemCode ? systemLogin : system);
427
+ }
428
+ else {
429
+ const newLogin = {
430
+ id: system.SystemCode,
431
+ code: system.SystemCode,
432
+ sessionId: sessionId,
433
+ privileges: yield this.getPrivileges(system.SystemCode, dbTransaction),
434
+ };
435
+ userSession.systemLogins.push(newLogin);
436
+ }
437
+ this._SessionService.setUserSession(this.ObjectId, userSession);
438
+ yield User._LoginHistoryRepository.create({
439
+ UserId: this.UserId,
440
+ SystemCode: system.SystemCode,
441
+ OriginIp: ipAddress,
442
+ CreatedAt: new Date(),
443
+ LoginStatus: login_status_enum_1.LoginStatusEnum.SUCCESS,
444
+ }, {
445
+ transaction: dbTransaction,
446
+ });
447
+ const is2FAEnabledYN = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'is2FAEnabledYN');
448
+ const loginUser = yield login_user_1.LoginUser.init(this.SessionService, this.UserId, dbTransaction);
449
+ if (is2FAEnabledYN === 'Y') {
450
+ loginUser.session.Id = `${this.UserId}:`;
451
+ }
452
+ else {
453
+ loginUser.session.Id = `${this.UserId}:${sessionId}`;
454
+ }
455
+ return loginUser;
456
+ }
457
+ catch (error) {
458
+ if (this.ObjectId) {
459
+ yield User._LoginHistoryRepository.create({
460
+ UserId: this.UserId,
461
+ SystemCode: systemCode,
462
+ OriginIp: ipAddress,
463
+ LoginStatus: login_status_enum_1.LoginStatusEnum.FAILURE,
464
+ CreatedAt: new Date(),
465
+ }, {
466
+ transaction: dbTransaction,
467
+ });
468
+ }
469
+ throw error;
470
+ }
471
+ });
472
+ }
473
+ checkSystemAccess(userId, systemCode, dbTransaction) {
474
+ return __awaiter(this, void 0, void 0, function* () {
475
+ try {
476
+ let isUserHaveAccess = false;
477
+ const systemAccess = yield User._UserSystemAccessRepo.findOne({
478
+ where: {
479
+ UserId: userId,
480
+ SystemCode: systemCode,
481
+ Status: 'Active',
482
+ },
483
+ dbTransaction,
484
+ });
485
+ if (systemAccess) {
486
+ isUserHaveAccess = true;
487
+ }
488
+ else {
489
+ const userGroups = yield User._UserGroupRepo.findAll({
490
+ where: {
491
+ UserId: userId,
492
+ InheritGroupAccessYN: 'Y',
493
+ Status: 'Active',
494
+ },
495
+ include: [
496
+ {
497
+ model: group_entity_1.default,
498
+ },
499
+ ],
500
+ dbTransaction,
501
+ });
502
+ for (const usergroup of userGroups) {
503
+ const group = usergroup.Group;
504
+ const groupSystemAccess = yield User.getInheritedSystemAccess(dbTransaction, group);
505
+ for (const system of groupSystemAccess) {
506
+ if (system.SystemCode === systemCode) {
507
+ isUserHaveAccess = true;
508
+ break;
509
+ }
510
+ }
511
+ }
512
+ }
513
+ if (!isUserHaveAccess) {
514
+ throw new Error("User don't have access to the system.");
515
+ }
516
+ }
517
+ catch (error) {
518
+ throw error;
519
+ }
520
+ });
521
+ }
522
+ checkPrivileges(systemCode, privilegeName) {
523
+ return __awaiter(this, void 0, void 0, function* () {
524
+ try {
525
+ if (!this.ObjectId) {
526
+ throw new Error('ObjectId(UserId) is not set');
527
+ }
528
+ const userSession = yield this._SessionService.retrieveUserSession(this.ObjectId);
529
+ const systemLogin = userSession.systemLogins.find((system) => system.code === systemCode);
530
+ if (!systemLogin) {
531
+ return false;
532
+ }
533
+ const privileges = systemLogin.privileges;
534
+ const hasPrivilege = privileges.includes(privilegeName);
535
+ return hasPrivilege;
536
+ }
537
+ catch (error) {
538
+ throw error;
539
+ }
540
+ });
541
+ }
542
+ alertNewLogin(userId, systemCode, ipAddress) {
543
+ return __awaiter(this, void 0, void 0, function* () {
544
+ try {
545
+ const userLogins = yield User._LoginHistoryRepository.findAll({
546
+ where: {
547
+ UserId: userId,
548
+ SystemCode: systemCode,
549
+ },
550
+ });
551
+ const gotPreviousLogins = (userLogins === null || userLogins === void 0 ? void 0 : userLogins.length) !== 0;
552
+ let ipFound = undefined;
553
+ if (gotPreviousLogins) {
554
+ ipFound = userLogins.find((item) => item.OriginIp === ipAddress);
555
+ }
556
+ }
557
+ catch (error) {
558
+ throw error;
559
+ }
560
+ });
561
+ }
562
+ getPrivileges(systemCode, dbTransaction) {
563
+ return __awaiter(this, void 0, void 0, function* () {
564
+ try {
565
+ const system = yield User._SystemRepository.findOne({
566
+ where: {
567
+ SystemCode: systemCode,
568
+ },
569
+ transaction: dbTransaction,
570
+ });
571
+ if (!system) {
572
+ throw new Error('Invalid system code.');
573
+ }
574
+ const userPrivileges = yield this.getUserPersonalPrivileges(systemCode, dbTransaction);
575
+ const objectPrivileges = yield this.getObjectPrivileges(systemCode, dbTransaction);
576
+ const userGroupOwnByUser = yield User._UserGroupRepo.findAll({
577
+ where: {
578
+ UserId: this.UserId,
579
+ InheritGroupSystemAccessYN: 'Y',
580
+ InheritGroupPrivilegeYN: 'Y',
581
+ Status: 'Active',
582
+ },
583
+ include: [
584
+ {
585
+ model: group_entity_1.default,
586
+ where: {
587
+ Status: 'Active',
588
+ },
589
+ include: [
590
+ {
591
+ model: group_system_access_entity_1.default,
592
+ where: {
593
+ SystemCode: systemCode,
594
+ },
595
+ },
596
+ ],
597
+ },
598
+ ],
599
+ transaction: dbTransaction,
600
+ });
601
+ let groupsPrivileges = [];
602
+ for (const userGroup of userGroupOwnByUser) {
603
+ const gp = yield this.getInheritedPrivileges(userGroup.GroupCode, systemCode, dbTransaction);
604
+ groupsPrivileges = [...groupsPrivileges, ...gp];
605
+ }
606
+ const privileges = [
607
+ ...userPrivileges,
608
+ ...objectPrivileges,
609
+ ...groupsPrivileges,
610
+ ];
611
+ return privileges;
612
+ }
613
+ catch (error) {
614
+ throw error;
615
+ }
616
+ });
617
+ }
618
+ getInheritedPrivileges(groupCode, systemCode, dbTransaction) {
619
+ return __awaiter(this, void 0, void 0, function* () {
620
+ try {
621
+ const group = yield User._GroupRepo.findOne({
622
+ where: {
623
+ GroupCode: groupCode,
624
+ Status: 'Active',
625
+ },
626
+ include: [
627
+ {
628
+ model: group_privilege_entity_1.default,
629
+ where: {
630
+ Status: 'Active',
631
+ },
632
+ include: [
633
+ {
634
+ model: system_privilege_entity_1.default,
635
+ where: {
636
+ SystemCode: systemCode,
637
+ Status: 'Active',
638
+ },
639
+ },
640
+ ],
641
+ },
642
+ ],
643
+ transaction: dbTransaction,
644
+ });
645
+ const objectPrivileges = yield User._GroupObjectPrivilegeRepo.findAll({
646
+ where: {
647
+ GroupCode: groupCode,
648
+ },
649
+ include: {
650
+ model: system_privilege_entity_1.default,
651
+ where: {
652
+ SystemCode: systemCode,
653
+ Status: 'Active',
654
+ },
655
+ },
656
+ transaction: dbTransaction,
657
+ });
658
+ let privileges = [];
659
+ const groupPrivileges = [];
660
+ for (const groupPrivilege of group.GroupPrivileges) {
661
+ groupPrivileges.push(groupPrivilege.Privilege.PrivilegeCode);
662
+ }
663
+ const ops = [];
664
+ for (const objectPrivilege of objectPrivileges) {
665
+ ops.push(objectPrivilege.Privilege.PrivilegeCode);
666
+ }
667
+ privileges = [...privileges, ...groupPrivileges, ...ops];
668
+ if (group.ParentGroupCode && group.InheritParentPrivilegeYN === 'Y') {
669
+ const parentGroupPrivileges = yield this.getInheritedPrivileges(group.ParentGroupCode, systemCode, dbTransaction);
670
+ privileges = [...privileges, ...parentGroupPrivileges];
671
+ }
672
+ return privileges;
673
+ }
674
+ catch (error) {
675
+ throw error;
676
+ }
677
+ });
678
+ }
679
+ getUserPersonalPrivileges(systemCode, dbTransaction) {
680
+ return __awaiter(this, void 0, void 0, function* () {
681
+ try {
682
+ const userPrivileges = yield User._UserPrivilegeRepo.findAll({
683
+ where: {
684
+ UserId: this.UserId,
685
+ Status: 'Active',
686
+ },
687
+ include: {
688
+ model: system_privilege_entity_1.default,
689
+ where: {
690
+ SystemCode: systemCode,
691
+ Status: 'Active',
692
+ },
693
+ },
694
+ transaction: dbTransaction,
695
+ });
696
+ const privileges = userPrivileges.map((u) => u.Privilege.PrivilegeCode);
697
+ return privileges;
698
+ }
699
+ catch (error) {
700
+ throw error;
701
+ }
702
+ });
703
+ }
704
+ getObjectPrivileges(systemCode, dbTransaction) {
705
+ return __awaiter(this, void 0, void 0, function* () {
706
+ try {
707
+ const userObjectPrivileges = yield User._UserObjectPrivilegeRepo.findAll({
708
+ where: {
709
+ UserId: this.UserId,
710
+ },
711
+ include: {
712
+ model: system_privilege_entity_1.default,
713
+ where: {
714
+ SystemCode: systemCode,
715
+ Status: 'Active',
716
+ },
717
+ },
718
+ transaction: dbTransaction,
719
+ });
720
+ const privilegesCodes = userObjectPrivileges.map((u) => u.Privilege.PrivilegeCode);
721
+ return privilegesCodes;
722
+ }
723
+ catch (error) {
724
+ throw error;
725
+ }
726
+ });
727
+ }
728
+ static checkUserInfoDuplicated(dbTransaction, query) {
729
+ return __awaiter(this, void 0, void 0, function* () {
730
+ try {
731
+ const { Email, UserName, IdType, IdNo, ContactNo } = query;
732
+ const where = {
733
+ [sequelize_1.Op.or]: {},
734
+ };
735
+ if (Email) {
736
+ where[sequelize_1.Op.or]['Email'] = Email;
737
+ }
738
+ if (UserName) {
739
+ where[sequelize_1.Op.or]['UserName'] = UserName;
740
+ }
741
+ if (IdType && IdNo) {
742
+ where[sequelize_1.Op.or]['IdType'] = IdType;
743
+ where[sequelize_1.Op.or]['IdNo'] = IdNo;
744
+ }
745
+ if (ContactNo) {
746
+ where[sequelize_1.Op.or]['ContactNo'] = ContactNo;
747
+ }
748
+ const user = yield User._Repository.findAll({
749
+ where,
750
+ transaction: dbTransaction,
751
+ });
752
+ if (user && user.length > 0) {
753
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'User info already exists');
754
+ }
755
+ }
756
+ catch (error) {
757
+ throw error;
758
+ }
759
+ });
760
+ }
761
+ static generateDefaultPassword() {
762
+ try {
763
+ const passwordPolicy = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'passwordPolicy');
764
+ if (!passwordPolicy ||
765
+ !passwordPolicy.maxLen ||
766
+ !passwordPolicy.minLen ||
767
+ !passwordPolicy.nonAcceptableChar ||
768
+ !passwordPolicy.numOfCapitalLetters ||
769
+ !passwordPolicy.numOfNumbers ||
770
+ !passwordPolicy.numOfSpecialChars) {
771
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Missing password policy. Please set in config file.');
772
+ }
773
+ if (passwordPolicy.numOfCapitalLetters +
774
+ passwordPolicy.numOfNumbers +
775
+ passwordPolicy.numOfSpecialChars >
776
+ passwordPolicy.maxLen) {
777
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Password policy is invalid. Please set in config file.');
778
+ }
779
+ const { maxLen, minLen, nonAcceptableChar, numOfCapitalLetters, numOfNumbers, numOfSpecialChars, } = passwordPolicy;
780
+ const passwordLength = Math.floor(Math.random() * (maxLen - minLen + 1)) + minLen;
781
+ const words = 'abcdefghijklmnopqrstuvwxyz';
782
+ const capitalLetters = words.toUpperCase();
783
+ const numbers = '0123456789';
784
+ const specialChars = '!@#$%^&*()_+-={}[]|:;"<>,.?/~`';
785
+ const nonAcceptableChars = nonAcceptableChar.split(',');
786
+ const filteredWords = words
787
+ .split('')
788
+ .filter((word) => !nonAcceptableChars.includes(word));
789
+ const filteredCapitalLetters = capitalLetters
790
+ .split('')
791
+ .filter((word) => !nonAcceptableChars.includes(word));
792
+ const filteredNumbers = numbers
793
+ .split('')
794
+ .filter((word) => !nonAcceptableChars.includes(word));
795
+ const filteredSpecialChars = specialChars
796
+ .split('')
797
+ .filter((word) => !nonAcceptableChars.includes(word));
798
+ const generatedCapitalLetters = [];
799
+ const generatedNumbers = [];
800
+ const generatedSpecialChars = [];
801
+ const generatedWords = [];
802
+ for (let i = 0; i < numOfCapitalLetters; i++) {
803
+ const randomIndex = Math.floor(Math.random() * filteredCapitalLetters.length);
804
+ generatedCapitalLetters.push(filteredCapitalLetters[randomIndex]);
805
+ }
806
+ for (let i = 0; i < numOfNumbers; i++) {
807
+ const randomIndex = Math.floor(Math.random() * filteredNumbers.length);
808
+ generatedNumbers.push(filteredNumbers[randomIndex]);
809
+ }
810
+ for (let i = 0; i < numOfSpecialChars; i++) {
811
+ const randomIndex = Math.floor(Math.random() * filteredSpecialChars.length);
812
+ generatedSpecialChars.push(filteredSpecialChars[randomIndex]);
813
+ }
814
+ for (let i = 0; i <
815
+ passwordLength -
816
+ (numOfCapitalLetters + numOfNumbers + numOfSpecialChars); i++) {
817
+ const randomIndex = Math.floor(Math.random() * filteredWords.length);
818
+ generatedWords.push(filteredWords[randomIndex]);
819
+ }
820
+ let generatedPassword = '';
821
+ const allGeneratedChars = generatedCapitalLetters.concat(generatedNumbers, generatedSpecialChars, generatedWords);
822
+ allGeneratedChars.sort(() => Math.random() - 0.5);
823
+ generatedPassword = allGeneratedChars.join('');
824
+ return generatedPassword;
825
+ }
826
+ catch (error) {
827
+ throw error;
828
+ }
829
+ }
830
+ static setPassword(dbTransaction, user, password) {
831
+ return __awaiter(this, void 0, void 0, function* () {
832
+ try {
833
+ const passwordPolicy = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'passwordPolicy');
834
+ if (!passwordPolicy ||
835
+ !passwordPolicy.maxLen ||
836
+ !passwordPolicy.minLen ||
837
+ !passwordPolicy.nonAcceptableChar ||
838
+ !passwordPolicy.numOfCapitalLetters ||
839
+ !passwordPolicy.numOfNumbers ||
840
+ !passwordPolicy.numOfSpecialChars) {
841
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Missing password policy. Please set in config file.');
842
+ }
843
+ try {
844
+ if (password.length < passwordPolicy.minLen) {
845
+ throw Error('Password is too short');
846
+ }
847
+ if (password.length > passwordPolicy.maxLen) {
848
+ throw Error('Password is too long');
849
+ }
850
+ const nonAcceptableChars = passwordPolicy.nonAcceptableChar.split(',');
851
+ const nonAcceptableCharsFound = nonAcceptableChars.some((char) => password.includes(char));
852
+ if (nonAcceptableCharsFound) {
853
+ throw Error('Password contains unacceptable characters');
854
+ }
855
+ const capitalLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
856
+ const numOfCapitalLetters = passwordPolicy.numOfCapitalLetters;
857
+ const capitalLettersFound = capitalLetters
858
+ .split('')
859
+ .filter((char) => password.includes(char)).length;
860
+ if (capitalLettersFound < numOfCapitalLetters) {
861
+ throw Error('Password does not contain enough capital letters');
862
+ }
863
+ const numbers = '0123456789';
864
+ const numOfNumbers = passwordPolicy.numOfNumbers;
865
+ const numbersFound = numbers
866
+ .split('')
867
+ .filter((char) => password.includes(char)).length;
868
+ if (numbersFound < numOfNumbers) {
869
+ throw Error('Password does not contain enough numbers');
870
+ }
871
+ const specialChars = '!@#$%^&*()_+-={}[]|:;"<>,.?/~`';
872
+ const numOfSpecialChars = passwordPolicy.numOfSpecialChars;
873
+ const specialCharsFound = specialChars
874
+ .split('')
875
+ .filter((char) => password.includes(char)).length;
876
+ if (specialCharsFound < numOfSpecialChars) {
877
+ throw Error('Password does not contain enough special characters');
878
+ }
879
+ }
880
+ catch (error) {
881
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', "Your password doesn't meet security requirements. Try using a mix of uppercase and lowercase letters, numbers, and symbols.");
882
+ }
883
+ const passwordHashService = new password_hash_service_1.PasswordHashService();
884
+ const hashedPassword = yield passwordHashService.hashPassword(password);
885
+ user._Password = hashedPassword;
886
+ return user;
887
+ }
888
+ catch (error) {
889
+ throw error;
890
+ }
891
+ });
892
+ }
893
+ static create(loginUser, dbTransaction, user) {
894
+ return __awaiter(this, void 0, void 0, function* () {
895
+ try {
896
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
897
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'User - Create');
898
+ if (!isPrivileged) {
899
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have the privilege to create user');
900
+ }
901
+ if (!user.Email && !user.UserName) {
902
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Email and Username is required');
903
+ }
904
+ yield User.checkUserInfoDuplicated(dbTransaction, {
905
+ Email: user.Email,
906
+ UserName: user.UserName,
907
+ IdType: user.IDType,
908
+ IdNo: user.IDNo,
909
+ ContactNo: user.ContactNo,
910
+ });
911
+ const defaultPassword = User.generateDefaultPassword();
912
+ user = yield User.setPassword(dbTransaction, user, defaultPassword);
913
+ const userInfo = {
914
+ UserName: user.UserName,
915
+ FullName: user.FullName,
916
+ IDNo: user.IDNo,
917
+ Email: user.Email,
918
+ ContactNo: user.ContactNo,
919
+ Password: user.Password,
920
+ Status: enum_1.UserStatus.ACTIVE,
921
+ FirstLoginAt: null,
922
+ LastLoginAt: null,
923
+ MFAEnabled: null,
924
+ MFAConfig: null,
925
+ RecoveryEmail: null,
926
+ FailedLoginAttemptCount: 0,
927
+ LastFailedLoginAt: null,
928
+ LastPasswordChangedAt: null,
929
+ DefaultPasswordChangedYN: yn_enum_1.YN.No,
930
+ NeedToChangePasswordYN: yn_enum_1.YN.Yes,
931
+ CreatedById: loginUser.UserId,
932
+ CreatedAt: new Date(),
933
+ UpdatedById: loginUser.UserId,
934
+ UpdatedAt: new Date(),
935
+ UserId: null,
936
+ };
937
+ const newUser = yield User._Repository.create({
938
+ Email: userInfo.Email,
939
+ UserName: userInfo.UserName,
940
+ Password: userInfo.Password,
941
+ Status: userInfo.Status,
942
+ DefaultPasswordChangedYN: userInfo.DefaultPasswordChangedYN,
943
+ FirstLoginAt: userInfo.FirstLoginAt,
944
+ LastLoginAt: userInfo.LastLoginAt,
945
+ MFAEnabled: userInfo.MFAEnabled,
946
+ MFAConfig: userInfo.MFAConfig,
947
+ RecoveryEmail: userInfo.RecoveryEmail,
948
+ FailedLoginAttemptCount: userInfo.FailedLoginAttemptCount,
949
+ LastFailedLoginAt: userInfo.LastFailedLoginAt,
950
+ LastPasswordChangedAt: userInfo.LastPasswordChangedAt,
951
+ NeedToChangePasswordYN: userInfo.NeedToChangePasswordYN,
952
+ CreatedById: userInfo.CreatedById,
953
+ CreatedAt: userInfo.CreatedAt,
954
+ UpdatedById: userInfo.UpdatedById,
955
+ UpdatedAt: userInfo.UpdatedAt,
956
+ }, {
957
+ transaction: dbTransaction,
958
+ });
959
+ userInfo.UserId = newUser.UserId;
960
+ const userToBeCreated = new User(loginUser.SessionService, dbTransaction, userInfo);
961
+ const activity = new activity_history_1.Activity();
962
+ activity.ActivityId = activity.createId();
963
+ activity.Action = activity_history_1.ActionEnum.ADD;
964
+ activity.Description = 'Create User';
965
+ activity.EntityType = 'LoginUser';
966
+ activity.EntityId = newUser.UserId.toString();
967
+ activity.EntityValueBefore = JSON.stringify({});
968
+ activity.EntityValueAfter = JSON.stringify(newUser.get({ plain: true }));
969
+ yield activity.create(loginUser.ObjectId, dbTransaction);
970
+ return userToBeCreated;
971
+ }
972
+ catch (error) {
973
+ throw error;
974
+ }
975
+ });
976
+ }
977
+ incrementFailedLoginAttemptCount(dbTransaction) {
978
+ return __awaiter(this, void 0, void 0, function* () {
979
+ const maxFailedLoginAttempts = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'maxFailedLoginAttempts');
980
+ const autoReleaseYN = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'autoReleaseYN');
981
+ if (!maxFailedLoginAttempts || !autoReleaseYN) {
982
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Missing maxFailedLoginAttempts and or autoReleaseYN. Please set in config file.');
983
+ }
984
+ const FailedLoginAttemptCount = this.FailedLoginAttemptCount + 1;
985
+ const LastFailedLoginAt = new Date();
986
+ if (FailedLoginAttemptCount > maxFailedLoginAttempts) {
987
+ this.Status = enum_1.UserStatus.LOCKED;
988
+ }
989
+ yield User._Repository.update({
990
+ FailedLoginAttemptCount: FailedLoginAttemptCount,
991
+ LastFailedLoginAt: LastFailedLoginAt,
992
+ Status: this.Status,
993
+ }, {
994
+ where: {
995
+ UserId: this.UserId,
996
+ },
997
+ transaction: dbTransaction,
998
+ });
999
+ if (this.Status === enum_1.UserStatus.LOCKED && autoReleaseYN === 'Y') {
1000
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Your account has been temporarily locked due to too many failed login attempts, please try again later.');
1001
+ }
1002
+ if (this.Status === enum_1.UserStatus.LOCKED && autoReleaseYN === 'N') {
1003
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Your account has been locked due to too many failed login attempts, please contact IT Support for instructions on how to unlock your account');
1004
+ }
1005
+ if (this.Status == enum_1.UserStatus.LOCKED) {
1006
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid credentials.');
1007
+ }
1008
+ });
1009
+ }
1010
+ static shouldReleaseLock(LastFailedLoginAt) {
1011
+ const minuteToAutoRelease = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'minuteToAutoRelease');
1012
+ const autoReleaseYN = config_1.ComponentConfig.getComponentConfigValue('@tomei/sso', 'autoReleaseYN');
1013
+ if (!minuteToAutoRelease || !autoReleaseYN) {
1014
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Missing minuteToAutoRelease and or autoReleaseYN. Please set in config file.');
1015
+ }
1016
+ if (autoReleaseYN === 'Y') {
1017
+ const lastFailedDate = new Date(LastFailedLoginAt);
1018
+ const currentDate = new Date();
1019
+ const timeDifferenceInMillis = currentDate.getTime() - lastFailedDate.getTime();
1020
+ const timeDifferenceInMinutes = timeDifferenceInMillis / (1000 * 60);
1021
+ if (timeDifferenceInMinutes > +minuteToAutoRelease) {
1022
+ return true;
1023
+ }
1024
+ else {
1025
+ return false;
1026
+ }
1027
+ }
1028
+ else if (autoReleaseYN === 'N') {
1029
+ return false;
1030
+ }
1031
+ }
1032
+ static releaseLock(UserId, dbTransaction) {
1033
+ this._Repository.update({
1034
+ FailedLoginAttemptCount: 0,
1035
+ Status: enum_1.UserStatus.ACTIVE,
1036
+ }, {
1037
+ where: {
1038
+ UserId: UserId,
1039
+ },
1040
+ transaction: dbTransaction,
1041
+ });
1042
+ }
1043
+ static getGroups(loginUser, dbTransaction) {
1044
+ return __awaiter(this, void 0, void 0, function* () {
1045
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1046
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'UserGroup - List Own');
1047
+ if (!isPrivileged) {
1048
+ throw new Error('You do not have permission to list UserGroup.');
1049
+ }
1050
+ const userGroups = yield User._UserGroupRepo.findAll({
1051
+ where: {
1052
+ UserId: loginUser.ObjectId,
1053
+ Status: 'Active',
1054
+ },
1055
+ include: [{ model: user_entity_1.default, as: 'User' }, { model: group_entity_1.default }],
1056
+ transaction: dbTransaction,
1057
+ });
1058
+ return userGroups;
1059
+ });
1060
+ }
1061
+ static getInheritedSystemAccess(dbTransaction, group) {
1062
+ return __awaiter(this, void 0, void 0, function* () {
1063
+ const dataSystemAccesses = yield User._GroupSystemAccessRepo.findAll({
1064
+ where: {
1065
+ GroupCode: group.GroupCode,
1066
+ Status: 'Active',
1067
+ },
1068
+ include: [{ model: system_entity_1.default }],
1069
+ transaction: dbTransaction,
1070
+ });
1071
+ let systemAccesses = dataSystemAccesses;
1072
+ if (group.InheritParentPrivilegeYN === 'Y' && group.ParentGroupCode) {
1073
+ const GroupCode = group.ParentGroupCode;
1074
+ const parentGroup = yield User._GroupRepo.findByPk(GroupCode, dbTransaction);
1075
+ const dataParentSystemAccesses = yield User.getInheritedSystemAccess(dbTransaction, parentGroup);
1076
+ const parentSystemAccesses = dataParentSystemAccesses;
1077
+ systemAccesses = systemAccesses.concat(parentSystemAccesses);
1078
+ }
1079
+ return systemAccesses;
1080
+ });
1081
+ }
1082
+ static combineSystemAccess(loginUser, dbTransaction, groups) {
1083
+ return __awaiter(this, void 0, void 0, function* () {
1084
+ const userAccess = yield User._UserSystemAccessRepo.findAll({
1085
+ where: {
1086
+ UserId: loginUser.ObjectId,
1087
+ Status: 'Active',
1088
+ },
1089
+ include: [{ model: system_entity_1.default }],
1090
+ transaction: dbTransaction,
1091
+ });
1092
+ const groupAccessPromises = groups.map((e) => __awaiter(this, void 0, void 0, function* () {
1093
+ if (e.InheritParentSystemAccessYN) {
1094
+ return yield this.getInheritedSystemAccess(dbTransaction, e);
1095
+ }
1096
+ else {
1097
+ return [];
1098
+ }
1099
+ }));
1100
+ const groupAccess = (yield Promise.all(groupAccessPromises)).flat();
1101
+ const allAccess = userAccess.concat(groupAccess);
1102
+ const uniqueAccess = new Set(allAccess.filter((value, index, self) => {
1103
+ return self.some((prev) => prev.SystemCode === value.SystemCode);
1104
+ }));
1105
+ return Array.from(uniqueAccess);
1106
+ });
1107
+ }
1108
+ static getSystems(loginUser, dbTransaction) {
1109
+ return __awaiter(this, void 0, void 0, function* () {
1110
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1111
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'System – List Own');
1112
+ if (!isPrivileged) {
1113
+ throw new Error('You do not have permission to list UserGroup.');
1114
+ }
1115
+ const groups = yield User.getGroups(loginUser, dbTransaction);
1116
+ const systemAccess = yield User.combineSystemAccess(loginUser, dbTransaction, groups);
1117
+ const output = [];
1118
+ if (systemAccess) {
1119
+ for (let i = 0; i < systemAccess.length; i++) {
1120
+ const system = yield User._SystemRepository.findOne({
1121
+ where: {
1122
+ SystemCode: systemAccess[i].SystemCode,
1123
+ Status: 'Active',
1124
+ },
1125
+ });
1126
+ output.push({
1127
+ UserSystemAccessId: systemAccess[i].UserSystemAccessId,
1128
+ UserId: systemAccess[i].UserId,
1129
+ SystemCode: systemAccess[i].SystemCode,
1130
+ Status: systemAccess[i].Status,
1131
+ CreatedById: systemAccess[i].CreatedById,
1132
+ UpdatedById: systemAccess[i].UpdatedById,
1133
+ CreatedAt: systemAccess[i].CreatedAt,
1134
+ UpdatedAt: systemAccess[i].UpdatedAt,
1135
+ System: system,
1136
+ });
1137
+ }
1138
+ }
1139
+ return output;
1140
+ });
1141
+ }
1142
+ static check2FA(loginUser, dbTransaction) {
1143
+ return __awaiter(this, void 0, void 0, function* () {
1144
+ try {
1145
+ const user = yield User._Repository.findOne({
1146
+ where: {
1147
+ UserId: loginUser.UserId,
1148
+ },
1149
+ transaction: dbTransaction,
1150
+ });
1151
+ if (user.MFAEnabled === 1) {
1152
+ return true;
1153
+ }
1154
+ return false;
1155
+ }
1156
+ catch (error) {
1157
+ throw error;
1158
+ }
1159
+ });
1160
+ }
1161
+ static setup2FA(userId, dbTransaction) {
1162
+ var _a, _b, _c, _d;
1163
+ return __awaiter(this, void 0, void 0, function* () {
1164
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1165
+ const user = yield User._Repository.findOne({
1166
+ where: {
1167
+ UserId: userId,
1168
+ },
1169
+ });
1170
+ if (!user) {
1171
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Credentials');
1172
+ }
1173
+ const secretCode = speakeasy.generateSecret({ name: systemCode });
1174
+ let userMFAConfig = null;
1175
+ if ((user === null || user === void 0 ? void 0 : user.MFAConfig) !== null && typeof (user === null || user === void 0 ? void 0 : user.MFAConfig) === 'string') {
1176
+ try {
1177
+ userMFAConfig = JSON.parse(user === null || user === void 0 ? void 0 : user.MFAConfig);
1178
+ }
1179
+ catch (error) {
1180
+ console.error('Invalid JSON string on MFAConfig:', error);
1181
+ }
1182
+ }
1183
+ const MFAConfig = {
1184
+ totp: {
1185
+ enabled: true,
1186
+ secret: secretCode.base32,
1187
+ issuer: systemCode,
1188
+ },
1189
+ sms: {
1190
+ enabled: ((_a = userMFAConfig === null || userMFAConfig === void 0 ? void 0 : userMFAConfig.sms) === null || _a === void 0 ? void 0 : _a.enable) || false,
1191
+ phoneNumber: ((_b = userMFAConfig === null || userMFAConfig === void 0 ? void 0 : userMFAConfig.sms) === null || _b === void 0 ? void 0 : _b.phoneNumber) || '',
1192
+ },
1193
+ email: {
1194
+ enabled: ((_c = userMFAConfig === null || userMFAConfig === void 0 ? void 0 : userMFAConfig.email) === null || _c === void 0 ? void 0 : _c.enable) || false,
1195
+ emailAddress: ((_d = userMFAConfig === null || userMFAConfig === void 0 ? void 0 : userMFAConfig.email) === null || _d === void 0 ? void 0 : _d.emailAddress) || '',
1196
+ },
1197
+ };
1198
+ user.MFAEnabled = 0;
1199
+ user.MFAConfig = JSON.stringify(MFAConfig);
1200
+ yield User._Repository.update({
1201
+ MFAEnabled: user.MFAEnabled,
1202
+ MFAConfig: user.MFAConfig,
1203
+ }, {
1204
+ where: {
1205
+ UserId: userId,
1206
+ },
1207
+ transaction: dbTransaction,
1208
+ });
1209
+ return secretCode.otpauth_url;
1210
+ });
1211
+ }
1212
+ verify2FASetup(userId, mfaToken, dbTransaction) {
1213
+ return __awaiter(this, void 0, void 0, function* () {
1214
+ const user = yield User._Repository.findOne({
1215
+ where: {
1216
+ UserId: userId,
1217
+ },
1218
+ });
1219
+ if (!user) {
1220
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Credentials');
1221
+ }
1222
+ let userMFAConfig = null;
1223
+ if ((user === null || user === void 0 ? void 0 : user.MFAConfig) !== null && typeof (user === null || user === void 0 ? void 0 : user.MFAConfig) === 'string') {
1224
+ try {
1225
+ userMFAConfig = JSON.parse(user === null || user === void 0 ? void 0 : user.MFAConfig);
1226
+ }
1227
+ catch (error) {
1228
+ console.error('Invalid JSON string on MFAConfig:', error);
1229
+ }
1230
+ }
1231
+ const isVerified = yield speakeasy.totp.verify({
1232
+ secret: userMFAConfig.totp.secret,
1233
+ encoding: 'base32',
1234
+ token: mfaToken,
1235
+ });
1236
+ if (!isVerified) {
1237
+ return false;
1238
+ }
1239
+ yield User._Repository.update({
1240
+ MFAEnabled: 1,
1241
+ }, {
1242
+ where: {
1243
+ UserId: userId,
1244
+ },
1245
+ transaction: dbTransaction,
1246
+ });
1247
+ const userSession = yield this._SessionService.retrieveUserSession(`${userId}`);
1248
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1249
+ const systemLogin = userSession.systemLogins.find((e) => e.code === systemCode);
1250
+ return `${userId}:${systemLogin.sessionId}`;
1251
+ });
1252
+ }
1253
+ verify2FACode(userId, mfaToken, dbTransaction) {
1254
+ return __awaiter(this, void 0, void 0, function* () {
1255
+ const user = yield User._Repository.findOne({
1256
+ where: {
1257
+ UserId: userId,
1258
+ },
1259
+ transaction: dbTransaction,
1260
+ });
1261
+ if (!user) {
1262
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Credentials');
1263
+ }
1264
+ let userMFAConfig = null;
1265
+ if ((user === null || user === void 0 ? void 0 : user.MFAConfig) !== null && typeof (user === null || user === void 0 ? void 0 : user.MFAConfig) === 'string') {
1266
+ try {
1267
+ userMFAConfig = JSON.parse(user === null || user === void 0 ? void 0 : user.MFAConfig);
1268
+ }
1269
+ catch (error) {
1270
+ console.error('Invalid JSON string on MFAConfig:', error);
1271
+ }
1272
+ }
1273
+ const isVerified = yield speakeasy.totp.verify({
1274
+ secret: userMFAConfig.totp.secret,
1275
+ encoding: 'base32',
1276
+ token: mfaToken,
1277
+ });
1278
+ if (!isVerified) {
1279
+ return false;
1280
+ }
1281
+ const userSession = yield this._SessionService.retrieveUserSession(`${userId}`);
1282
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1283
+ const systemLogin = userSession.systemLogins.find((e) => e.code === systemCode);
1284
+ return `${userId}:${systemLogin.sessionId}`;
1285
+ });
1286
+ }
1287
+ addUserGroup(GroupCode, loginUser, dbTransaction) {
1288
+ return __awaiter(this, void 0, void 0, function* () {
1289
+ const group = yield User._GroupRepo.findOne({
1290
+ where: {
1291
+ GroupCode,
1292
+ },
1293
+ transaction: dbTransaction,
1294
+ });
1295
+ if (!group) {
1296
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Group Code');
1297
+ }
1298
+ const entityValueAfter = {
1299
+ UserId: this.UserId,
1300
+ GroupCode: group.GroupCode,
1301
+ CreatedAt: new Date(),
1302
+ CreatedById: loginUser.UserId,
1303
+ UpdatedAt: new Date(),
1304
+ UpdatedById: loginUser.UserId,
1305
+ };
1306
+ yield User._UserGroupRepo.create(entityValueAfter, {
1307
+ transaction: dbTransaction,
1308
+ });
1309
+ const activity = new activity_history_1.Activity();
1310
+ activity.ActivityId = activity.createId();
1311
+ activity.Action = activity_history_1.ActionEnum.ADD;
1312
+ activity.Description = 'Add User Group';
1313
+ activity.EntityType = 'UserGroup';
1314
+ activity.EntityId = group.GroupCode;
1315
+ activity.EntityValueBefore = JSON.stringify({});
1316
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
1317
+ yield activity.create(loginUser.ObjectId, dbTransaction);
1318
+ });
1319
+ }
1320
+ update(data, loginUser, dbTransaction) {
1321
+ return __awaiter(this, void 0, void 0, function* () {
1322
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1323
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'User - Update');
1324
+ if (!isPrivileged) {
1325
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have the privilege to update user');
1326
+ }
1327
+ if (!this.UserId) {
1328
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'UserId is required');
1329
+ }
1330
+ if (data.Email !== this.Email || data.UserName !== this.UserName) {
1331
+ yield User.checkUserInfoDuplicated(dbTransaction, {
1332
+ Email: data.Email,
1333
+ UserName: data.UserName,
1334
+ });
1335
+ }
1336
+ if (data.BuildingCode) {
1337
+ const building = yield group_entity_1.default.findOne({
1338
+ where: {
1339
+ Type: 'Building',
1340
+ GroupCode: data.BuildingCode,
1341
+ },
1342
+ transaction: dbTransaction,
1343
+ });
1344
+ if (!building) {
1345
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Building Code');
1346
+ }
1347
+ const userBuilding = yield User._UserGroupRepo.findOne({
1348
+ where: {
1349
+ UserId: this.UserId,
1350
+ },
1351
+ include: [
1352
+ {
1353
+ model: group_entity_1.default,
1354
+ where: {
1355
+ Type: 'Building',
1356
+ },
1357
+ },
1358
+ ],
1359
+ transaction: dbTransaction,
1360
+ });
1361
+ if (userBuilding) {
1362
+ yield User._UserGroupRepo.update({
1363
+ GroupCode: data.BuildingCode,
1364
+ UpdatedAt: new Date(),
1365
+ UpdatedById: loginUser.UserId,
1366
+ }, {
1367
+ where: {
1368
+ UserId: this.UserId,
1369
+ GroupCode: userBuilding.GroupCode,
1370
+ },
1371
+ transaction: dbTransaction,
1372
+ });
1373
+ }
1374
+ else {
1375
+ yield User._UserGroupRepo.create({
1376
+ UserId: this.UserId,
1377
+ GroupCode: data.BuildingCode,
1378
+ CreatedAt: new Date(),
1379
+ CreatedById: loginUser.UserId,
1380
+ UpdatedAt: new Date(),
1381
+ UpdatedById: loginUser.UserId,
1382
+ }, {
1383
+ transaction: dbTransaction,
1384
+ });
1385
+ }
1386
+ }
1387
+ if (data.CompanyCode) {
1388
+ const company = yield group_entity_1.default.findOne({
1389
+ where: {
1390
+ Type: 'Company',
1391
+ GroupCode: data.CompanyCode,
1392
+ },
1393
+ transaction: dbTransaction,
1394
+ });
1395
+ if (!company) {
1396
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Company Code');
1397
+ }
1398
+ const userCompany = yield User._UserGroupRepo.findOne({
1399
+ where: {
1400
+ UserId: this.UserId,
1401
+ },
1402
+ include: [
1403
+ {
1404
+ model: group_entity_1.default,
1405
+ where: {
1406
+ Type: 'Company',
1407
+ },
1408
+ },
1409
+ ],
1410
+ transaction: dbTransaction,
1411
+ });
1412
+ if (userCompany) {
1413
+ yield User._UserGroupRepo.update({
1414
+ GroupCode: data.CompanyCode,
1415
+ UpdatedAt: new Date(),
1416
+ UpdatedById: loginUser.UserId,
1417
+ }, {
1418
+ where: {
1419
+ UserId: this.UserId,
1420
+ GroupCode: userCompany.GroupCode,
1421
+ },
1422
+ transaction: dbTransaction,
1423
+ });
1424
+ }
1425
+ else {
1426
+ yield User._UserGroupRepo.create({
1427
+ UserId: this.UserId,
1428
+ GroupCode: data.CompanyCode,
1429
+ CreatedAt: new Date(),
1430
+ CreatedById: loginUser.UserId,
1431
+ UpdatedAt: new Date(),
1432
+ UpdatedById: loginUser.UserId,
1433
+ }, {
1434
+ transaction: dbTransaction,
1435
+ });
1436
+ }
1437
+ }
1438
+ if (data.DepartmentCode) {
1439
+ const department = yield group_entity_1.default.findOne({
1440
+ where: {
1441
+ Type: 'Department',
1442
+ GroupCode: data.DepartmentCode,
1443
+ },
1444
+ transaction: dbTransaction,
1445
+ });
1446
+ if (!department) {
1447
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'Invalid Department Code');
1448
+ }
1449
+ const userDepartment = yield User._UserGroupRepo.findOne({
1450
+ where: {
1451
+ UserId: this.UserId,
1452
+ },
1453
+ include: [
1454
+ {
1455
+ model: group_entity_1.default,
1456
+ where: {
1457
+ Type: 'Department',
1458
+ },
1459
+ },
1460
+ ],
1461
+ transaction: dbTransaction,
1462
+ });
1463
+ if (userDepartment) {
1464
+ yield User._UserGroupRepo.update({
1465
+ GroupCode: data.DepartmentCode,
1466
+ UpdatedAt: new Date(),
1467
+ UpdatedById: loginUser.UserId,
1468
+ }, {
1469
+ where: {
1470
+ UserId: this.UserId,
1471
+ GroupCode: userDepartment.GroupCode,
1472
+ },
1473
+ transaction: dbTransaction,
1474
+ });
1475
+ }
1476
+ else {
1477
+ yield User._UserGroupRepo.create({
1478
+ UserId: this.UserId,
1479
+ GroupCode: data.DepartmentCode,
1480
+ CreatedAt: new Date(),
1481
+ CreatedById: loginUser.UserId,
1482
+ UpdatedAt: new Date(),
1483
+ UpdatedById: loginUser.UserId,
1484
+ }, {
1485
+ transaction: dbTransaction,
1486
+ });
1487
+ }
1488
+ }
1489
+ const entityValueBefore = {
1490
+ UserId: this.UserId,
1491
+ UserName: this.UserName,
1492
+ Email: this.Email,
1493
+ Password: this.Password,
1494
+ Status: this.Status,
1495
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
1496
+ FirstLoginAt: this.FirstLoginAt,
1497
+ LastLoginAt: this.LastLoginAt,
1498
+ MFAEnabled: this.MFAEnabled,
1499
+ MFAConfig: this.MFAConfig,
1500
+ RecoveryEmail: this.RecoveryEmail,
1501
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
1502
+ LastFailedLoginAt: this.LastFailedLoginAt,
1503
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
1504
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
1505
+ CreatedById: this.CreatedById,
1506
+ CreatedAt: this.CreatedAt,
1507
+ UpdatedById: this.UpdatedById,
1508
+ UpdatedAt: this.UpdatedAt,
1509
+ };
1510
+ this.UserName = data.UserName;
1511
+ this.Email = data.Email;
1512
+ this.Status = data.Status;
1513
+ this.RecoveryEmail = data.RecoveryEmail;
1514
+ this.UpdatedAt = new Date();
1515
+ this.UpdatedById = loginUser.UserId;
1516
+ yield User._Repository.update({
1517
+ UserName: this.UserName,
1518
+ Email: this.Email,
1519
+ Status: this.Status,
1520
+ RecoveryEmail: this.RecoveryEmail,
1521
+ UpdatedById: this.UpdatedById,
1522
+ UpdatedAt: this.UpdatedAt,
1523
+ }, {
1524
+ where: {
1525
+ UserId: this.UserId,
1526
+ },
1527
+ transaction: dbTransaction,
1528
+ });
1529
+ const entityValueAfter = {
1530
+ UserId: this.UserId,
1531
+ UserName: this.UserName,
1532
+ Email: this.Email,
1533
+ Password: this.Password,
1534
+ Status: this.Status,
1535
+ DefaultPasswordChangedYN: this.DefaultPasswordChangedYN,
1536
+ FirstLoginAt: this.FirstLoginAt,
1537
+ LastLoginAt: this.LastLoginAt,
1538
+ MFAEnabled: this.MFAEnabled,
1539
+ MFAConfig: this.MFAConfig,
1540
+ RecoveryEmail: this.RecoveryEmail,
1541
+ FailedLoginAttemptCount: this.FailedLoginAttemptCount,
1542
+ LastFailedLoginAt: this.LastFailedLoginAt,
1543
+ LastPasswordChangedAt: this.LastPasswordChangedAt,
1544
+ NeedToChangePasswordYN: this.NeedToChangePasswordYN,
1545
+ CreatedById: this.CreatedById,
1546
+ CreatedAt: this.CreatedAt,
1547
+ UpdatedById: this.UpdatedById,
1548
+ UpdatedAt: this.UpdatedAt,
1549
+ };
1550
+ const activity = new activity_history_1.Activity();
1551
+ activity.ActivityId = activity.createId();
1552
+ activity.Action = activity_history_1.ActionEnum.UPDATE;
1553
+ activity.Description = 'Update User';
1554
+ activity.EntityType = 'LoginUser';
1555
+ activity.EntityId = this.UserId.toString();
1556
+ activity.EntityValueBefore = JSON.stringify(entityValueBefore);
1557
+ activity.EntityValueAfter = JSON.stringify(entityValueAfter);
1558
+ yield activity.create(loginUser.ObjectId, dbTransaction);
1559
+ return this;
1560
+ });
1561
+ }
1562
+ static findById(loginUser, dbTransaction, UserId) {
1563
+ var _a, _b, _c;
1564
+ return __awaiter(this, void 0, void 0, function* () {
1565
+ const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code');
1566
+ const isPrivileged = yield loginUser.checkPrivileges(systemCode, 'USER_VIEW');
1567
+ if (!isPrivileged) {
1568
+ throw new general_1.ClassError('LoginUser', 'LoginUserErrMsg0X', 'You do not have the privilege to find user');
1569
+ }
1570
+ const user = yield User._Repository.findOne({
1571
+ where: {
1572
+ UserId: UserId,
1573
+ Status: 'Active',
1574
+ },
1575
+ transaction: dbTransaction,
1576
+ });
1577
+ const userAttr = {
1578
+ UserId: user.UserId,
1579
+ UserName: user.UserName,
1580
+ FullName: ((_a = user === null || user === void 0 ? void 0 : user.Staff) === null || _a === void 0 ? void 0 : _a.FullName) || null,
1581
+ IDNo: ((_b = user === null || user === void 0 ? void 0 : user.Staff) === null || _b === void 0 ? void 0 : _b.IdNo) || null,
1582
+ ContactNo: ((_c = user === null || user === void 0 ? void 0 : user.Staff) === null || _c === void 0 ? void 0 : _c.Mobile) || null,
1583
+ Email: user.Email,
1584
+ Password: user.Password,
1585
+ Status: user.Status,
1586
+ DefaultPasswordChangedYN: user.DefaultPasswordChangedYN,
1587
+ FirstLoginAt: user.FirstLoginAt,
1588
+ LastLoginAt: user.LastLoginAt,
1589
+ MFAEnabled: user.MFAEnabled,
1590
+ MFAConfig: user.MFAConfig,
1591
+ RecoveryEmail: user.RecoveryEmail,
1592
+ FailedLoginAttemptCount: user.FailedLoginAttemptCount,
1593
+ LastFailedLoginAt: user.LastFailedLoginAt,
1594
+ LastPasswordChangedAt: user.LastPasswordChangedAt,
1595
+ NeedToChangePasswordYN: user.NeedToChangePasswordYN,
1596
+ CreatedById: user.CreatedById,
1597
+ CreatedAt: user.CreatedAt,
1598
+ UpdatedById: user.UpdatedById,
1599
+ UpdatedAt: user.UpdatedAt,
1600
+ staffs: (user === null || user === void 0 ? void 0 : user.Staff) || null,
1601
+ };
1602
+ return new User(null, dbTransaction, userAttr);
1603
+ });
1604
+ }
1605
+ }
1606
+ exports.User = User;
1607
+ User._Repository = new user_repository_1.UserRepository();
1608
+ User._LoginHistoryRepository = new login_history_repository_1.LoginHistoryRepository();
1609
+ User._UserGroupRepo = new user_group_repository_1.UserGroupRepository();
1610
+ User._UserPrivilegeRepo = new user_privilege_repository_1.UserPrivilegeRepository();
1611
+ User._UserObjectPrivilegeRepo = new user_object_privilege_repository_1.UserObjectPrivilegeRepository();
1612
+ User._GroupObjectPrivilegeRepo = new group_object_privilege_repository_1.GroupObjectPrivilegeRepository();
1613
+ User._SystemRepository = new system_repository_1.SystemRepository();
1614
+ User._UserSystemAccessRepo = new user_system_access_repository_1.UserSystemAccessRepository();
1615
+ User._GroupSystemAccessRepo = new group_system_access_repository_1.GroupSystemAccessRepository();
1616
+ User._GroupRepo = new group_repository_1.GroupRepository();
1617
+ //# sourceMappingURL=user.js.map