@tomei/sso 0.66.1-test.3 → 0.66.1-test.4

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 (43) hide show
  1. package/__tests__/unit/components/login-user/login.spec.ts +271 -2
  2. package/__tests__/unit/components/login-user/password-expiry.spec.ts +87 -0
  3. package/dist/__tests__/unit/components/login-user/login.spec.js +199 -2
  4. package/dist/__tests__/unit/components/login-user/login.spec.js.map +1 -1
  5. package/dist/__tests__/unit/components/login-user/password-expiry.spec.d.ts +1 -0
  6. package/dist/__tests__/unit/components/login-user/password-expiry.spec.js +86 -0
  7. package/dist/__tests__/unit/components/login-user/password-expiry.spec.js.map +1 -0
  8. package/dist/src/components/login-user/interfaces/user-info.interface.d.ts +1 -0
  9. package/dist/src/components/login-user/user.d.ts +1 -0
  10. package/dist/src/components/login-user/user.js +7 -1
  11. package/dist/src/components/login-user/user.js.map +1 -1
  12. package/dist/src/components/system/system.d.ts +1 -0
  13. package/dist/src/components/system/system.js +1 -0
  14. package/dist/src/components/system/system.js.map +1 -1
  15. package/dist/src/components/system-privilege/system-privilege.d.ts +1 -0
  16. package/dist/src/components/system-privilege/system-privilege.js +2 -0
  17. package/dist/src/components/system-privilege/system-privilege.js.map +1 -1
  18. package/dist/src/interfaces/system-privilege.interface.d.ts +1 -0
  19. package/dist/src/interfaces/system.interface.d.ts +1 -0
  20. package/dist/src/models/group.entity.d.ts +1 -0
  21. package/dist/src/models/group.entity.js +8 -1
  22. package/dist/src/models/group.entity.js.map +1 -1
  23. package/dist/src/models/system-privilege.entity.d.ts +1 -0
  24. package/dist/src/models/system-privilege.entity.js +7 -0
  25. package/dist/src/models/system-privilege.entity.js.map +1 -1
  26. package/dist/src/models/system.entity.d.ts +1 -0
  27. package/dist/src/models/system.entity.js +7 -0
  28. package/dist/src/models/system.entity.js.map +1 -1
  29. package/dist/src/models/user.entity.d.ts +1 -0
  30. package/dist/src/models/user.entity.js +7 -0
  31. package/dist/src/models/user.entity.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +1 -1
  34. package/src/components/login-user/interfaces/user-info.interface.ts +1 -0
  35. package/src/components/login-user/user.ts +14 -2
  36. package/src/components/system/system.ts +2 -0
  37. package/src/components/system-privilege/system-privilege.ts +3 -0
  38. package/src/interfaces/system-privilege.interface.ts +1 -0
  39. package/src/interfaces/system.interface.ts +1 -0
  40. package/src/models/group.entity.ts +7 -1
  41. package/src/models/system-privilege.entity.ts +6 -0
  42. package/src/models/system.entity.ts +6 -0
  43. package/src/models/user.entity.ts +6 -0
@@ -71,7 +71,11 @@ describe('LoginUser', () => {
71
71
  dbTransaction = null;
72
72
  jest
73
73
  .spyOn(ComponentConfig, 'getComponentConfigValue')
74
- .mockReturnValue(mockLoginApiEndpoint as any);
74
+ .mockImplementation((componentName: string, configKey: string) =>
75
+ configKey === 'useLoginApiYN'
76
+ ? ('Y' as any)
77
+ : (mockLoginApiEndpoint as any),
78
+ );
75
79
  });
76
80
 
