@tomei/sso 0.2.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.husky/commit-msg +16 -0
- package/Jenkinsfile +0 -1
- package/__tests__/unit/components/login-user/login-user.spec.ts +482 -62
- package/dist/__tests__/unit/components/login-user/login-user.spec.js +429 -48
- package/dist/__tests__/unit/components/login-user/login-user.spec.js.map +1 -1
- package/dist/src/components/login-user/login-user.d.ts +1 -1
- package/dist/src/components/login-user/login-user.js +49 -44
- package/dist/src/components/login-user/login-user.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +1 -1
- package/package.json +8 -3
- package/src/components/login-user/login-user.ts +74 -70
package/index.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export * from "./src"
|
1
|
+
export * from "./src"
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tomei/sso",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.0",
|
4
4
|
"description": "Tomei SSO Package",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -41,6 +41,7 @@
|
|
41
41
|
"husky": "^8.0.3",
|
42
42
|
"jest": "^29.5.0",
|
43
43
|
"jest-mock-extended": "^3.0.4",
|
44
|
+
"lint-staged": "^13.2.2",
|
44
45
|
"prettier": "^2.7.1",
|
45
46
|
"prisma": "^4.14.0",
|
46
47
|
"redis-mock": "^0.56.3",
|
@@ -58,12 +59,16 @@
|
|
58
59
|
"@prisma/client": "^4.14.1",
|
59
60
|
"@tomei/general": "^0.1.0",
|
60
61
|
"@types/jest": "^29.5.2",
|
62
|
+
"argon2": "^0.30.3",
|
61
63
|
"cls-hooked": "^4.2.2",
|
62
64
|
"nodemailer": "^6.9.3",
|
63
65
|
"prismock": "^1.14.0",
|
64
66
|
"redis": "^4.6.7"
|
65
67
|
},
|
66
|
-
"
|
67
|
-
"
|
68
|
+
"lint-staged": {
|
69
|
+
"*/**/*.{js,ts,tsx}": [
|
70
|
+
"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
71
|
+
"eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
|
72
|
+
]
|
68
73
|
}
|
69
74
|
}
|
@@ -134,78 +134,82 @@ export class LoginUser extends ObjectBase implements IPerson {
|
|
134
134
|
password: string,
|
135
135
|
ipAddress: string,
|
136
136
|
): Promise<string> {
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
try {
|
138
|
+
//validate email
|
139
|
+
if (this.Email !== email) {
|
140
|
+
throw new Error('Invalid credentials.');
|
141
|
+
}
|
141
142
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
143
|
+
//validate password
|
144
|
+
const isPasswordValid = await this._PasswordHashService.verify(
|
145
|
+
password,
|
146
|
+
this.Password,
|
147
|
+
);
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
if (!isPasswordValid) {
|
150
|
+
throw new Error('Invalid credentials.');
|
151
|
+
}
|
151
152
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
153
|
+
//validate system code
|
154
|
+
const system = await LoginUser._SystemRepository.findOne({
|
155
|
+
where: {
|
156
|
+
code: systemCode,
|
157
|
+
},
|
158
|
+
});
|
158
159
|
|
159
|
-
|
160
|
-
|
161
|
-
|
160
|
+
if (!system) {
|
161
|
+
throw new Error('Invalid system code.');
|
162
|
+
}
|
163
|
+
|
164
|
+
//validate system access
|
165
|
+
await this.checkSystemAccess(this.ObjectId, system.id);
|
166
|
+
// alert user if new login
|
167
|
+
await this.alertNewLogin(this.ObjectId, system.id, ipAddress);
|
162
168
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
await this.alertNewLogin(this.ObjectId, system.id, ipAddress);
|
167
|
-
|
168
|
-
// fetch user session if exists
|
169
|
-
const userSession = await this._SessionService.retrieveUserSession(
|
170
|
-
this.ObjectId,
|
171
|
-
);
|
172
|
-
let systemLogin = userSession.systemLogins.find(
|
173
|
-
(system) => system.code === systemCode,
|
174
|
-
);
|
175
|
-
|
176
|
-
// generate new session id
|
177
|
-
const { randomUUID } = require('crypto');
|
178
|
-
const sessionId = randomUUID();
|
179
|
-
|
180
|
-
if (systemLogin) {
|
181
|
-
systemLogin = systemLogin.sessionId = sessionId;
|
182
|
-
userSession.systemLogins.map((system) =>
|
183
|
-
system.code === systemCode ? systemLogin : system,
|
169
|
+
// fetch user session if exists
|
170
|
+
const userSession = await this._SessionService.retrieveUserSession(
|
171
|
+
this.ObjectId,
|
184
172
|
);
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
173
|
+
let systemLogin = userSession.systemLogins.find(
|
174
|
+
(system) => system.code === systemCode,
|
175
|
+
);
|
176
|
+
|
177
|
+
// generate new session id
|
178
|
+
const { randomUUID } = require('crypto');
|
179
|
+
const sessionId = randomUUID();
|
180
|
+
|
181
|
+
if (systemLogin) {
|
182
|
+
systemLogin = systemLogin.sessionId = sessionId;
|
183
|
+
userSession.systemLogins.map((system) =>
|
184
|
+
system.code === systemCode ? systemLogin : system,
|
185
|
+
);
|
186
|
+
} else {
|
187
|
+
// if not, add new system login into the userSession
|
188
|
+
const newLogin = {
|
189
|
+
id: system.id.toString(),
|
190
|
+
code: system.code,
|
191
|
+
sessionId: sessionId,
|
192
|
+
privileges: await this.getPrivileges(system.code),
|
193
|
+
};
|
194
|
+
userSession.systemLogins.push(newLogin);
|
195
|
+
}
|
196
|
+
// then update userSession inside the redis storage with 1 day duration of time-to-live
|
197
|
+
this._SessionService.setUserSession(this.ObjectId, userSession);
|
207
198
|
|
208
|
-
|
199
|
+
// record new login history
|
200
|
+
await LoginUser._LoginHistoryRepository.create({
|
201
|
+
data: {
|
202
|
+
userId: this.ObjectId,
|
203
|
+
systemId: system.id,
|
204
|
+
originIp: ipAddress,
|
205
|
+
createdAt: new Date(),
|
206
|
+
},
|
207
|
+
});
|
208
|
+
|
209
|
+
return sessionId;
|
210
|
+
} catch (error) {
|
211
|
+
throw error;
|
212
|
+
}
|
209
213
|
}
|
210
214
|
|
211
215
|
private async checkSystemAccess(
|
@@ -252,7 +256,7 @@ export class LoginUser extends ObjectBase implements IPerson {
|
|
252
256
|
}
|
253
257
|
}
|
254
258
|
|
255
|
-
async getPrivileges(systemCode: string): Promise<string[]> {
|
259
|
+
private async getPrivileges(systemCode: string): Promise<string[]> {
|
256
260
|
try {
|
257
261
|
const system = await LoginUser._SystemRepository.findOne({
|
258
262
|
where: {
|
@@ -263,12 +267,12 @@ export class LoginUser extends ObjectBase implements IPerson {
|
|
263
267
|
if (!system) {
|
264
268
|
throw new Error('Invalid system code.');
|
265
269
|
}
|
270
|
+
|
266
271
|
// retrive user userGroups with system privileges
|
267
272
|
const userUserGroups = await this.getUserUserGroupFromDB(system.id);
|
268
273
|
|
269
274
|
// get all userGroup data from user userGroups
|
270
275
|
const userGroupData = userUserGroups.map((u) => u.userGroup);
|
271
|
-
|
272
276
|
// get all privileges from userGroup data
|
273
277
|
let privileges: string[] = [];
|
274
278
|
for (const userGroup of userGroupData) {
|
@@ -286,7 +290,7 @@ export class LoginUser extends ObjectBase implements IPerson {
|
|
286
290
|
) {
|
287
291
|
// get all parent tree privileges
|
288
292
|
const parentTreePrivileges = await this.getPrivilegesFromUserGroup(
|
289
|
-
userGroup.
|
293
|
+
userGroup.parentGroupCode,
|
290
294
|
);
|
291
295
|
|
292
296
|
privileges = [...privileges, ...parentTreePrivileges];
|
@@ -417,8 +421,8 @@ export class LoginUser extends ObjectBase implements IPerson {
|
|
417
421
|
(u) => u.systemPrivilege,
|
418
422
|
);
|
419
423
|
|
420
|
-
userSystemPrivileges =
|
421
|
-
(u) => u.
|
424
|
+
userSystemPrivileges = userSystemPrivileges.filter(
|
425
|
+
(u) => u.systemId === systemId,
|
422
426
|
);
|
423
427
|
|
424
428
|
const userPrivileges: string[] = userSystemPrivileges.map((u) => u.code);
|