@tomei/sso 0.44.1 → 0.45.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/dist/src/components/api-key/api-key.d.ts +4 -0
- package/dist/src/components/api-key/api-key.js +9 -0
- package/dist/src/components/api-key/api-key.js.map +1 -1
- package/dist/src/components/group/group.d.ts +4 -0
- package/dist/src/components/group/group.js +34 -0
- package/dist/src/components/group/group.js.map +1 -1
- package/dist/src/components/group-reporting-user/group-reporting-user.d.ts +1 -1
- package/dist/src/components/group-reporting-user/group-reporting-user.js +8 -7
- package/dist/src/components/group-reporting-user/group-reporting-user.js.map +1 -1
- package/dist/src/interfaces/api-key-attr.interface.d.ts +1 -0
- package/dist/src/models/api-key-entity.d.ts +3 -0
- package/dist/src/models/api-key-entity.js +13 -0
- package/dist/src/models/api-key-entity.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/migrations/20240528063108-create-api-key-table.js +70 -63
- package/package.json +1 -1
- package/src/components/api-key/api-key.ts +16 -0
- package/src/components/group/group.ts +63 -1
- package/src/components/group-reporting-user/group-reporting-user.ts +9 -9
- package/src/interfaces/api-key-attr.interface.ts +1 -0
- package/src/models/api-key-entity.ts +11 -0
@@ -3,73 +3,80 @@
|
|
3
3
|
/** @type {import('sequelize-cli').Migration} */
|
4
4
|
module.exports = {
|
5
5
|
async up(queryInterface, Sequelize) {
|
6
|
-
await queryInterface.createTable(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
Status: {
|
29
|
-
type: Sequelize.STRING(50),
|
30
|
-
defaultValue: 'Active',
|
31
|
-
allowNull: false,
|
32
|
-
},
|
33
|
-
ExpirationDate: {
|
34
|
-
allowNull: false,
|
35
|
-
type: Sequelize.DATE,
|
36
|
-
},
|
37
|
-
CreatedAt: {
|
38
|
-
allowNull: false,
|
39
|
-
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP(3)'),
|
40
|
-
type: Sequelize.DATE,
|
41
|
-
},
|
42
|
-
CreatedById: {
|
43
|
-
type: Sequelize.INTEGER,
|
44
|
-
allowNull: true,
|
45
|
-
references: {
|
46
|
-
model: 'sso_User',
|
47
|
-
key: 'UserId',
|
48
|
-
},
|
49
|
-
onDelete: 'CASCADE',
|
50
|
-
onUpdate: 'CASCADE',
|
51
|
-
},
|
52
|
-
RevokedAt: {
|
53
|
-
allowNull: true,
|
54
|
-
type: Sequelize.DATE,
|
6
|
+
await queryInterface.createTable('sso_APIKey', {
|
7
|
+
APIKeyId: {
|
8
|
+
primaryKey: true,
|
9
|
+
type: Sequelize.INTEGER,
|
10
|
+
allowNull: false,
|
11
|
+
autoIncrement: true,
|
12
|
+
},
|
13
|
+
APIKey: {
|
14
|
+
type: Sequelize.STRING(128),
|
15
|
+
allowNull: false,
|
16
|
+
unique: true,
|
17
|
+
},
|
18
|
+
Name: {
|
19
|
+
type: Sequelize.STRING(255),
|
20
|
+
allowNull: false,
|
21
|
+
},
|
22
|
+
SystemCode: {
|
23
|
+
type: Sequelize.STRING(10),
|
24
|
+
allowNull: false,
|
25
|
+
references: {
|
26
|
+
model: 'sso_System',
|
27
|
+
key: 'SystemCode',
|
55
28
|
},
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
29
|
+
onDelete: 'CASCADE',
|
30
|
+
onUpdate: 'CASCADE',
|
31
|
+
},
|
32
|
+
Description: {
|
33
|
+
type: Sequelize.TEXT,
|
34
|
+
allowNull: true,
|
35
|
+
},
|
36
|
+
Status: {
|
37
|
+
type: Sequelize.STRING(50),
|
38
|
+
defaultValue: 'Active',
|
39
|
+
allowNull: false,
|
40
|
+
},
|
41
|
+
ExpirationDate: {
|
42
|
+
allowNull: false,
|
43
|
+
type: Sequelize.DATE,
|
44
|
+
},
|
45
|
+
CreatedAt: {
|
46
|
+
allowNull: false,
|
47
|
+
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP(3)'),
|
48
|
+
type: Sequelize.DATE,
|
49
|
+
},
|
50
|
+
CreatedById: {
|
51
|
+
type: Sequelize.INTEGER,
|
52
|
+
allowNull: true,
|
53
|
+
references: {
|
54
|
+
model: 'sso_User',
|
55
|
+
key: 'UserId',
|
65
56
|
},
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
57
|
+
onDelete: 'CASCADE',
|
58
|
+
onUpdate: 'CASCADE',
|
59
|
+
},
|
60
|
+
RevokedAt: {
|
61
|
+
allowNull: true,
|
62
|
+
type: Sequelize.DATE,
|
63
|
+
},
|
64
|
+
RevokedById: {
|
65
|
+
type: Sequelize.INTEGER,
|
66
|
+
allowNull: true,
|
67
|
+
references: {
|
68
|
+
model: 'sso_User',
|
69
|
+
key: 'UserId',
|
70
70
|
},
|
71
|
+
onDelete: 'CASCADE',
|
72
|
+
onUpdate: 'CASCADE',
|
73
|
+
},
|
74
|
+
RevokedReason: {
|
75
|
+
type: Sequelize.TEXT,
|
76
|
+
defaultValue: 'Active',
|
77
|
+
allowNull: true,
|
71
78
|
},
|
72
|
-
);
|
79
|
+
});
|
73
80
|
},
|
74
81
|
|
75
82
|
async down(queryInterface, Sequelize) {
|
package/package.json
CHANGED
@@ -7,6 +7,7 @@ import { ApplicationConfig } from '@tomei/config';
|
|
7
7
|
import { randomBytes } from 'crypto';
|
8
8
|
import { ActionEnum, Activity } from '@tomei/activity-history';
|
9
9
|
import { Op } from 'sequelize';
|
10
|
+
import { System } from '../system/system';
|
10
11
|
|
11
12
|
export class APIKey extends ObjectBase {
|
12
13
|
ObjectId: string;
|
@@ -16,6 +17,7 @@ export class APIKey extends ObjectBase {
|
|
16
17
|
|
17
18
|
ApiKey: string;
|
18
19
|
Name: string;
|
20
|
+
SystemCode: string;
|
19
21
|
Description: string;
|
20
22
|
Status: APIKeyStatusEnum;
|
21
23
|
ExpirationDate: Date;
|
@@ -57,6 +59,7 @@ export class APIKey extends ObjectBase {
|
|
57
59
|
this.APIKeyId = apiKeyAttr.APIKeyId;
|
58
60
|
this.ApiKey = apiKeyAttr.ApiKey;
|
59
61
|
this.Name = apiKeyAttr.Name;
|
62
|
+
this.SystemCode = apiKeyAttr.SystemCode;
|
60
63
|
this.Description = apiKeyAttr.Description;
|
61
64
|
this.Status = apiKeyAttr.Status;
|
62
65
|
this.ExpirationDate = apiKeyAttr.ExpirationDate;
|
@@ -114,6 +117,12 @@ export class APIKey extends ObjectBase {
|
|
114
117
|
);
|
115
118
|
}
|
116
119
|
|
120
|
+
// Part 3: System Existence Check
|
121
|
+
// Call System.init(dbTransaction, this.SystemCode) to verify the System exists.
|
122
|
+
// If the group does not exist, throw a NotFoundError.
|
123
|
+
|
124
|
+
await System.init(dbTransaction, this.SystemCode);
|
125
|
+
|
117
126
|
// Part 3: Generate API Key
|
118
127
|
// Populate the following attributes:
|
119
128
|
// CreatedById: Set to loginUser.UserId.
|
@@ -133,6 +142,7 @@ export class APIKey extends ObjectBase {
|
|
133
142
|
const EntityValueAfter: any = {
|
134
143
|
ApiKey: this.ApiKey,
|
135
144
|
Name: this.Name,
|
145
|
+
SystemCode: this.SystemCode,
|
136
146
|
Status: this.Status,
|
137
147
|
Description: this.Description,
|
138
148
|
ExpirationDate: this.ExpirationDate,
|
@@ -188,6 +198,7 @@ export class APIKey extends ObjectBase {
|
|
188
198
|
Name: this.Name,
|
189
199
|
Status: this.Status,
|
190
200
|
Description: this.Description,
|
201
|
+
SystemCode: this.SystemCode,
|
191
202
|
ExpirationDate: this.ExpirationDate,
|
192
203
|
CreatedAt: this.CreatedAt,
|
193
204
|
CreatedById: this.CreatedById,
|
@@ -205,6 +216,7 @@ export class APIKey extends ObjectBase {
|
|
205
216
|
loginUser: LoginUser,
|
206
217
|
dbTransaction: any,
|
207
218
|
whereOptions: {
|
219
|
+
SystemCode?: string;
|
208
220
|
Status?: APIKeyStatusEnum;
|
209
221
|
ExpirationDate?: {
|
210
222
|
FromDate: Date;
|
@@ -246,6 +258,9 @@ export class APIKey extends ObjectBase {
|
|
246
258
|
// CreatedById: Filter by the user who created the API key.
|
247
259
|
const where = {};
|
248
260
|
if (whereOptions) {
|
261
|
+
if (whereOptions.SystemCode) {
|
262
|
+
where['SystemCode'] = whereOptions.SystemCode;
|
263
|
+
}
|
249
264
|
if (whereOptions.Status) {
|
250
265
|
where['Status'] = whereOptions.Status;
|
251
266
|
}
|
@@ -311,6 +326,7 @@ export class APIKey extends ObjectBase {
|
|
311
326
|
ApiKeyId: row.APIKeyId,
|
312
327
|
ApiKey: row.ApiKey,
|
313
328
|
Name: row.Name,
|
329
|
+
SystemCode: row.SystemCode,
|
314
330
|
Description: row.Description,
|
315
331
|
Status: row.Status,
|
316
332
|
ExpirationDate: row.ExpirationDate,
|
@@ -5,7 +5,7 @@ import { GroupTypeEnum } from 'enum';
|
|
5
5
|
import { LoginUser } from '../login-user/login-user';
|
6
6
|
import { IGroupSearchAttr } from '../../interfaces/group-search-attr.interface';
|
7
7
|
import { ApplicationConfig } from '@tomei/config';
|
8
|
-
import { Op } from 'sequelize';
|
8
|
+
import { Op, Transaction } from 'sequelize';
|
9
9
|
import { ActionEnum, Activity } from '@tomei/activity-history';
|
10
10
|
import { GroupSystemAccessRepository } from '../group-system-access/group-system-access.repository';
|
11
11
|
import SystemModel from '../../models/system.entity';
|
@@ -18,6 +18,10 @@ import GroupPrivilegeModel from '../../models/group-privilege.entity';
|
|
18
18
|
import { GroupObjectPrivilegeRepository } from '../group-object-privilege/group-object-privilege.repository';
|
19
19
|
import { GroupObjectPrivilege } from '../group-object-privilege/group-object-privilege';
|
20
20
|
import { GroupPrivilege } from '../group-privilege/group-privilege';
|
21
|
+
import { User } from '../login-user/user';
|
22
|
+
import GroupReportingUserModel from '../../models/group-reporting-user.entity';
|
23
|
+
import GroupModel from '../../models/group.entity';
|
24
|
+
import UserModel from '../../models/user.entity';
|
21
25
|
|
22
26
|
export class Group extends TreeNodeBase<Group> {
|
23
27
|
ObjectId: string;
|
@@ -1900,4 +1904,62 @@ export class Group extends TreeNodeBase<Group> {
|
|
1900
1904
|
return tree;
|
1901
1905
|
}
|
1902
1906
|
}
|
1907
|
+
|
1908
|
+
public static async getGroupsWithReportingUser(
|
1909
|
+
loginUser: User, //The user performing the action.
|
1910
|
+
dbTransaction: Transaction, //Active database transaction.
|
1911
|
+
whereOptions: any, //The filter criteria for selecting groups.
|
1912
|
+
) {
|
1913
|
+
try {
|
1914
|
+
// Part 1: Privilege Checking
|
1915
|
+
// Call loginUser.checkPrivileges() by passing:
|
1916
|
+
// SystemCode: Retrieve from app config.
|
1917
|
+
// PrivilegeCode: 'GROUP_VIEW'.
|
1918
|
+
const systemCode =
|
1919
|
+
ApplicationConfig.getComponentConfigValue('system-code');
|
1920
|
+
const isPrivileged = await loginUser.checkPrivileges(
|
1921
|
+
systemCode,
|
1922
|
+
'GROUP_VIEW',
|
1923
|
+
);
|
1924
|
+
if (!isPrivileged) {
|
1925
|
+
throw new ClassError(
|
1926
|
+
'Group',
|
1927
|
+
'GroupErrMsg04',
|
1928
|
+
'User is not privileged to view group',
|
1929
|
+
);
|
1930
|
+
}
|
1931
|
+
// Part 2: Prepare Group Query
|
1932
|
+
// Call Group._Repo.findAll() to fetch groups from the sso_Group table by passing:
|
1933
|
+
// where: whereOptions
|
1934
|
+
// include:
|
1935
|
+
// Model: sso_GroupReportingUsers
|
1936
|
+
// where: { Status: 'Active' }
|
1937
|
+
// include:
|
1938
|
+
// Model: sso_User
|
1939
|
+
// attributes: ['UserId', 'FullName']
|
1940
|
+
// attributes: ['GroupCode', 'UserId', 'Rank']
|
1941
|
+
const options = {
|
1942
|
+
where: whereOptions,
|
1943
|
+
include: [
|
1944
|
+
{
|
1945
|
+
model: GroupReportingUserModel,
|
1946
|
+
where: { Status: 'Active' },
|
1947
|
+
include: [
|
1948
|
+
{
|
1949
|
+
model: UserModel,
|
1950
|
+
attributes: ['UserId', 'FullName'],
|
1951
|
+
},
|
1952
|
+
],
|
1953
|
+
},
|
1954
|
+
],
|
1955
|
+
transaction: dbTransaction,
|
1956
|
+
};
|
1957
|
+
const groups = await Group._Repo.findAll(options);
|
1958
|
+
// Part 3: Retrieve and Return
|
1959
|
+
// Return the list of groups with nested reporting users.
|
1960
|
+
return groups;
|
1961
|
+
} catch (error) {
|
1962
|
+
throw error;
|
1963
|
+
}
|
1964
|
+
}
|
1903
1965
|
}
|
@@ -2,6 +2,7 @@ import { ClassError, ObjectBase } from '@tomei/general';
|
|
2
2
|
import { GroupReportingUserRepository } from './group-reporting-user.repository';
|
3
3
|
import { IGroupReportingUserAttr } from '../../interfaces/group-reporting-user.interface';
|
4
4
|
import { User } from '../login-user/user';
|
5
|
+
import UserModel from '../../models/user.entity';
|
5
6
|
import { Group } from '../group/group';
|
6
7
|
import { ApplicationConfig } from '@tomei/config';
|
7
8
|
import { ActionEnum, Activity } from '@tomei/activity-history';
|
@@ -256,6 +257,12 @@ export class GroupReportingUser extends ObjectBase {
|
|
256
257
|
where: {
|
257
258
|
GroupCode: groupCode,
|
258
259
|
},
|
260
|
+
include: [
|
261
|
+
{
|
262
|
+
model: UserModel,
|
263
|
+
as: 'User',
|
264
|
+
},
|
265
|
+
],
|
259
266
|
order: [
|
260
267
|
['Rank', 'ASC'], // or 'DESC' for descending order
|
261
268
|
],
|
@@ -264,15 +271,8 @@ export class GroupReportingUser extends ObjectBase {
|
|
264
271
|
|
265
272
|
// Part 4: Return Results
|
266
273
|
// Return the array of GroupReportingUser records found.
|
267
|
-
|
268
|
-
|
269
|
-
for (let i = 0; i < result.length; i++) {
|
270
|
-
reportingUser.push(
|
271
|
-
new GroupReportingUser(result[i].get({ plain: true })),
|
272
|
-
);
|
273
|
-
}
|
274
|
-
}
|
275
|
-
return reportingUser;
|
274
|
+
|
275
|
+
return result;
|
276
276
|
} catch (error) {
|
277
277
|
// Part 5: Handle Errors
|
278
278
|
// Catch and handle any errors during the execution. If an error occurs, ensure the transaction is rolled back.
|
@@ -10,6 +10,7 @@ import {
|
|
10
10
|
} from 'sequelize-typescript';
|
11
11
|
import User from './user.entity';
|
12
12
|
import { APIKeyStatusEnum } from '../enum/api-key.enum';
|
13
|
+
import SystemModel from './system.entity';
|
13
14
|
|
14
15
|
@Table({
|
15
16
|
tableName: 'sso_ApiKey',
|
@@ -37,6 +38,13 @@ export default class APIKeyModel extends Model {
|
|
37
38
|
})
|
38
39
|
Name: string;
|
39
40
|
|
41
|
+
@ForeignKey(() => SystemModel)
|
42
|
+
@Column({
|
43
|
+
allowNull: false,
|
44
|
+
type: DataType.STRING(10),
|
45
|
+
})
|
46
|
+
SystemCode: string;
|
47
|
+
|
40
48
|
@Column({
|
41
49
|
type: DataType.TEXT,
|
42
50
|
allowNull: true,
|
@@ -87,4 +95,7 @@ export default class APIKeyModel extends Model {
|
|
87
95
|
|
88
96
|
@BelongsTo(() => User, 'RevokedById')
|
89
97
|
UpdatedByUser: User;
|
98
|
+
|
99
|
+
@BelongsTo(() => SystemModel, 'SystemCode')
|
100
|
+
System: SystemModel;
|
90
101
|
}
|