77
81
  it('should initialize LoginUser with valid userId', async () => {
@@ -136,6 +140,35 @@ describe('LoginUser', () => {
136
140
 
137
141
  expect(axiosPostMock).toHaveBeenCalledTimes(1);
138
142
  });
143
+
144
+ it('should initialize LoginUser via direct db query when useLoginApi is false', async () => {
145
+ jest
146
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
147
+ .mockImplementation((componentName: string, configKey: string) => {
148
+ if (configKey === 'useLoginApiYN') return 'N' as any;
149
+ return mockLoginApiEndpoint as any;
150
+ });
151
+
152
+ const findOneMock = jest
153
+ .spyOn(LoginUser['_Repository'], 'findOne')
154
+ .mockResolvedValueOnce(mockUserData as any);
155
+ const axiosPostMock = jest.spyOn(axios, 'post');
156
+
157
+ const result = await LoginUser.init(
158
+ sessionService,
159
+ userId,
160
+ dbTransaction,
161
+ );
162
+
163
+ expect(findOneMock).toHaveBeenCalledWith({
164
+ where: { UserId: userId },
165
+ include: [{ model: expect.anything() }],
166
+ transaction: dbTransaction,
167
+ });
168
+ expect(axiosPostMock).not.toHaveBeenCalled();
169
+ expect(result).toBeInstanceOf(LoginUser);
170
+ expect(result.Email).toBe(mockUserData.Email);
171
+ });
139
172
  });
140
173
 
141
174
  // describe('checkSession', () => {
@@ -876,7 +909,11 @@ describe('LoginUser', () => {
876
909
  .mockReturnValue('test-session' as any);
877
910
  jest
878
911
  .spyOn(ComponentConfig, 'getComponentConfigValue')
879
- .mockReturnValue(mockLoginApiEndpoint as any);
912
+ .mockImplementation((componentName: string, configKey: string) =>
913
+ configKey === 'useLoginApiYN'
914
+ ? ('Y' as any)
915
+ : (mockLoginApiEndpoint as any),
916
+ );
880
917
  });
881
918
 
