@tomei/sso 0.48.4 → 0.49.1
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/src/components/login-user/login-user.js.map +1 -1
- package/dist/src/components/login-user/user.d.ts +7 -0
- package/dist/src/components/login-user/user.js +58 -0
- package/dist/src/components/login-user/user.js.map +1 -1
- package/dist/src/components/system-privilege/system-privilege.js +3 -1
- package/dist/src/components/system-privilege/system-privilege.js.map +1 -1
- package/dist/src/redis-client/redis.service.d.ts +1 -0
- package/dist/src/redis-client/redis.service.js +10 -0
- package/dist/src/redis-client/redis.service.js.map +1 -1
- package/dist/src/session/interfaces/session-service.interface.d.ts +3 -0
- package/dist/src/session/session.service.d.ts +3 -0
- package/dist/src/session/session.service.js +33 -0
- package/dist/src/session/session.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/login-user/login-user.ts +1 -0
- package/src/components/login-user/user.ts +107 -1
- package/src/components/system-privilege/system-privilege.ts +3 -1
- package/src/redis-client/redis.service.ts +8 -0
- package/src/session/interfaces/session-service.interface.ts +7 -0
- package/src/session/session.service.ts +31 -0
package/package.json
CHANGED
@@ -7,6 +7,7 @@ import { RedisService } from '../../redis-client/redis.service';
|
|
7
7
|
import { UserRepository } from './user.repository';
|
8
8
|
import { IUserAttr, IUserInfo } from './interfaces/user-info.interface';
|
9
9
|
import Staff from '../../models/staff.entity';
|
10
|
+
import { createHash, randomBytes } from 'crypto';
|
10
11
|
|
11
12
|
export class LoginUser extends User implements ILoginUser {
|
12
13
|
session = {
|
@@ -32,7 +32,7 @@ import { LoginStatusEnum } from '../../enum/login-status.enum';
|
|
32
32
|
import { RedisService } from '../../redis-client/redis.service';
|
33
33
|
import { LoginUser } from './login-user';
|
34
34
|
import { SessionService } from '../../session/session.service';
|
35
|
-
import { randomUUID } from 'crypto';
|
35
|
+
import { createHash, randomBytes, randomUUID } from 'crypto';
|
36
36
|
|
37
37
|
export class User extends UserBase {
|
38
38
|
ObjectId: string;
|
@@ -1271,6 +1271,112 @@ export class User extends UserBase {
|
|
1271
1271
|
}
|
1272
1272
|
}
|
1273
1273
|
|
1274
|
+
public async generateAuthorizationToken(): Promise<{
|
1275
|
+
plaintextToken: string;
|
1276
|
+
hashedToken: string;
|
1277
|
+
}> {
|
1278
|
+
// Generate a random token
|
1279
|
+
const plaintextToken = randomBytes(32).toString('hex'); // 64-character hex string
|
1280
|
+
|
1281
|
+
// Hash the token using SHA-256
|
1282
|
+
const hashedToken = createHash('sha256')
|
1283
|
+
.update(plaintextToken)
|
1284
|
+
.digest('hex');
|
1285
|
+
|
1286
|
+
// Save the hashed token to Redis
|
1287
|
+
this._SessionService.setAuthorizationCode(
|
1288
|
+
hashedToken,
|
1289
|
+
this.ObjectId,
|
1290
|
+
60 * 60 * 24,
|
1291
|
+
); // 24 hours
|
1292
|
+
|
1293
|
+
// Return the plaintext token for the user to use
|
1294
|
+
return { plaintextToken, hashedToken };
|
1295
|
+
}
|
1296
|
+
|
1297
|
+
public async validateAuthorizationToken(
|
1298
|
+
autorizationToken: string,
|
1299
|
+
): Promise<string> {
|
1300
|
+
try {
|
1301
|
+
const hashedSubmittedToken = createHash('sha256')
|
1302
|
+
.update(autorizationToken)
|
1303
|
+
.digest('hex');
|
1304
|
+
|
1305
|
+
// Check if the token exists in Redis
|
1306
|
+
const userId = await this._SessionService.retrieveAuthorizationCode(
|
1307
|
+
hashedSubmittedToken,
|
1308
|
+
);
|
1309
|
+
if (!userId) {
|
1310
|
+
return null;
|
1311
|
+
}
|
1312
|
+
|
1313
|
+
await this._SessionService.deleteAuthorizationCode(hashedSubmittedToken);
|
1314
|
+
return userId;
|
1315
|
+
} catch (error) {
|
1316
|
+
throw error;
|
1317
|
+
}
|
1318
|
+
}
|
1319
|
+
|
1320
|
+
public static async resetPassword(
|
1321
|
+
sessionService: ISessionService,
|
1322
|
+
autorizationToken: string,
|
1323
|
+
password: string,
|
1324
|
+
dbTransaction: any,
|
1325
|
+
): Promise<void> {
|
1326
|
+
try {
|
1327
|
+
const hashedSubmittedToken = createHash('sha256')
|
1328
|
+
.update(autorizationToken)
|
1329
|
+
.digest('hex');
|
1330
|
+
|
1331
|
+
// Check if the token exists in Redis
|
1332
|
+
const userId = await sessionService.retrieveAuthorizationCode(
|
1333
|
+
hashedSubmittedToken,
|
1334
|
+
);
|
1335
|
+
if (!userId) {
|
1336
|
+
// Token is not valid, throw an error
|
1337
|
+
throw new ClassError(
|
1338
|
+
'LoginUser',
|
1339
|
+
'LoginUserErrMsg0X',
|
1340
|
+
'Invalid token',
|
1341
|
+
'setupFirstPassword',
|
1342
|
+
401,
|
1343
|
+
);
|
1344
|
+
}
|
1345
|
+
|
1346
|
+
await sessionService.deleteAuthorizationCode(hashedSubmittedToken);
|
1347
|
+
console.log(`Token verified for user: ${userId}`);
|
1348
|
+
|
1349
|
+
//Instantiate user
|
1350
|
+
const user = await User.init(
|
1351
|
+
sessionService,
|
1352
|
+
parseInt(userId),
|
1353
|
+
dbTransaction,
|
1354
|
+
);
|
1355
|
+
|
1356
|
+
//Set new password
|
1357
|
+
await User.setPassword(dbTransaction, user, password);
|
1358
|
+
|
1359
|
+
//Update user record
|
1360
|
+
await User._Repository.update(
|
1361
|
+
{
|
1362
|
+
Password: user._Password,
|
1363
|
+
DefaultPasswordChangedYN: YN.Yes,
|
1364
|
+
NeedToChangePasswordYN: YN.No,
|
1365
|
+
},
|
1366
|
+
{
|
1367
|
+
where: {
|
1368
|
+
UserId: user.UserId,
|
1369
|
+
},
|
1370
|
+
transaction: dbTransaction,
|
1371
|
+
},
|
1372
|
+
);
|
1373
|
+
} catch (error) {
|
1374
|
+
throw error;
|
1375
|
+
}
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
public async;
|
1379
|
+
|
1274
1380
|
public static async create(
|
1275
1381
|
loginUser: User,
|
1276
1382
|
dbTransaction: any,
|
@@ -196,7 +196,9 @@ export class SystemPrivilege extends ObjectBase {
|
|
196
196
|
CreatedAt: newSystemPrivilege._CreatedAt,
|
197
197
|
UpdatedAt: newSystemPrivilege._UpdatedAt,
|
198
198
|
},
|
199
|
-
|
199
|
+
{
|
200
|
+
transaction: dbTransaction,
|
201
|
+
},
|
200
202
|
);
|
201
203
|
|
202
204
|
//Part 4: Record Create Privilege Activity
|
@@ -57,6 +57,14 @@ export class RedisService {
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|
60
|
+
public async del(key: string): Promise<void> {
|
61
|
+
try {
|
62
|
+
await RedisService.client.del(key);
|
63
|
+
} catch (error) {
|
64
|
+
throw error;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
60
68
|
public static async close(): Promise<void> {
|
61
69
|
try {
|
62
70
|
await RedisService.client.disconnect();
|
@@ -4,4 +4,11 @@ export interface ISessionService {
|
|
4
4
|
retrieveUserSession(userId: string): Promise<IUserSession>;
|
5
5
|
setUserSession(userId: string, sessionData: IUserSession): Promise<void>;
|
6
6
|
refreshDuration(userId: string): Promise<void>;
|
7
|
+
setAuthorizationCode(
|
8
|
+
token: string,
|
9
|
+
value: string,
|
10
|
+
expire: number,
|
11
|
+
): Promise<void>;
|
12
|
+
retrieveAuthorizationCode(token: string): Promise<string>;
|
13
|
+
deleteAuthorizationCode(token: string): Promise<void>;
|
7
14
|
}
|
@@ -51,4 +51,35 @@ export class SessionService implements ISessionService {
|
|
51
51
|
throw error;
|
52
52
|
}
|
53
53
|
}
|
54
|
+
|
55
|
+
async setAuthorizationCode(
|
56
|
+
token: string,
|
57
|
+
value: string,
|
58
|
+
expire: number,
|
59
|
+
): Promise<void> {
|
60
|
+
try {
|
61
|
+
const key = `tomei-auth-code:${token}`;
|
62
|
+
await SessionService._RedisService.set(key, value, expire);
|
63
|
+
} catch (error) {
|
64
|
+
throw error;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
async retrieveAuthorizationCode(token: string): Promise<string> {
|
69
|
+
try {
|
70
|
+
const key = `tomei-auth-code:${token}`;
|
71
|
+
return await SessionService._RedisService.get(key);
|
72
|
+
} catch (error) {
|
73
|
+
throw error;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
async deleteAuthorizationCode(token: string): Promise<void> {
|
78
|
+
try {
|
79
|
+
const key = `tomei-auth-code:${token}`;
|
80
|
+
await SessionService._RedisService.del(key);
|
81
|
+
} catch (error) {
|
82
|
+
throw error;
|
83
|
+
}
|
84
|
+
}
|
54
85
|
}
|