@tomei/sso 0.60.4-dev.1 → 0.60.4-dev.10
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/coverage/lcov-report/components/login-user/login-user.ts.html +80 -73
- package/dist/src/components/login-history/index.d.ts +1 -0
- package/dist/src/components/login-history/index.js +1 -0
- package/dist/src/components/login-history/index.js.map +1 -1
- package/dist/src/components/login-history/login-history.d.ts +23 -0
- package/dist/src/components/login-history/login-history.js +88 -0
- package/dist/src/components/login-history/login-history.js.map +1 -0
- package/dist/src/components/login-history/login-history.repository.d.ts +2 -2
- package/dist/src/components/login-history/login-history.repository.js.map +1 -1
- package/dist/src/components/login-user/interfaces/user-info.interface.d.ts +1 -0
- package/dist/src/components/login-user/login-user.js +1 -0
- package/dist/src/components/login-user/login-user.js.map +1 -1
- package/dist/src/components/login-user/user.d.ts +28 -3
- package/dist/src/components/login-user/user.js +356 -13
- package/dist/src/components/login-user/user.js.map +1 -1
- package/dist/src/components/user-system-access/user-system-access.js +1 -1
- package/dist/src/components/user-system-access/user-system-access.js.map +1 -1
- package/dist/src/interfaces/login-history-search-attr.interface.d.ts +8 -0
- package/dist/src/interfaces/login-history-search-attr.interface.js +3 -0
- package/dist/src/interfaces/login-history-search-attr.interface.js.map +1 -0
- package/dist/src/interfaces/login-history.interface.d.ts +11 -0
- package/dist/src/interfaces/login-history.interface.js +3 -0
- package/dist/src/interfaces/login-history.interface.js.map +1 -0
- package/dist/src/models/login-history.entity.d.ts +2 -2
- package/dist/src/models/login-history.entity.js +13 -13
- package/dist/src/models/login-history.entity.js.map +1 -1
- package/dist/src/models/user.entity.d.ts +1 -0
- package/dist/src/models/user.entity.js +8 -0
- package/dist/src/models/user.entity.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/migrations/20250610070720-added-MFBypassYN-to-sso-user.js +30 -0
- package/package.json +1 -1
- package/src/components/login-history/index.ts +1 -0
- package/src/components/login-history/login-history.repository.ts +4 -4
- package/src/components/login-history/login-history.ts +124 -0
- package/src/components/login-user/interfaces/user-info.interface.ts +1 -0
- package/src/components/login-user/login-user.ts +1 -0
- package/src/components/login-user/user.ts +434 -15
- package/src/components/user-system-access/user-system-access.ts +1 -1
- package/src/interfaces/login-history-search-attr.interface.ts +8 -0
- package/src/interfaces/login-history.interface.ts +11 -0
- package/src/models/login-history.entity.ts +2 -2
- package/src/models/user.entity.ts +7 -0
- package/sonar-project.properties +0 -23
@@ -0,0 +1,30 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
module.exports = {
|
4
|
+
up: async (queryInterface, Sequelize) => {
|
5
|
+
const transaction = await queryInterface.sequelize.transaction();
|
6
|
+
try {
|
7
|
+
await queryInterface.addColumn('sso_User', 'MFABypassYN', {
|
8
|
+
type: Sequelize.CHAR(1),
|
9
|
+
allowNull: false,
|
10
|
+
defaultValue: 'N',
|
11
|
+
});
|
12
|
+
|
13
|
+
await transaction.commit();
|
14
|
+
} catch (error) {
|
15
|
+
await transaction.rollback();
|
16
|
+
throw error;
|
17
|
+
}
|
18
|
+
},
|
19
|
+
|
20
|
+
down: async (queryInterface, Sequelize) => {
|
21
|
+
const transaction = await queryInterface.sequelize.transaction();
|
22
|
+
try {
|
23
|
+
await queryInterface.removeColumn('sso_User', 'MFABypassYN');
|
24
|
+
await transaction.commit();
|
25
|
+
} catch (error) {
|
26
|
+
await transaction.rollback();
|
27
|
+
throw error;
|
28
|
+
}
|
29
|
+
},
|
30
|
+
};
|
package/package.json
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
import
|
1
|
+
import LoginHistoryModel from '../../models/login-history.entity';
|
2
2
|
import { RepositoryBase, IRepositoryBase } from '@tomei/general';
|
3
3
|
|
4
4
|
export class LoginHistoryRepository
|
5
|
-
extends RepositoryBase<
|
6
|
-
implements IRepositoryBase<
|
5
|
+
extends RepositoryBase<LoginHistoryModel>
|
6
|
+
implements IRepositoryBase<LoginHistoryModel>
|
7
7
|
{
|
8
8
|
constructor() {
|
9
|
-
super(
|
9
|
+
super(LoginHistoryModel);
|
10
10
|
}
|
11
11
|
}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
import { ClassError, ObjectBase } from '@tomei/general';
|
2
|
+
import { LoginHistoryRepository } from './login-history.repository';
|
3
|
+
import { ILoginHistoryAttr } from '../../interfaces/login-history.interface';
|
4
|
+
import { LoginUser } from '../login-user/login-user';
|
5
|
+
import { ApplicationConfig } from '@tomei/config';
|
6
|
+
import { ILoginHistorySearchAttr } from '../../interfaces/login-history-search-attr.interface';
|
7
|
+
import { Op } from 'sequelize';
|
8
|
+
import User from '../../models/user.entity';
|
9
|
+
|
10
|
+
export class LoginHistory extends ObjectBase {
|
11
|
+
ObjectId: string;
|
12
|
+
ObjectName: string;
|
13
|
+
TableName = 'sso_LoginHistory';
|
14
|
+
ObjectType = 'Login History';
|
15
|
+
|
16
|
+
HistoryId: number;
|
17
|
+
UserId: number;
|
18
|
+
UserName: string;
|
19
|
+
OriginIP: string;
|
20
|
+
SystemCode: string;
|
21
|
+
LoginStatus: string;
|
22
|
+
private _CreatedAt: Date;
|
23
|
+
private static _Repo = new LoginHistoryRepository();
|
24
|
+
|
25
|
+
get CreatedAt(): Date {
|
26
|
+
return this._CreatedAt;
|
27
|
+
}
|
28
|
+
|
29
|
+
private constructor(loginHistoryAttr?: ILoginHistoryAttr) {
|
30
|
+
super();
|
31
|
+
if (loginHistoryAttr) {
|
32
|
+
this.HistoryId = loginHistoryAttr?.HistoryId;
|
33
|
+
this.UserId = loginHistoryAttr?.UserId;
|
34
|
+
this.UserName = loginHistoryAttr?.User?.UserName;
|
35
|
+
this.OriginIP = loginHistoryAttr?.OriginIp;
|
36
|
+
this.SystemCode = loginHistoryAttr?.SystemCode;
|
37
|
+
this.LoginStatus = loginHistoryAttr?.LoginStatus;
|
38
|
+
this._CreatedAt = loginHistoryAttr?.CreatedAt;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
public static async findAll(
|
43
|
+
dbTransaction: any,
|
44
|
+
loginUser: LoginUser,
|
45
|
+
page?: number,
|
46
|
+
rows?: number,
|
47
|
+
search?: ILoginHistorySearchAttr,
|
48
|
+
): Promise<{ count: number; loginHistory: LoginHistory[] }> {
|
49
|
+
try {
|
50
|
+
// Part 1: Make sure loginUser got "LOGIN_HISTORY_REPORT" privilege.
|
51
|
+
const sc = ApplicationConfig.getComponentConfigValue('system-code');
|
52
|
+
const isPrivileged = await loginUser.checkPrivileges(
|
53
|
+
sc,
|
54
|
+
'LOGIN_HISTORY_REPORT',
|
55
|
+
);
|
56
|
+
|
57
|
+
if (!isPrivileged) {
|
58
|
+
throw new ClassError(
|
59
|
+
'System',
|
60
|
+
'SystemErrMsg06',
|
61
|
+
'You do not have permission to list login histories.',
|
62
|
+
);
|
63
|
+
}
|
64
|
+
|
65
|
+
//Part 2: Transform page and row into sequelize limit and offset & If search object exists, transform search object to Sequelize where object.
|
66
|
+
const queryObj: any = {};
|
67
|
+
const whereObj: any = {};
|
68
|
+
|
69
|
+
if (search) {
|
70
|
+
Object.entries(search).forEach(([key, value]) => {
|
71
|
+
if (value !== undefined && value !== null) {
|
72
|
+
if (key === 'DateFrom' || key === 'DateTo') {
|
73
|
+
// We'll handle DateFrom and DateTo after this loop
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
if (key === 'UserId') {
|
78
|
+
queryObj[key] = value; // Directly assign UserId
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
|
82
|
+
queryObj[key] = {
|
83
|
+
[Op.substring]: value,
|
84
|
+
};
|
85
|
+
}
|
86
|
+
});
|
87
|
+
}
|
88
|
+
|
89
|
+
if (page && rows) {
|
90
|
+
whereObj.offset = (page - 1) * rows;
|
91
|
+
whereObj.limit = rows;
|
92
|
+
}
|
93
|
+
|
94
|
+
if (search?.DateFrom || search?.DateTo) {
|
95
|
+
queryObj.createdAt = {
|
96
|
+
...(search?.DateFrom && { [Op.gte]: search.DateFrom }),
|
97
|
+
...(search?.DateTo && { [Op.lte]: search.DateTo }),
|
98
|
+
};
|
99
|
+
}
|
100
|
+
|
101
|
+
//Part 3: Call the class' repo class findAndCountAll() method queryObj and whereObj
|
102
|
+
const result = await LoginHistory._Repo.findAllWithPagination({
|
103
|
+
distinct: true,
|
104
|
+
where: queryObj,
|
105
|
+
...whereObj,
|
106
|
+
order: [['CreatedAt', 'DESC']],
|
107
|
+
include: [
|
108
|
+
{
|
109
|
+
model: User,
|
110
|
+
required: false,
|
111
|
+
attributes: ['UserName'],
|
112
|
+
},
|
113
|
+
],
|
114
|
+
transaction: dbTransaction,
|
115
|
+
});
|
116
|
+
|
117
|
+
//Part 4: Return the Count and LoginHistories.
|
118
|
+
const loginHistory = result.rows.map((data) => new LoginHistory(data));
|
119
|
+
return { count: result.count, loginHistory };
|
120
|
+
} catch (error) {
|
121
|
+
throw error;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
@@ -61,6 +61,7 @@ export class LoginUser extends User implements ILoginUser {
|
|
61
61
|
LastLoginAt: user.LastLoginAt,
|
62
62
|
MFAEnabled: user.MFAEnabled,
|
63
63
|
MFAConfig: user.MFAConfig,
|
64
|
+
MFABypassYN: user.MFABypassYN,
|
64
65
|
RecoveryEmail: user.RecoveryEmail,
|
65
66
|
FailedLoginAttemptCount: user.FailedLoginAttemptCount,
|
66
67
|
LastFailedLoginAt: user.LastFailedLoginAt,
|