@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.
@@ -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
- 'sso_APIKey',
8
- {
9
- APIKeyId: {
10
- primaryKey: true,
11
- type: Sequelize.INTEGER,
12
- allowNull: false,
13
- autoIncrement: true,
14
- },
15
- APIKey: {
16
- type: Sequelize.STRING(128),
17
- allowNull: false,
18
- unique: true,
19
- },
20
- Name: {
21
- type: Sequelize.STRING(255),
22
- allowNull: false,
23
- },
24
- Description: {
25
- type: Sequelize.TEXT,
26
- allowNull: true,
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
- RevokedById: {
57
- type: Sequelize.INTEGER,
58
- allowNull: true,
59
- references: {
60
- model: 'sso_User',
61
- key: 'UserId',
62
- },
63
- onDelete: 'CASCADE',
64
- onUpdate: 'CASCADE',
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
- RevokedReason: {
67
- type: Sequelize.TEXT,
68
- defaultValue: 'Active',
69
- allowNull: true,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomei/sso",
3
- "version": "0.44.1",
3
+ "version": "0.45.0",
4
4
  "description": "Tomei SSO Package",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -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
- const reportingUser: GroupReportingUser[] = [];
268
- if (result.length > 0) {
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.
@@ -4,6 +4,7 @@ export interface IAPIKeyAttr {
4
4
  APIKeyId: number;
5
5
  ApiKey: string;
6
6
  Name: string;
7
+ SystemCode: string;
7
8
  Description: string;
8
9
  Status: APIKeyStatusEnum;
9
10
  ExpirationDate: Date;
@@ -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
  }