882
919
  it('should return true if user has the specified privilege', async () => {
@@ -941,6 +978,238 @@ describe('LoginUser', () => {
941
978
  loginUser.checkPrivileges(systemCode, privilegeName),
942
979
  ).rejects.toThrow();
943
980
  });
981
+
982
+ it('should check the session privileges directly when useLoginApi is false', async () => {
983
+ const systemCode = 'SS';
984
+ const privilegeName = 'Privilege 1';
985
+ jest
986
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
987
+ .mockImplementation((componentName: string, configKey: string) => {
988
+ if (configKey === 'useLoginApiYN') return 'N' as any;
989
+ return mockLoginApiEndpoint as any;
990
+ });
991
+
992
+ const sessionService = await SessionService.init();
993
+ const loginUser = await LoginUser.init(sessionService);
994
+ loginUser.ObjectId = '1';
995
+ loginUser['_SessionService'].retrieveUserSession = jest
996
+ .fn()
997
+ .mockResolvedValue({
998
+ systemLogins: [{ code: systemCode, privileges: [privilegeName] }],
999
+ });
1000
+
1001
+ const axiosPostMock = jest.spyOn(axios, 'post');
1002
+
1003
+ const hasPrivilege = await loginUser.checkPrivileges(
1004
+ systemCode,
1005
+ privilegeName,
1006
+ );
1007
+
1008
+ expect(hasPrivilege).toBe(true);
1009
+ expect(axiosPostMock).not.toHaveBeenCalled();
1010
+ });
1011
+ });
1012
+
1013
+ describe('checkSession', () => {
1014
+ const mockLoginApiEndpoint = {
1015
+ baseUrl: 'http://sso-api',
1016
+ checkSession: '/check-session',
1017
+ apiKey: 'test-api-key',
1018
+ };
1019
+
1020
+ beforeEach(() => {
1021
+ jest
1022
+ .spyOn(ApplicationConfig, 'getComponentConfigValue')
1023
+ .mockReturnValue('test-session' as any);
1024
+ });
1025
+
1026
+ it('should call the login-api endpoint when useLoginApi is true', async () => {
1027
+ jest
1028
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
1029
+ .mockImplementation((componentName: string, configKey: string) =>
1030
+ configKey === 'useLoginApiYN'
1031
+ ? ('Y' as any)
1032
+ : (mockLoginApiEndpoint as any),
1033
+ );
1034
+
1035
+ const systemCode = 'SS';
1036
+ const sessionId = 'session-1';
1037
+ const userId = '1';
1038
+ const sessionService = await SessionService.init();
1039
+ const loginUser = await LoginUser.init(sessionService);
1040
+
1041
+ const mockSystemLogin = { code: systemCode, sessionId };
1042
+ const axiosPostMock = jest
1043
+ .spyOn(axios, 'post')
1044
+ .mockResolvedValueOnce({
1045
+ data: { systemLogin: mockSystemLogin },
1046
+ } as any);
1047
+
1048
+ const systemLogin = await loginUser.checkSession(
1049
+ systemCode,
1050
+ sessionId,
1051
+ userId,
1052
+ );
1053
+
1054
+ expect(systemLogin).toEqual(mockSystemLogin);
1055
+ expect(axiosPostMock).toHaveBeenCalledWith(
1056
+ `${mockLoginApiEndpoint.baseUrl}${mockLoginApiEndpoint.checkSession}`,
1057
+ {
1058
+ SystemCode: systemCode,
1059
+ SessionName: 'test-session',
1060
+ SessionId: sessionId,
1061
+ UserId: userId,
1062
+ },
1063
+ {
1064
+ headers: {
1065
+ 'Content-Type': 'application/json',
1066
+ 'x-api-key': mockLoginApiEndpoint.apiKey,
1067
+ },
1068
+ },
1069
+ );
1070
+ });
1071
+
1072
+ it('should validate the session directly against redis when useLoginApi is false', async () => {
1073
+ jest
1074
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
1075
+ .mockImplementation((componentName: string, configKey: string) => {
1076
+ if (configKey === 'useLoginApiYN') return 'N' as any;
1077
+ return mockLoginApiEndpoint as any;
1078
+ });
1079
+
1080
+ const systemCode = 'SS';
1081
+ const sessionId = 'session-1';
1082
+ const userId = '1';
1083
+ const sessionService = await SessionService.init();
1084
+ const loginUser = await LoginUser.init(sessionService);
1085
+
1086
+ const mockSystemLogin = { code: systemCode, sessionId };
1087
+ loginUser['_SessionService'].retrieveUserSession = jest
1088
+ .fn()
1089
+ .mockResolvedValue({ systemLogins: [mockSystemLogin] });
1090
+ loginUser['_SessionService'].refreshDuration = jest.fn();
1091
+
1092
+ const axiosPostMock = jest.spyOn(axios, 'post');
1093
+
1094
+ const systemLogin = await loginUser.checkSession(
1095
+ systemCode,
1096
+ sessionId,
1097
+ userId,
1098
+ );
1099
+
1100
+ expect(systemLogin).toEqual(mockSystemLogin);
1101
+ expect(
1102
+ loginUser['_SessionService'].refreshDuration,
1103
+ ).toHaveBeenCalledWith(userId, 'test-session');
1104
+ expect(axiosPostMock).not.toHaveBeenCalled();
1105
+ });
1106
+
1107
+ it('should throw "Session expired." when useLoginApi is false and the session is stale', async () => {
1108
+ jest
1109
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
1110
+ .mockImplementation((componentName: string, configKey: string) => {
1111
+ if (configKey === 'useLoginApiYN') return 'N' as any;
1112
+ return mockLoginApiEndpoint as any;
1113
+ });
1114
+
1115
+ const sessionService = await SessionService.init();
1116
+ const loginUser = await LoginUser.init(sessionService);
1117
+ loginUser['_SessionService'].retrieveUserSession = jest
1118
+ .fn()
1119
+ .mockResolvedValue({ systemLogins: [] });
1120
+
1121
+ await expect(
1122
+ loginUser.checkSession('SS', 'session-1', '1'),
1123
+ ).rejects.toThrow('Session expired.');
1124
+ });
1125
+ });
1126
+
1127
+ describe('setSession', () => {
1128
+ const mockLoginApiEndpoint = {
1129
+ baseUrl: 'http://sso-api',
1130
+ setSession: '/set-session',
1131
+ apiKey: 'test-api-key',
1132
+ };
1133
+
1134
+ beforeEach(() => {
1135
+ jest
1136
+ .spyOn(ApplicationConfig, 'getComponentConfigValue')
1137
+ .mockReturnValue('test-session' as any);
1138
+ });
1139
+
1140
+ it('should call the login-api endpoint when useLoginApi is true', async () => {
1141
+ jest
1142
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
1143
+ .mockImplementation((componentName: string, configKey: string) =>
1144
+ configKey === 'useLoginApiYN'
1145
+ ? ('Y' as any)
1146
+ : (mockLoginApiEndpoint as any),
1147
+ );
1148
+
1149
+ const systemCode = 'SS';
1150
+ const sessionId = 'session-1';
1151
+ const sessionService = await SessionService.init();
1152
+ const loginUser = await LoginUser.init(sessionService);
1153
+ loginUser.ObjectId = '1';
1154
+
1155
+ const axiosPostMock = jest
1156
+ .spyOn(axios, 'post')
1157
+ .mockResolvedValueOnce({ data: {} } as any);
1158
+
1159
+ await loginUser.setSession(systemCode, sessionId, null);
1160
+
1161
+ expect(axiosPostMock).toHaveBeenCalledWith(
1162
+ `${mockLoginApiEndpoint.baseUrl}${mockLoginApiEndpoint.setSession}`,
1163
+ {
1164
+ SystemCode: systemCode,
1165
+ SessionName: 'test-session',
1166
+ SessionId: sessionId,
1167
+ UserId: '1',
1168
+ },
1169
+ {
1170
+ headers: {
1171
+ 'Content-Type': 'application/json',
1172
+ 'x-api-key': mockLoginApiEndpoint.apiKey,
1173
+ },
1174
+ },
1175
+ );
1176
+ });
1177
+
1178
+ it('should persist the session directly to redis when useLoginApi is false', async () => {
1179
+ jest
1180
+ .spyOn(ComponentConfig, 'getComponentConfigValue')
1181
+ .mockImplementation((componentName: string, configKey: string) => {
1182
+ if (configKey === 'useLoginApiYN') return 'N' as any;
1183
+ return mockLoginApiEndpoint as any;
1184
+ });
1185
+
1186
+ const systemCode = 'SS';
1187
+ const sessionId = 'session-1';
1188
+ const sessionService = await SessionService.init();
1189
+ const loginUser = await LoginUser.init(sessionService);
1190
+ loginUser.ObjectId = '1';
1191
+
1192
+ jest.spyOn(loginUser, 'getPrivileges').mockResolvedValue(['privilege1']);
1193
+ loginUser['_SessionService'].retrieveUserSession = jest
1194
+ .fn()
1195
+ .mockResolvedValue({ systemLogins: [] });
1196
+ loginUser['_SessionService'].setUserSession = jest.fn();
1197
+
1198
+ const axiosPostMock = jest.spyOn(axios, 'post');
1199
+
1200
+ await loginUser.setSession(systemCode, sessionId, null);
1201
+
1202
+ expect(axiosPostMock).not.toHaveBeenCalled();
1203
+ expect(loginUser['_SessionService'].setUserSession).toHaveBeenCalledWith(
1204
+ '1',
1205
+ {
1206
+ systemLogins: [
1207
+ { id: systemCode, code: systemCode, sessionId, privileges: ['privilege1'] },
1208
+ ],
1209
+ },
1210
+ 'test-session',
1211
+ );
1212
+ });
944
1213
  });
