UNPKG

@tomei/sso

Version:
718 lines (656 loc) 24.7 kB
import { ClassError, ObjectBase } from '@tomei/general'; import { UserSystemAccessRepository } from './user-system-access.repository'; import { IUserSystemAccess } from '../../interfaces/user-system-access.interface'; import { User } from '../login-user/user'; import { ApplicationConfig } from '@tomei/config'; import SystemModel from '../../models/system.entity'; import SystemPrivilegeModel from '../../models/system-privilege.entity'; import UserSystemAccessModel from '../../models/user-system-access.entity'; import GroupModel from '../../models/group.entity'; import GroupSystemAccessModel from '../../models/group-system-access.entity'; import UserModel from '../../models/user.entity'; import { ActionEnum, Activity } from '@tomei/activity-history'; import { Op } from 'sequelize'; import { UserPrivilegeRepository } from '../user-privilege/user-privilege.repository'; import UserGroupModel from 'models/user-group.entity'; import { UserStatus } from '../../enum'; export class UserSystemAccess extends ObjectBase { ObjectType = 'UserSystemAccess'; TableName = 'sso_UserSystemAccess'; ObjectName: string; ObjectId: string; UserSystemAccessId: number; UserId: number; SystemCode: string; Status: string; private _CreatedAt: Date; private _UpdatedAt: Date; private _CreatedById: number; private _UpdatedById: number; get CreatedAt() { return this._CreatedAt; } get UpdatedAt() { return this._UpdatedAt; } get CreatedById() { return this._CreatedById; } get UpdatedById() { return this._UpdatedById; } private static _Repository = new UserSystemAccessRepository(); private static _UserPrivilegeRepo = new UserPrivilegeRepository(); private constructor(userSystemAccessAttr?: IUserSystemAccess) { super(); if (userSystemAccessAttr) { this.UserSystemAccessId = userSystemAccessAttr.UserSystemAccessId; this.UserId = userSystemAccessAttr.UserId; this.SystemCode = userSystemAccessAttr.SystemCode; this.Status = userSystemAccessAttr.Status; this._CreatedById = userSystemAccessAttr.CreatedById; this._CreatedAt = userSystemAccessAttr.CreatedAt; this._UpdatedById = userSystemAccessAttr.UpdatedById; this._UpdatedAt = userSystemAccessAttr.UpdatedAt; } } static async init(dbTransaction: any, UserSystemAccessId?: number) { try { const userSystemAccess = new UserSystemAccess(); if (UserSystemAccessId) { const userSystemAccessAttr = await this._Repository.findOne({ where: { UserSystemAccessId }, transaction: dbTransaction, }); if (userSystemAccessAttr) { return new UserSystemAccess( userSystemAccessAttr.get({ plain: true }), ); } else { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg00', 'UserSystemAccess not found', ); } } return userSystemAccess; } catch (error) { throw error; } } public static async findAll( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. whereOption: { //An object containing filter criteria, specifically: UserId: number; //The ID of the user whose system access records are to be retrieved. SystemCode?: string; }, pagination: { //An object containing pagination parameters: page: number; //The current page number to retrieve. limit: number; //The number of records to retrieve per page. }, ): Promise<{ records: { SystemName: string; SystemCode: string; Status: string; CreatedBy: string; CreatedAt: Date; UpdatedBy: string; UpdatedAt: Date; }[]; pagination: { currentPage: number; pageSize: number; totalRecords: number; }; }> { try { // Privilege Checking: // Call loginUser.checkPrivileges() method by passing: // SystemCode: Retrieve from app config. // PrivilegeCode: 'USER_SYSTEM_ACCESS_LIST'. const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const privilegeCode = 'USER_SYSTEM_ACCESS_LIST'; const isPrivileged = await loginUser.checkPrivileges( systemCode, privilegeCode, ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg01', 'You do not have permission to access this resource.', ); } // Create a where condition using whereOption to filter by UserId. // Set up pagination logic using the pagination parameter: // Calculate offset based on page and limit. const options: any = { distinct: true, where: { UserId: whereOption.UserId, }, offset: (pagination.page - 1) * pagination.limit, limit: pagination.limit, transaction: dbTransaction, include: [ { model: SystemModel, attributes: ['Name', 'SystemCode'], }, { model: UserModel, as: 'CreatedBy', attributes: ['FullName'], }, { model: UserModel, as: 'UpdatedBy', attributes: ['FullName'], }, ], }; const userSystemAccesses = await this._Repository.findAllWithPagination(options); return { records: userSystemAccesses.rows.map((userSystemAccess) => { return { UserSystemAccessId: userSystemAccess.UserSystemAccessId, SystemName: userSystemAccess.System.Name, SystemCode: userSystemAccess.System.SystemCode, Status: userSystemAccess.Status, CreatedBy: userSystemAccess.CreatedBy.FullName, CreatedAt: userSystemAccess.CreatedAt, UpdatedBy: userSystemAccess.UpdatedBy.FullName, UpdatedAt: userSystemAccess.UpdatedAt, }; }), pagination: { currentPage: pagination.page, pageSize: pagination.limit, totalRecords: userSystemAccesses.count, }, }; } catch (error) { throw error; } } public static async findAllUsers( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. SystemCode: string, Page: number, Rows: number, Search: { UserId?: string | number; Status?: string; }, ) { // Part 1: Privilege Checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'USER_SYSTEM_ACCESS_LIST', ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccessUser', 'UserSystemAccessUserErrMsg01', 'You do not have permission to view system access users.', ); } try { // Part 2: Retrieve System Access Users and returns const queryObj: any = { SystemCode: SystemCode }; if (Search) { Object.entries(Search).forEach(([key, value]) => { queryObj[key] = value; }); } let options: any = { where: queryObj, distinct: true, transaction: dbTransaction, }; if (Page && Rows) { options = { ...options, limit: Rows, offset: Rows * (Page - 1), order: [['CreatedAt', 'DESC']], include: [ { model: SystemModel, attributes: ['Name', 'SystemCode'], }, { model: UserModel, where: { Status: UserStatus.ACTIVE, }, as: 'User', attributes: ['UserId', 'FullName', 'Email'], }, ], }; } const userSystemAccesses = await this._Repository.findAndCountAll(options); return userSystemAccesses; } catch (error) { throw error; } } public static async findAllUserPrivileges( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. SystemCode: string, search?: { UserId?: string[]; Status?: string; }, ) { // Part 1: Privilege Checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'USER_SYSTEM_ACCESS_LIST', ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccessUser', 'UserSystemAccessUserErrMsg01', 'You do not have permission to view system access users.', ); } try { //Part 2: Retrieve User System Access Based on Privileges let systemWhere: any = {}; if (SystemCode) { systemWhere = { SystemCode: { [Op.substring]: SystemCode, }, }; } const allSystemAccessUsers = await UserSystemAccessModel.findAll({ include: [ { model: SystemModel, where: systemWhere, }, { model: UserModel, as: 'User', attributes: ['UserId', 'FullName'], }, ], transaction: dbTransaction, }); const allPrivileges = await SystemPrivilegeModel.findAll({ where: systemWhere, transaction: dbTransaction, }); const systemAccessUserPrivileges = allPrivileges.map( async (privilege) => { const filteredUsers = allSystemAccessUsers .map((userAccess) => userAccess.User) .filter((user) => search.UserId.includes(String(user.UserId))); return { ...privilege.get({ plain: true }), Users: filteredUsers, }; }, ); return systemAccessUserPrivileges; } catch (error) { throw error; } } public static async findAllUserRoles( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. SystemCode: string, search?: { UserId?: string[]; Status?: string; }, ) { // Part 1: Privilege Checking const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges( systemCode, 'USER_SYSTEM_ACCESS_LIST', ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccessUser', 'UserSystemAccessUserErrMsg01', 'You do not have permission to view system access users.', ); } try { //Part 2: Retrieve User System Access Based on Privileges let systemWhere: any = {}; if (SystemCode) { systemWhere = { SystemCode: { [Op.substring]: SystemCode, }, }; } const allGroupSystemAccess = await GroupSystemAccessModel.findAll({ where: systemWhere, include: [ { model: GroupModel, where: { Type: 'Role', }, }, ], transaction: dbTransaction, }); const allSystemAccessUsers = await UserSystemAccessModel.findAll({ include: [ { model: SystemModel, where: systemWhere, }, { model: UserModel, as: 'User', attributes: ['UserId', 'FullName'], }, ], transaction: dbTransaction, }); const systemAccessUserRoles = allGroupSystemAccess.map( (groupSystemAccess) => { const filteredUsers = allSystemAccessUsers .map((userAccess) => userAccess.User) .filter((user) => search.UserId.includes(String(user.UserId))); return { ...groupSystemAccess.Group.get({ plain: true }), Users: filteredUsers, }; }, ); return systemAccessUserRoles; } catch (error) { throw error; } } public static async createAccess( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. UserId: string, //The user ID for whom system access is being created. SystemCode: string, //The system code for which access is being granted. Status: string, //The status of access ('Active' or 'Inactive'). ) { try { // Part 1: Privilege Checking: // Call loginUser.checkPrivileges() method by passing: // SystemCode: Retrieve from app config. // PrivilegeCode: 'USER_SYSTEM_ACCESS_CREATE'. const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const privilegeCode = 'USER_SYSTEM_ACCESS_CREATE'; const isPrivileged = await loginUser.checkPrivileges( systemCode, privilegeCode, ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg01', 'You do not have permission to access this resource.', ); } // Part 2: Validation for Existing Access // Use the UserSystemAccess.findAll() method to check if the user already has access to the specified system: // Pass the following parameters: // loginUser // dbTransaction // whereOption: set to UserId = UserId and SystemCode = SystemCode. // If a record is found, throw an error indicating that access for this user and system already exists. const isExist = await UserSystemAccess._Repository.findAll({ where: { [Op.and]: [{ UserId: UserId }, { SystemCode: SystemCode }] }, transaction: dbTransaction, }); if (isExist?.length > 0) { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg01', 'User already have access to this system', ); } // Part 3: Insert System Access Record // After successful validation, create a new instance of UserSystemAccess with the following fields: // - UserId: set to the UserId parameter. // - SystemCode: set to the SystemCode parameter. // - Status: set to the Status parameter. // - CreatedById: set to loginUser.UserId. // - CreatedAt: set to the current timestamp. // - UpdatedById: set to loginUser.UserId. // - UpdatedAt: set to the current timestamp (same as CreatedAt). // Save the new UserSystemAccess instance in the database within the dbTransaction. const newUserSystemAccess = new UserSystemAccess(); newUserSystemAccess.UserId = parseInt(UserId); newUserSystemAccess.SystemCode = SystemCode; newUserSystemAccess.Status = Status; newUserSystemAccess._CreatedById = loginUser.UserId; newUserSystemAccess._CreatedAt = new Date(); newUserSystemAccess._UpdatedById = loginUser.UserId; newUserSystemAccess._UpdatedAt = new Date(); const payload = { UserId: newUserSystemAccess.UserId, SystemCode: newUserSystemAccess.SystemCode, Status: newUserSystemAccess.Status, CreatedById: newUserSystemAccess.CreatedById, CreatedAt: newUserSystemAccess.CreatedAt, UpdatedById: newUserSystemAccess.UpdatedById, UpdatedAt: newUserSystemAccess.UpdatedAt, }; const systemAccess = await UserSystemAccess._Repository.create(payload, { transaction: dbTransaction, }); // Part 4: Record Activity History // Initialize an empty object ({}) as EntityValueBefore. // Set EntityValueAfter to the stringified version of the newly created UserSystemAccess instance. // Create a new activity log entry: // ActivityId: auto-generated by calling activity.createId(). // Action: set to ActionEnum.Create. // Description: set to "Create User System Access". // EntityType: set to UserSystemAccess. // EntityId: set to the newly created UserSystemAccess.UserSystemAccessId. // EntityValueBefore: set to {} (empty). // EntityValueAfter: set to the stringified version of the new access record. // Call the activity.create() method, passing: // dbTransaction // userId: set to loginUser.UserId. const entityValueBefore = {}; //Instantiate new activity const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.CREATE; activity.Description = 'Create User System Access'; activity.EntityType = 'UserSystemAccess'; activity.EntityId = systemAccess.UserSystemAccessId?.toString(); activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify(payload); //Call Activity.create method await activity.create(loginUser.ObjectId, dbTransaction); // Part 5: Return Newly Created Record // Return the newly created UserSystemAccess instance with all relevant fields, including UserSystemAccessId, SystemCode, Status, CreatedAt, and CreatedById. newUserSystemAccess.UserSystemAccessId = systemAccess.UserSystemAccessId; return newUserSystemAccess; } catch (error) { throw error; } } public async update( loginUser: User, //The user object representing the currently logged-in user. dbTransaction: any, //The database transaction instance for managing the transaction scope. Status: string, //The new access status (Active/Inactive) for the user system access. ) { try { // Part 1: Update Access // Call the UserSystemAccess._Repo.update() method to perform the update operation, passing: // - Status: The new access status. // - UpdatedById: loginUser.UserId (to indicate who updated the record). // - UpdatedAt: Set to the current date and time. // - dbTransaction: The database transaction instance. const entityValueBefore = { UserId: this.UserId, SystemCode: this.SystemCode, Status: this.Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, }; await UserSystemAccess._Repository.update( { Status: Status, UpdatedById: loginUser.UserId, UpdatedAt: new Date(), }, { where: { UserSystemAccessId: this.UserSystemAccessId, }, transaction: dbTransaction, }, ); const entityValueAfter = { UserId: this.UserId, SystemCode: this.SystemCode, Status: Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: loginUser.UserId, UpdatedAt: new Date(), }; // Part 2: Record Activity History // Initialize a variable entityValueBefore to store the current state of the user system access record before the update. // Create an instance of the Activity class and set the following properties: // - ActivityId: Call activity.createId(). // - Action: Set to ActionEnum.Update. // - Description: Set to Update User System Access. // - EntityType: Set to UserSystemAccess. // - EntityId: Use the ID of the updated user system access record. // - EntityValueBefore: Stringify entityValueBefore to capture the state before the update. // - EntityValueAfter: Stringify the updated user system access record to capture the new state after the update. // Call the activity create method with the following parameters: // - dbTransaction // - userId: loginUser.UserId const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.UPDATE; activity.Description = 'Update User System Access'; activity.EntityType = 'UserSystemAccess'; activity.EntityId = this.UserSystemAccessId + ''; activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify(entityValueAfter); await activity.create(loginUser.ObjectId, dbTransaction); // Part 3: Return Updated Record // Retrieve the updated user system access record from the database or return the updated instance as needed. // Part 5: Return Newly Created Record // Return the newly created UserSystemAccess instance with all relevant fields, including UserSystemAccessId, SystemCode, Status, CreatedAt, and CreatedById. return entityValueAfter; } catch (error) { throw error; } } public static async remove( loginUser: User, //The currently logged-in user initiating the request. dbTransaction: any, //The active database transaction to ensure consistency during the query. UserSystemAccessId: number, //The unique identifier of the User System Access record to be deleted. ) { try { // Part 1: Privilege Checking // Call loginUser.checkPrivileges() method by passing: // - SystemCode: Retrieve from app config. // - PrivilegeCode: 'USER_SYSTEM_ACCESS_REMOVE'. // If the user does not have the required privileges, throw an appropriate exception. const systemCode = ApplicationConfig.getComponentConfigValue('system-code'); const privilegeCode = 'USER_SYSTEM_ACCESS_REMOVE'; const isPrivileged = await loginUser.checkPrivileges( systemCode, privilegeCode, ); if (!isPrivileged) { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg01', 'You do not have permission to access this resource.', ); } // Part 2: Retrieve Record // Use the UserSystemAccessRepo.findById(UserSystemAccessId) method to retrieve the record. // If the record does not exist, throw an exception indicating the record was not found. const userSystemAccess = await UserSystemAccess._Repository.findOne({ where: { UserSystemAccessId: UserSystemAccessId, }, transaction: dbTransaction, }); if (!userSystemAccess) { throw new ClassError( 'UserSystemAccess', 'UserSystemAccessErrMsg02', 'User System Access not Found', ); } // Part 3: Delete Record // Call the UserSystemAccess._Repo.delete() method, passing: // - UserSystemAccessId // dbTransaction to permanently delete the record from the database. await UserSystemAccess._Repository.delete( UserSystemAccessId, dbTransaction, ); const entityValueBefore = { UserId: userSystemAccess.UserId, SystemCode: userSystemAccess.SystemCode, Status: userSystemAccess.Status, CreatedById: userSystemAccess.CreatedById, CreatedAt: userSystemAccess.CreatedAt, UpdatedById: userSystemAccess.UpdatedById, UpdatedAt: userSystemAccess.UpdatedAt, }; // Part 4: Record Activity History // Instantiate a new activity from the Activity class, and set: // - ActivityId: activity.createId() // - Action: ActionEnum.Delete // - Description: Delete User System Access // - EntityType: UserSystemAccess // - EntityId: UserSystemAccessId // - EntityValueBefore: Stringified representation of the record before deletion. // - EntityValueAfter: null. // Call the activity.create() method by passing: // - dbTransaction // - userId: loginUser.UserId. //Instantiate new activity const activity = new Activity(); activity.ActivityId = activity.createId(); activity.Action = ActionEnum.DELETE; activity.Description = 'Delete User System Access'; activity.EntityType = 'UserSystemAccess'; activity.EntityId = UserSystemAccessId?.toString(); activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify({}); //Call Activity.create method await activity.create(loginUser.ObjectId, dbTransaction); } catch (error) { throw error; } } }