945
1214
 
946
1215
  describe('getObjectPrivileges', () => {
@@ -0,0 +1,87 @@
1
+ import { User } from '../../../../src/components/login-user/user';
2
+ import { UserPasswordHistory } from '../../../../src/components/user-password-history/user-password-history';
3
+ import { YN } from '../../../../src/enum/yn.enum';
4
+
5
+ // User and LoginUser import each other; this test exercises only User's expiry policy.
6
+ jest.mock('../../../../src/components/login-user/login-user', () => ({
7
+ LoginUser: class {},
8
+ }));
9
+
10
+ describe('User.getPasswordExpiryStatus', () => {
11
+ const originalExpiryMonths = process.env.PASSWORD_EXPIRY_MONTHS;
12
+ const originalWarningDays = process.env.PASSWORD_EXPIRY_WARNING_DAYS;
13
+
14
+ const user = (password: string | null) =>
15
+ Object.assign(Object.create(User.prototype), {
16
+ ObjectId: '123',
17
+ _Password: password,
18
+ _NeedToChangePasswordYN: YN.No,
19
+ }) as User;
20
+
21
+ beforeEach(() => {
22
+ process.env.PASSWORD_EXPIRY_MONTHS = '1';
23
+ process.env.PASSWORD_EXPIRY_WARNING_DAYS = '14';
24
+ jest.useFakeTimers().setSystemTime(new Date('2026-02-20T12:00:00Z'));
25
+ });
26
+
27
+ afterEach(() => {
28
+ jest.restoreAllMocks();
29
+ jest.useRealTimers();
30
+ if (originalExpiryMonths === undefined)
31
+ delete process.env.PASSWORD_EXPIRY_MONTHS;
32
+ else process.env.PASSWORD_EXPIRY_MONTHS = originalExpiryMonths;
33
+ if (originalWarningDays === undefined)
34
+ delete process.env.PASSWORD_EXPIRY_WARNING_DAYS;
35
+ else process.env.PASSWORD_EXPIRY_WARNING_DAYS = originalWarningDays;
36
+ });
37
+
38
+ it('disables expiry when the period is zero', async () => {
39
+ process.env.PASSWORD_EXPIRY_MONTHS = '0';
40
+ const lookup = jest.spyOn(UserPasswordHistory, 'getLatestByUserId');
41
+
42
+ expect(await user('hash').getPasswordExpiryStatus()).toEqual({
43
+ expired: false,
44
+ expiringSoon: false,
45
+ expiresInDays: null,
46
+ });
47
+ expect(lookup).not.toHaveBeenCalled();
48
+ });
49
+
50
+ it('skips an account without a local password', async () => {
51
+ const lookup = jest.spyOn(UserPasswordHistory, 'getLatestByUserId');
52
+
53
+ expect(await user(null).getPasswordExpiryStatus()).toEqual({
54
+ expired: false,
55
+ expiringSoon: false,
56
+ expiresInDays: null,
57
+ });
58
+ expect(lookup).not.toHaveBeenCalled();
59
+ });
60
+
61
+ it('expires an account without password history', async () => {
62
+ jest
63
+ .spyOn(UserPasswordHistory, 'getLatestByUserId')
64
+ .mockResolvedValue(null);
65
+
66
+ expect(await user('hash').getPasswordExpiryStatus()).toEqual({
67
+ expired: true,
68
+ expiringSoon: false,
69
+ expiresInDays: null,
70
+ });
71
+ });
72
+
73
+ it('warns before expiry and clamps month-end dates', async () => {
74
+ jest.spyOn(UserPasswordHistory, 'getLatestByUserId').mockResolvedValue({
75
+ CreatedAt: new Date('2026-01-31T12:00:00Z'),
76
+ } as UserPasswordHistory);
77
+
78
+ expect(await user('hash').getPasswordExpiryStatus()).toEqual({
79
+ expired: false,
80
+ expiringSoon: true,
81
+ expiresInDays: 8,
82
+ });
83
+
84
+ jest.setSystemTime(new Date('2026-02-28T12:00:00Z'));
85
+ expect((await user('hash').getPasswordExpiryStatus()).expired).toBe(true);
86
+ });
87
+ });
@@ -72,7 +72,9 @@ describe('LoginUser', () => {
72
72
  dbTransaction = null;
73
73
  jest
74
74
  .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
75
- .mockReturnValue(mockLoginApiEndpoint);
75
+ .mockImplementation((componentName, configKey) => configKey === 'useLoginApiYN'
76
+ ? 'Y'
77
+ : mockLoginApiEndpoint);
76
78
  });
77
79
  it('should initialize LoginUser with valid userId', () => __awaiter(void 0, void 0, void 0, function* () {
78
80
  const user = {
@@ -120,6 +122,28 @@ describe('LoginUser', () => {
120
122
  yield expect(login_user_1.LoginUser.init(sessionService, userId, dbTransaction)).rejects.toThrow(Error);
121
123
  expect(axiosPostMock).toHaveBeenCalledTimes(1);
122
124
  }));
125
+ it('should initialize LoginUser via direct db query when useLoginApi is false', () => __awaiter(void 0, void 0, void 0, function* () {
126
+ jest
127
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
128
+ .mockImplementation((componentName, configKey) => {
129
+ if (configKey === 'useLoginApiYN')
130
+ return 'N';
131
+ return mockLoginApiEndpoint;
132
+ });
133
+ const findOneMock = jest
134
+ .spyOn(login_user_1.LoginUser['_Repository'], 'findOne')
135
+ .mockResolvedValueOnce(mockUserData);
136
+ const axiosPostMock = jest.spyOn(axios_1.default, 'post');
137
+ const result = yield login_user_1.LoginUser.init(sessionService, userId, dbTransaction);
138
+ expect(findOneMock).toHaveBeenCalledWith({
139
+ where: { UserId: userId },
140
+ include: [{ model: expect.anything() }],
141
+ transaction: dbTransaction,
142
+ });
143
+ expect(axiosPostMock).not.toHaveBeenCalled();
144
+ expect(result).toBeInstanceOf(login_user_1.LoginUser);
145
+ expect(result.Email).toBe(mockUserData.Email);
146
+ }));
123
147
  });
124
148
  describe('shouldReleaseLock', () => {
125
149
  const minuteToAutoRelease = 5;
@@ -452,7 +476,9 @@ describe('LoginUser', () => {
452
476
  .mockReturnValue('test-session');
453
477
  jest
454
478
  .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
455
- .mockReturnValue(mockLoginApiEndpoint);
479
+ .mockImplementation((componentName, configKey) => configKey === 'useLoginApiYN'
480
+ ? 'Y'
481
+ : mockLoginApiEndpoint);
456
482
  });
457
483
  it('should return true if user has the specified privilege', () => __awaiter(void 0, void 0, void 0, function* () {
458
484
  const systemCode = 'SS';
@@ -487,6 +513,177 @@ describe('LoginUser', () => {
487
513
  loginUser.ObjectId = null;
488
514
  yield expect(loginUser.checkPrivileges(systemCode, privilegeName)).rejects.toThrow();
489
515
  }));
516
+ it('should check the session privileges directly when useLoginApi is false', () => __awaiter(void 0, void 0, void 0, function* () {
517
+ const systemCode = 'SS';
518
+ const privilegeName = 'Privilege 1';
519
+ jest
520
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
521
+ .mockImplementation((componentName, configKey) => {
522
+ if (configKey === 'useLoginApiYN')
523
+ return 'N';
524
+ return mockLoginApiEndpoint;
525
+ });
526
+ const sessionService = yield session_service_1.SessionService.init();
527
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
528
+ loginUser.ObjectId = '1';
529
+ loginUser['_SessionService'].retrieveUserSession = jest
530
+ .fn()
531
+ .mockResolvedValue({
532
+ systemLogins: [{ code: systemCode, privileges: [privilegeName] }],
533
+ });
534
+ const axiosPostMock = jest.spyOn(axios_1.default, 'post');
535
+ const hasPrivilege = yield loginUser.checkPrivileges(systemCode, privilegeName);
536
+ expect(hasPrivilege).toBe(true);
537
+ expect(axiosPostMock).not.toHaveBeenCalled();
538
+ }));
539
+ });
540
+ describe('checkSession', () => {
541
+ const mockLoginApiEndpoint = {
542
+ baseUrl: 'http://sso-api',
543
+ checkSession: '/check-session',
544
+ apiKey: 'test-api-key',
545
+ };
546
+ beforeEach(() => {
547
+ jest
548
+ .spyOn(config_1.ApplicationConfig, 'getComponentConfigValue')
549
+ .mockReturnValue('test-session');
550
+ });
551
+ it('should call the login-api endpoint when useLoginApi is true', () => __awaiter(void 0, void 0, void 0, function* () {
552
+ jest
553
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
554
+ .mockImplementation((componentName, configKey) => configKey === 'useLoginApiYN'
555
+ ? 'Y'
556
+ : mockLoginApiEndpoint);
557
+ const systemCode = 'SS';
558
+ const sessionId = 'session-1';
559
+ const userId = '1';
560
+ const sessionService = yield session_service_1.SessionService.init();
561
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
562
+ const mockSystemLogin = { code: systemCode, sessionId };
563
+ const axiosPostMock = jest
564
+ .spyOn(axios_1.default, 'post')
565
+ .mockResolvedValueOnce({
566
+ data: { systemLogin: mockSystemLogin },
567
+ });
568
+ const systemLogin = yield loginUser.checkSession(systemCode, sessionId, userId);
569
+ expect(systemLogin).toEqual(mockSystemLogin);
570
+ expect(axiosPostMock).toHaveBeenCalledWith(`${mockLoginApiEndpoint.baseUrl}${mockLoginApiEndpoint.checkSession}`, {
571
+ SystemCode: systemCode,
572
+ SessionName: 'test-session',
573
+ SessionId: sessionId,
574
+ UserId: userId,
575
+ }, {
576
+ headers: {
577
+ 'Content-Type': 'application/json',
578
+ 'x-api-key': mockLoginApiEndpoint.apiKey,
579
+ },
580
+ });
581
+ }));
582
+ it('should validate the session directly against redis when useLoginApi is false', () => __awaiter(void 0, void 0, void 0, function* () {
583
+ jest
584
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
585
+ .mockImplementation((componentName, configKey) => {
586
+ if (configKey === 'useLoginApiYN')
587
+ return 'N';
588
+ return mockLoginApiEndpoint;
589
+ });
590
+ const systemCode = 'SS';
591
+ const sessionId = 'session-1';
592
+ const userId = '1';
593
+ const sessionService = yield session_service_1.SessionService.init();
594
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
595
+ const mockSystemLogin = { code: systemCode, sessionId };
596
+ loginUser['_SessionService'].retrieveUserSession = jest
597
+ .fn()
598
+ .mockResolvedValue({ systemLogins: [mockSystemLogin] });
599
+ loginUser['_SessionService'].refreshDuration = jest.fn();
600
+ const axiosPostMock = jest.spyOn(axios_1.default, 'post');
601
+ const systemLogin = yield loginUser.checkSession(systemCode, sessionId, userId);
602
+ expect(systemLogin).toEqual(mockSystemLogin);
603
+ expect(loginUser['_SessionService'].refreshDuration).toHaveBeenCalledWith(userId, 'test-session');
604
+ expect(axiosPostMock).not.toHaveBeenCalled();
605
+ }));
606
+ it('should throw "Session expired." when useLoginApi is false and the session is stale', () => __awaiter(void 0, void 0, void 0, function* () {
607
+ jest
608
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
609
+ .mockImplementation((componentName, configKey) => {
610
+ if (configKey === 'useLoginApiYN')
611
+ return 'N';
612
+ return mockLoginApiEndpoint;
613
+ });
614
+ const sessionService = yield session_service_1.SessionService.init();
615
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
616
+ loginUser['_SessionService'].retrieveUserSession = jest
617
+ .fn()
618
+ .mockResolvedValue({ systemLogins: [] });
619
+ yield expect(loginUser.checkSession('SS', 'session-1', '1')).rejects.toThrow('Session expired.');
620
+ }));
621
+ });
622
+ describe('setSession', () => {
623
+ const mockLoginApiEndpoint = {
624
+ baseUrl: 'http://sso-api',
625
+ setSession: '/set-session',
626
+ apiKey: 'test-api-key',
627
+ };
628
+ beforeEach(() => {
629
+ jest
630
+ .spyOn(config_1.ApplicationConfig, 'getComponentConfigValue')
631
+ .mockReturnValue('test-session');
632
+ });
633
+ it('should call the login-api endpoint when useLoginApi is true', () => __awaiter(void 0, void 0, void 0, function* () {
634
+ jest
635
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
636
+ .mockImplementation((componentName, configKey) => configKey === 'useLoginApiYN'
637
+ ? 'Y'
638
+ : mockLoginApiEndpoint);
639
+ const systemCode = 'SS';
640
+ const sessionId = 'session-1';
641
+ const sessionService = yield session_service_1.SessionService.init();
642
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
643
+ loginUser.ObjectId = '1';
644
+ const axiosPostMock = jest
645
+ .spyOn(axios_1.default, 'post')
646
+ .mockResolvedValueOnce({ data: {} });
647
+ yield loginUser.setSession(systemCode, sessionId, null);
648
+ expect(axiosPostMock).toHaveBeenCalledWith(`${mockLoginApiEndpoint.baseUrl}${mockLoginApiEndpoint.setSession}`, {
649
+ SystemCode: systemCode,
650
+ SessionName: 'test-session',
651
+ SessionId: sessionId,
652
+ UserId: '1',
653
+ }, {
654
+ headers: {
655
+ 'Content-Type': 'application/json',
656
+ 'x-api-key': mockLoginApiEndpoint.apiKey,
657
+ },
658
+ });
659
+ }));
660
+ it('should persist the session directly to redis when useLoginApi is false', () => __awaiter(void 0, void 0, void 0, function* () {
661
+ jest
662
+ .spyOn(config_1.ComponentConfig, 'getComponentConfigValue')
663
+ .mockImplementation((componentName, configKey) => {
664
+ if (configKey === 'useLoginApiYN')
665
+ return 'N';
666
+ return mockLoginApiEndpoint;
667
+ });
668
+ const systemCode = 'SS';
669
+ const sessionId = 'session-1';
670
+ const sessionService = yield session_service_1.SessionService.init();
671
+ const loginUser = yield login_user_1.LoginUser.init(sessionService);
672
+ loginUser.ObjectId = '1';
673
+ jest.spyOn(loginUser, 'getPrivileges').mockResolvedValue(['privilege1']);
674
+ loginUser['_SessionService'].retrieveUserSession = jest
675
+ .fn()
676
+ .mockResolvedValue({ systemLogins: [] });
677
+ loginUser['_SessionService'].setUserSession = jest.fn();
678
+ const axiosPostMock = jest.spyOn(axios_1.default, 'post');
679
+ yield loginUser.setSession(systemCode, sessionId, null);
680
+ expect(axiosPostMock).not.toHaveBeenCalled();
681
+ expect(loginUser['_SessionService'].setUserSession).toHaveBeenCalledWith('1', {
682
+ systemLogins: [
683
+ { id: systemCode, code: systemCode, sessionId, privileges: ['privilege1'] },
684
+ ],
685
+ }, 'test-session');
686
+ }));
490
687
  });
491
688
  describe('getObjectPrivileges', () => {
492
689
  it('should return an array of privileges', () => __awaiter(void 0, void 0, void 0, function* () {