@flusys/nestjs-iam 0.1.0-beta.1 → 0.1.0-beta.2
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/README.md +665 -0
- package/cjs/config/iam.constants.js +11 -0
- package/cjs/config/index.js +18 -0
- package/cjs/controllers/action.controller.js +117 -0
- package/cjs/controllers/company-action-permission.controller.js +110 -0
- package/cjs/controllers/index.js +23 -0
- package/cjs/controllers/my-permission.controller.js +90 -0
- package/cjs/controllers/role-permission.controller.js +160 -0
- package/cjs/controllers/role.controller.js +58 -0
- package/cjs/controllers/user-action-permission.controller.js +110 -0
- package/cjs/docs/iam-swagger.config.js +202 -0
- package/cjs/docs/index.js +18 -0
- package/cjs/dtos/action.dto.js +347 -0
- package/cjs/dtos/index.js +21 -0
- package/cjs/dtos/permission.dto.js +554 -0
- package/cjs/dtos/role.dto.js +238 -0
- package/cjs/entities/action-base.entity.js +135 -0
- package/cjs/entities/action.entity.js +28 -0
- package/cjs/entities/index.js +81 -0
- package/cjs/entities/permission-base.entity.js +156 -0
- package/cjs/entities/permission-with-company.entity.js +99 -0
- package/cjs/entities/role-base.entity.js +86 -0
- package/cjs/entities/role-with-company.entity.js +55 -0
- package/cjs/entities/role.entity.js +25 -0
- package/cjs/entities/user-iam-permission.entity.js +57 -0
- package/cjs/enums/action-type.enum.js +22 -0
- package/cjs/enums/index.js +19 -0
- package/cjs/enums/permission-type.enum.js +16 -0
- package/cjs/helpers/index.js +19 -0
- package/cjs/helpers/permission-evaluator.helper.js +175 -0
- package/cjs/helpers/permission-mode.helper.js +49 -0
- package/cjs/index.js +28 -79
- package/cjs/interfaces/action.interface.js +4 -0
- package/cjs/interfaces/iam-module-async-options.interface.js +4 -0
- package/cjs/interfaces/iam-module-options.interface.js +18 -0
- package/cjs/interfaces/index.js +21 -0
- package/cjs/interfaces/role.interface.js +7 -0
- package/cjs/modules/iam.module.js +237 -0
- package/cjs/modules/index.js +18 -0
- package/cjs/services/action.service.js +253 -0
- package/cjs/services/iam-config.service.js +107 -0
- package/cjs/services/iam-datasource.provider.js +205 -0
- package/cjs/services/index.js +23 -0
- package/cjs/services/permission-cache.service.js +308 -0
- package/cjs/services/permission.service.js +1020 -0
- package/cjs/services/role.service.js +181 -0
- package/cjs/types/index.js +18 -0
- package/cjs/types/logic-node.type.js +54 -0
- package/fesm/config/iam.constants.js +1 -0
- package/fesm/config/index.js +1 -0
- package/fesm/controllers/action.controller.js +107 -0
- package/fesm/controllers/company-action-permission.controller.js +100 -0
- package/fesm/controllers/index.js +7 -0
- package/fesm/controllers/my-permission.controller.js +80 -0
- package/fesm/controllers/role-permission.controller.js +150 -0
- package/fesm/controllers/role.controller.js +48 -0
- package/fesm/controllers/user-action-permission.controller.js +100 -0
- package/fesm/docs/iam-swagger.config.js +192 -0
- package/fesm/docs/index.js +1 -0
- package/fesm/dtos/action.dto.js +317 -0
- package/fesm/dtos/index.js +4 -0
- package/fesm/dtos/permission.dto.js +490 -0
- package/fesm/dtos/role.dto.js +214 -0
- package/fesm/entities/action-base.entity.js +128 -0
- package/fesm/entities/action.entity.js +18 -0
- package/fesm/entities/index.js +56 -0
- package/fesm/entities/permission-base.entity.js +138 -0
- package/fesm/entities/permission-with-company.entity.js +89 -0
- package/fesm/entities/role-base.entity.js +79 -0
- package/fesm/entities/role-with-company.entity.js +45 -0
- package/fesm/entities/role.entity.js +15 -0
- package/fesm/entities/user-iam-permission.entity.js +38 -0
- package/fesm/enums/action-type.enum.js +12 -0
- package/fesm/enums/index.js +2 -0
- package/fesm/enums/permission-type.enum.js +6 -0
- package/fesm/helpers/index.js +2 -0
- package/fesm/helpers/permission-evaluator.helper.js +165 -0
- package/fesm/helpers/permission-mode.helper.js +49 -0
- package/fesm/index.js +11 -79
- package/fesm/interfaces/action.interface.js +3 -0
- package/fesm/interfaces/iam-module-async-options.interface.js +3 -0
- package/fesm/interfaces/iam-module-options.interface.js +1 -0
- package/fesm/interfaces/index.js +4 -0
- package/fesm/interfaces/role.interface.js +4 -0
- package/fesm/modules/iam.module.js +227 -0
- package/fesm/modules/index.js +1 -0
- package/fesm/services/action.service.js +243 -0
- package/fesm/services/iam-config.service.js +97 -0
- package/fesm/services/iam-datasource.provider.js +154 -0
- package/fesm/services/index.js +6 -0
- package/fesm/services/permission-cache.service.js +298 -0
- package/fesm/services/permission.service.js +1010 -0
- package/fesm/services/role.service.js +171 -0
- package/fesm/types/index.js +1 -0
- package/fesm/types/logic-node.type.js +36 -0
- package/package.json +25 -25
- package/cjs/config-index.js +0 -1
- package/cjs/controllers-index.js +0 -1
- package/cjs/docs-index.js +0 -79
- package/cjs/dtos-index.js +0 -1
- package/cjs/entities-index.js +0 -1
- package/cjs/enums-index.js +0 -1
- package/cjs/helpers-index.js +0 -1
- package/cjs/interfaces-index.js +0 -1
- package/cjs/modules-index.js +0 -1
- package/cjs/services-index.js +0 -1
- package/cjs/types-index.js +0 -1
- package/fesm/config-index.js +0 -1
- package/fesm/controllers-index.js +0 -1
- package/fesm/docs-index.js +0 -79
- package/fesm/dtos-index.js +0 -1
- package/fesm/entities-index.js +0 -1
- package/fesm/enums-index.js +0 -1
- package/fesm/helpers-index.js +0 -1
- package/fesm/interfaces-index.js +0 -0
- package/fesm/modules-index.js +0 -1
- package/fesm/services-index.js +0 -1
- package/fesm/types-index.js +0 -1
package/fesm/services-index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __name=(target,value)=>__defProp(target,"name",{value,configurable:true});var __esm=(fn,res)=>function __init(){return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __decorateClass=(decorators,target,key,kind)=>{var result=kind>1?void 0:kind?__getOwnPropDesc(target,key):target;for(var i=decorators.length-1,decorator;i>=0;i--)if(decorator=decorators[i])result=(kind?decorator(target,key,result):decorator(result))||result;if(kind&&result)__defProp(target,key,result);return result};var __decorateParam=(index,decorator)=>(target,key)=>decorator(target,key,index);var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var ActionType;var init_action_type_enum=__esm({"projects/nestjs-iam/src/enums/action-type.enum.ts"(){"use strict";ActionType=(ActionType2=>{ActionType2["BACKEND"]="backend";ActionType2["FRONTEND"]="frontend";ActionType2["BOTH"]="both";return ActionType2})(ActionType||{})}});var IAMPermissionMode;var init_permission_type_enum=__esm({"projects/nestjs-iam/src/enums/permission-type.enum.ts"(){"use strict";IAMPermissionMode=(IAMPermissionMode2=>{IAMPermissionMode2[IAMPermissionMode2["RBAC"]=1]="RBAC";IAMPermissionMode2[IAMPermissionMode2["DIRECT"]=2]="DIRECT";IAMPermissionMode2[IAMPermissionMode2["FULL"]=3]="FULL";return IAMPermissionMode2})(IAMPermissionMode||{})}});var init_enums=__esm({"projects/nestjs-iam/src/enums/index.ts"(){"use strict";init_action_type_enum();init_permission_type_enum()}});import{Identity}from"@flusys/nestjs-shared";import{Column,JoinColumn,ManyToOne,OneToMany}from"typeorm";var ActionBase;var init_action_base_entity=__esm({"projects/nestjs-iam/src/entities/action-base.entity.ts"(){"use strict";init_enums();ActionBase=class extends Identity{static{__name(this,"ActionBase")}readOnly;name;description;code;actionType;permissionLogic;serial;isActive;parent;parentId;children;metadata};__decorateClass([Column({type:"boolean",nullable:false,default:false,name:"read_only"})],ActionBase.prototype,"readOnly",2);__decorateClass([Column({type:"varchar",length:255,nullable:false})],ActionBase.prototype,"name",2);__decorateClass([Column({type:"varchar",length:500,nullable:true})],ActionBase.prototype,"description",2);__decorateClass([Column({type:"varchar",length:255,nullable:true,unique:true})],ActionBase.prototype,"code",2);__decorateClass([Column({type:"enum",enum:ActionType,nullable:false,default:"backend",name:"action_type"})],ActionBase.prototype,"actionType",2);__decorateClass([Column("simple-json",{nullable:true,name:"permission_logic"})],ActionBase.prototype,"permissionLogic",2);__decorateClass([Column({type:"int",nullable:true})],ActionBase.prototype,"serial",2);__decorateClass([Column({type:"boolean",nullable:false,default:true,name:"is_active"})],ActionBase.prototype,"isActive",2);__decorateClass([ManyToOne("Action","children",{nullable:true,onDelete:"CASCADE"}),JoinColumn({name:"parent_id"})],ActionBase.prototype,"parent",2);__decorateClass([Column({type:"uuid",nullable:true,name:"parent_id"})],ActionBase.prototype,"parentId",2);__decorateClass([OneToMany("Action","parent")],ActionBase.prototype,"children",2);__decorateClass([Column("simple-json",{nullable:true})],ActionBase.prototype,"metadata",2)}});import{Entity,Index}from"typeorm";var Action;var init_action_entity=__esm({"projects/nestjs-iam/src/entities/action.entity.ts"(){"use strict";init_action_base_entity();Action=class extends ActionBase{};__name(Action,"Action");Action=__decorateClass([Entity({name:"action"}),Index(["parentId"])],Action)}});import{Identity as Identity2}from"@flusys/nestjs-shared";import{Column as Column2}from"typeorm";var IamPermissionType,IamEntityType,PermissionBase;var init_permission_base_entity=__esm({"projects/nestjs-iam/src/entities/permission-base.entity.ts"(){"use strict";IamPermissionType=(IamPermissionType2=>{IamPermissionType2["USER_ROLE"]="user_role";IamPermissionType2["ROLE_ACTION"]="role_action";IamPermissionType2["USER_ACTION"]="user_action";IamPermissionType2["COMPANY_ACTION"]="company_action";return IamPermissionType2})(IamPermissionType||{});IamEntityType=(IamEntityType2=>{IamEntityType2["USER"]="user";IamEntityType2["ROLE"]="role";IamEntityType2["ACTION"]="action";IamEntityType2["COMPANY"]="company";return IamEntityType2})(IamEntityType||{});PermissionBase=class extends Identity2{static{__name(this,"PermissionBase")}permissionType;sourceType;sourceId;targetType;targetId;userId;validFrom;validUntil;reason;metadata;isUserRole(){return this.permissionType==="user_role"}isRoleAction(){return this.permissionType==="role_action"}isUserAction(){return this.permissionType==="user_action"}isCompanyAction(){return this.permissionType==="company_action"}isValid(now=new Date){if(this.validFrom&&now<this.validFrom)return false;if(this.validUntil&&now>this.validUntil)return false;return true}};__decorateClass([Column2({type:"enum",enum:IamPermissionType,name:"permission_type"})],PermissionBase.prototype,"permissionType",2);__decorateClass([Column2({type:"enum",enum:IamEntityType,name:"source_type"})],PermissionBase.prototype,"sourceType",2);__decorateClass([Column2({type:"uuid",name:"source_id"})],PermissionBase.prototype,"sourceId",2);__decorateClass([Column2({type:"enum",enum:IamEntityType,name:"target_type"})],PermissionBase.prototype,"targetType",2);__decorateClass([Column2({type:"uuid",name:"target_id"})],PermissionBase.prototype,"targetId",2);__decorateClass([Column2({type:"uuid",nullable:true,name:"user_id"})],PermissionBase.prototype,"userId",2);__decorateClass([Column2({type:"timestamp",nullable:true,name:"valid_from"})],PermissionBase.prototype,"validFrom",2);__decorateClass([Column2({type:"timestamp",nullable:true,name:"valid_until"})],PermissionBase.prototype,"validUntil",2);__decorateClass([Column2({type:"text",nullable:true})],PermissionBase.prototype,"reason",2);__decorateClass([Column2("simple-json",{nullable:true})],PermissionBase.prototype,"metadata",2)}});import{Column as Column3,Entity as Entity2,Index as Index2}from"typeorm";var UserIamPermissionWithCompany;var init_permission_with_company_entity=__esm({"projects/nestjs-iam/src/entities/permission-with-company.entity.ts"(){"use strict";init_permission_base_entity();UserIamPermissionWithCompany=class extends PermissionBase{companyId;branchId};__name(UserIamPermissionWithCompany,"UserIamPermissionWithCompany");__decorateClass([Column3({type:"uuid",nullable:true,name:"company_id"})],UserIamPermissionWithCompany.prototype,"companyId",2);__decorateClass([Column3({type:"uuid",nullable:true,name:"branch_id"})],UserIamPermissionWithCompany.prototype,"branchId",2);UserIamPermissionWithCompany=__decorateClass([Entity2({name:"user_iam_permission"}),Index2(["permissionType","sourceId","targetId"],{unique:true}),Index2(["sourceId","sourceType"]),Index2(["targetId","targetType"]),Index2(["permissionType"]),Index2(["userId"]),Index2(["companyId"]),Index2(["branchId"]),Index2(["companyId","branchId"])],UserIamPermissionWithCompany)}});import{Identity as Identity3}from"@flusys/nestjs-shared";import{Column as Column4}from"typeorm";var RoleBase;var init_role_base_entity=__esm({"projects/nestjs-iam/src/entities/role-base.entity.ts"(){"use strict";RoleBase=class extends Identity3{static{__name(this,"RoleBase")}readOnly;name;description;isActive;serial;metadata};__decorateClass([Column4({type:"boolean",nullable:false,default:false,name:"read_only"})],RoleBase.prototype,"readOnly",2);__decorateClass([Column4({type:"varchar",length:255,nullable:false})],RoleBase.prototype,"name",2);__decorateClass([Column4({type:"varchar",length:500,nullable:true})],RoleBase.prototype,"description",2);__decorateClass([Column4({type:"boolean",nullable:false,default:true,name:"is_active"})],RoleBase.prototype,"isActive",2);__decorateClass([Column4({type:"int",nullable:true})],RoleBase.prototype,"serial",2);__decorateClass([Column4("simple-json",{nullable:true})],RoleBase.prototype,"metadata",2)}});import{Column as Column5,Entity as Entity3,Index as Index3}from"typeorm";var RoleWithCompany;var init_role_with_company_entity=__esm({"projects/nestjs-iam/src/entities/role-with-company.entity.ts"(){"use strict";init_role_base_entity();RoleWithCompany=class extends RoleBase{companyId};__name(RoleWithCompany,"RoleWithCompany");__decorateClass([Column5({type:"uuid",nullable:true,name:"company_id"})],RoleWithCompany.prototype,"companyId",2);RoleWithCompany=__decorateClass([Entity3({name:"role"}),Index3(["companyId"])],RoleWithCompany)}});import{Entity as Entity4}from"typeorm";var Role;var init_role_entity=__esm({"projects/nestjs-iam/src/entities/role.entity.ts"(){"use strict";init_role_base_entity();Role=class extends RoleBase{};__name(Role,"Role");Role=__decorateClass([Entity4({name:"role"})],Role)}});import{Entity as Entity5,Index as Index5}from"typeorm";var UserIamPermission;var init_user_iam_permission_entity=__esm({"projects/nestjs-iam/src/entities/user-iam-permission.entity.ts"(){"use strict";init_permission_base_entity();init_permission_base_entity();UserIamPermission=class extends PermissionBase{};__name(UserIamPermission,"UserIamPermission");UserIamPermission=__decorateClass([Entity5({name:"user_iam_permission"}),Index5(["permissionType","sourceId","targetId"],{unique:true}),Index5(["sourceId","sourceType"]),Index5(["targetId","targetType"]),Index5(["permissionType"]),Index5(["userId"])],UserIamPermission)}});var entities_exports={};__export(entities_exports,{Action:()=>Action,ActionBase:()=>ActionBase,IAMAllEntities:()=>IAMAllEntities,IAMCompanyEntities:()=>IAMCompanyEntities,IAMCoreEntities:()=>IAMCoreEntities,IamEntityType:()=>IamEntityType,IamPermissionType:()=>IamPermissionType,PermissionBase:()=>PermissionBase,Role:()=>Role,RoleBase:()=>RoleBase,RoleWithCompany:()=>RoleWithCompany,UserIamPermission:()=>UserIamPermission,UserIamPermissionWithCompany:()=>UserIamPermissionWithCompany,getIAMEntitiesByConfig:()=>getIAMEntitiesByConfig});function getIAMEntitiesByConfig(enableCompanyFeature,permissionMode="FULL"){const entities=[Action];if(enableCompanyFeature){entities.push(UserIamPermissionWithCompany)}else{entities.push(UserIamPermission)}if(permissionMode==="RBAC"||permissionMode==="FULL"){if(enableCompanyFeature){entities.push(RoleWithCompany)}else{entities.push(Role)}}return entities}var IAMCoreEntities,IAMCompanyEntities,IAMAllEntities;var init_entities=__esm({"projects/nestjs-iam/src/entities/index.ts"(){"use strict";init_action_base_entity();init_action_entity();init_permission_base_entity();init_permission_with_company_entity();init_role_base_entity();init_role_with_company_entity();init_role_entity();init_user_iam_permission_entity();init_action_entity();init_role_entity();init_role_with_company_entity();init_user_iam_permission_entity();init_permission_with_company_entity();IAMCoreEntities=[Action,Role,UserIamPermission];IAMCompanyEntities=[RoleWithCompany,UserIamPermissionWithCompany];IAMAllEntities=[Action,Role,RoleWithCompany,UserIamPermission,UserIamPermissionWithCompany];__name(getIAMEntitiesByConfig,"getIAMEntitiesByConfig")}});init_action_entity();import{RequestScopedApiService}from"@flusys/nestjs-shared/classes";import{UtilsService}from"@flusys/nestjs-shared/modules";import{Inject as Inject5,Injectable as Injectable6,Logger as Logger4,NotFoundException,Scope as Scope3}from"@nestjs/common";import{In as In2}from"typeorm";import{Inject,Injectable as Injectable2,Optional}from"@nestjs/common";var IAM_MODULE_OPTIONS="IAM_MODULE_OPTIONS";init_permission_type_enum();import{Injectable}from"@nestjs/common";var PermissionEvaluatorHelper=class{evaluate(logic,context){if(!logic){return true}return this.evaluateNode(logic,context)}evaluateNode(node,context){switch(node.type){case"action":return this.evaluateAction(node.actionId,context);case"group":return this.evaluateGroup(node,context);default:return false}}evaluateAction(actionId,context){if(context.deniedActionIds.has(actionId)){return false}if(context.grantedActionIds.has(actionId)){return true}if(context.inheritedActionIds?.has(actionId)){return true}return false}evaluateGroup(node,context){if(!node.children||node.children.length===0){return false}const results=node.children.map(child=>this.evaluateNode(child,context));if(node.operator==="AND"){return results.every(result=>result===true)}else if(node.operator==="OR"){return results.some(result=>result===true)}return false}batchEvaluate(logics,context){const results=new Map;for(const item of logics){results.set(item.id,this.evaluate(item.logic,context))}return results}hasAnyAction(actionIds,context){return actionIds.some(actionId=>this.evaluateAction(actionId,context))}hasAllActions(actionIds,context){return actionIds.every(actionId=>this.evaluateAction(actionId,context))}hasAnyRole(roleIds,context){return roleIds.some(roleId=>context.roleIds.has(roleId))}hasAllRoles(roleIds,context){return roleIds.every(roleId=>context.roleIds.has(roleId))}evaluateLogicNode(logic,actionCodes){if(!logic){return true}return this.evaluateNodeSimple(logic,actionCodes)}evaluateNodeSimple(node,actionCodes){switch(node.type){case"action":return node.actionId?actionCodes.has(node.actionId):false;case"group":return this.evaluateGroupSimple(node,actionCodes);default:return false}}evaluateGroupSimple(node,actionCodes){if(!node.children||node.children.length===0){return node.operator==="AND"}const results=node.children.map(child=>this.evaluateNodeSimple(child,actionCodes));if(node.operator==="AND"){return results.every(result=>result===true)}else if(node.operator==="OR"){return results.some(result=>result===true)}return false}};__name(PermissionEvaluatorHelper,"PermissionEvaluatorHelper");PermissionEvaluatorHelper=__decorateClass([Injectable()],PermissionEvaluatorHelper);init_permission_type_enum();var PermissionModeHelper=class{static{__name(this,"PermissionModeHelper")}static fromString(modeStr){if(!modeStr){return 3}const mode=IAMPermissionMode[modeStr];return mode??3}static toString(mode){return IAMPermissionMode[mode]}};var IAMConfigService=class{options;constructor(injectedOptions){this.options=injectedOptions??{global:false,includeController:false}}getDatabaseMode(){return this.options.bootstrapAppConfig?.databaseMode??"single"}isMultiTenant(){return this.getDatabaseMode()==="multi-tenant"}getEnableCompanyFeature(){return this.options.bootstrapAppConfig?.enableCompanyFeature??false}isCompanyFeatureEnabled(){return this.getEnableCompanyFeature()}getPermissionMode(){return PermissionModeHelper.fromString(this.options.bootstrapAppConfig?.permissionMode)}isRbacEnabled(){const mode=this.getPermissionMode();return mode===1||mode===3}isDirectPermissionEnabled(){const mode=this.getPermissionMode();return mode===2||mode===3}getOptions(){return this.options}};__name(IAMConfigService,"IAMConfigService");IAMConfigService=__decorateClass([Injectable2(),__decorateParam(0,Optional()),__decorateParam(0,Inject(IAM_MODULE_OPTIONS))],IAMConfigService);import{MultiTenantDataSourceService}from"@flusys/nestjs-shared/modules";import{Inject as Inject2,Injectable as Injectable3,Logger,Optional as Optional2,Scope}from"@nestjs/common";import{REQUEST}from"@nestjs/core";var IAMDataSourceProvider=class extends MultiTenantDataSourceService{constructor(iamOptions,request){super(IAMDataSourceProvider.buildParentOptions(iamOptions),request);this.iamOptions=iamOptions}logger=new Logger(IAMDataSourceProvider.name);static buildParentOptions(options){return{bootstrapAppConfig:options.bootstrapAppConfig,defaultDatabaseConfig:options.config?.defaultDatabaseConfig,tenantDefaultDatabaseConfig:options.config?.tenantDefaultDatabaseConfig,tenants:options.config?.tenants}}getEnableCompanyFeature(){return this.iamOptions.bootstrapAppConfig?.enableCompanyFeature??false}getEnableCompanyFeatureForTenant(tenant){return tenant?.enableCompanyFeature??this.getEnableCompanyFeature()}getEnableCompanyFeatureForCurrentTenant(){return this.getEnableCompanyFeatureForTenant(this.getCurrentTenant()??void 0)}async getIAMEntities(){const{Action:Action2,Role:Role2,RoleWithCompany:RoleWithCompany2,UserIamPermission:UserIamPermission2,UserIamPermissionWithCompany:UserIamPermissionWithCompany2,getIAMEntitiesByConfig:getIAMEntitiesByConfig2}=await Promise.resolve().then(()=>(init_entities(),entities_exports));const enableCompanyFeature=this.getEnableCompanyFeatureForCurrentTenant();const permissionMode=this.iamOptions.bootstrapAppConfig?.permissionMode||"FULL";return getIAMEntitiesByConfig2(enableCompanyFeature,permissionMode)}async createDataSourceFromConfig(config){const entities=await this.getIAMEntities();return super.createDataSourceFromConfig(config,entities)}async getSingleDataSource(){if(!IAMDataSourceProvider.singleDataSource){if(IAMDataSourceProvider.singleConnectionLock){return IAMDataSourceProvider.singleConnectionLock}const lockPromise=(async()=>{const config=this.getDefaultDatabaseConfig();if(!config){throw new Error("Default database config is not available")}const ds=await this.createDataSourceFromConfig(config);IAMDataSourceProvider.singleDataSource=ds;IAMDataSourceProvider.initialized=true;return ds})();IAMDataSourceProvider.singleConnectionLock=lockPromise;try{return await lockPromise}finally{IAMDataSourceProvider.singleConnectionLock=null}}return IAMDataSourceProvider.singleDataSource}async getOrCreateTenantConnection(tenant){const existing=IAMDataSourceProvider.tenantConnections.get(tenant.id);if(existing?.isInitialized){return existing}const pendingConnection=IAMDataSourceProvider.connectionLocks.get(tenant.id);if(pendingConnection){return pendingConnection}const config=this.buildTenantDatabaseConfig(tenant);const connectionPromise=this.createDataSourceFromConfig(config);IAMDataSourceProvider.connectionLocks.set(tenant.id,connectionPromise);try{const dataSource=await connectionPromise;IAMDataSourceProvider.tenantConnections.set(tenant.id,dataSource);return dataSource}finally{IAMDataSourceProvider.connectionLocks.delete(tenant.id)}}};__name(IAMDataSourceProvider,"IAMDataSourceProvider");__publicField(IAMDataSourceProvider,"tenantConnections",new Map);__publicField(IAMDataSourceProvider,"singleDataSource",null);__publicField(IAMDataSourceProvider,"tenantsRegistry",new Map);__publicField(IAMDataSourceProvider,"initialized",false);__publicField(IAMDataSourceProvider,"connectionLocks",new Map);__publicField(IAMDataSourceProvider,"singleConnectionLock",null);IAMDataSourceProvider=__decorateClass([Injectable3({scope:Scope.REQUEST}),__decorateParam(0,Inject2(IAM_MODULE_OPTIONS)),__decorateParam(1,Optional2()),__decorateParam(1,Inject2(REQUEST))],IAMDataSourceProvider);import{Inject as Inject4,Injectable as Injectable5,Logger as Logger3,Scope as Scope2}from"@nestjs/common";import{In,IsNull}from"typeorm";import{ApiProperty,ApiPropertyOptional}from"@nestjs/swagger";import{Type}from"class-transformer";import{IsArray,IsEnum,IsOptional,IsString,IsUUID,ValidateNested}from"class-validator";var PermissionAction=(PermissionAction2=>{PermissionAction2["ADD"]="add";PermissionAction2["REMOVE"]="remove";return PermissionAction2})(PermissionAction||{});var PermissionItemDto=class{static{__name(this,"PermissionItemDto")}id;action};__decorateClass([ApiProperty({description:"ID of the target (action or role)"}),IsUUID()],PermissionItemDto.prototype,"id",2);__decorateClass([ApiProperty({description:"Action to perform",enum:PermissionAction,example:"add"}),IsEnum(PermissionAction)],PermissionItemDto.prototype,"action",2);var AssignUserActionsDto=class{static{__name(this,"AssignUserActionsDto")}userId;companyId;branchId;items};__decorateClass([ApiProperty({description:"User ID"}),IsUUID()],AssignUserActionsDto.prototype,"userId",2);__decorateClass([ApiPropertyOptional({description:"Company ID (for company-wide or branch-specific assignments)"}),IsUUID(),IsOptional()],AssignUserActionsDto.prototype,"companyId",2);__decorateClass([ApiPropertyOptional({description:"Branch ID (null = company-wide, set = branch-specific)"}),IsUUID(),IsOptional()],AssignUserActionsDto.prototype,"branchId",2);__decorateClass([ApiProperty({description:"Array of actions to assign/remove",type:[PermissionItemDto]}),IsArray(),ValidateNested({each:true}),Type(()=>PermissionItemDto)],AssignUserActionsDto.prototype,"items",2);var AssignCompanyActionsDto=class{static{__name(this,"AssignCompanyActionsDto")}companyId;items};__decorateClass([ApiProperty({description:"Company ID"}),IsUUID()],AssignCompanyActionsDto.prototype,"companyId",2);__decorateClass([ApiProperty({description:"Array of actions to assign/remove to company (whitelist)",type:[PermissionItemDto]}),IsArray(),ValidateNested({each:true}),Type(()=>PermissionItemDto)],AssignCompanyActionsDto.prototype,"items",2);var AssignRoleActionsDto=class{static{__name(this,"AssignRoleActionsDto")}roleId;items};__decorateClass([ApiProperty({description:"Role ID"}),IsUUID()],AssignRoleActionsDto.prototype,"roleId",2);__decorateClass([ApiProperty({description:"Array of actions to assign/remove",type:[PermissionItemDto]}),IsArray(),ValidateNested({each:true}),Type(()=>PermissionItemDto)],AssignRoleActionsDto.prototype,"items",2);var AssignUserRolesDto=class{static{__name(this,"AssignUserRolesDto")}userId;companyId;branchId;items};__decorateClass([ApiProperty({description:"User ID"}),IsUUID()],AssignUserRolesDto.prototype,"userId",2);__decorateClass([ApiPropertyOptional({description:"Company ID (for company-wide or branch-specific assignments)"}),IsUUID(),IsOptional()],AssignUserRolesDto.prototype,"companyId",2);__decorateClass([ApiPropertyOptional({description:"Branch ID (null = company-wide, set = branch-specific)"}),IsUUID(),IsOptional()],AssignUserRolesDto.prototype,"branchId",2);__decorateClass([ApiProperty({description:"Array of roles to assign/remove",type:[PermissionItemDto]}),IsArray(),ValidateNested({each:true}),Type(()=>PermissionItemDto)],AssignUserRolesDto.prototype,"items",2);var GetUserActionsDto=class{static{__name(this,"GetUserActionsDto")}companyId;branchId};__decorateClass([ApiPropertyOptional({description:"Company ID (ignored when enableCompanyFeature is false)"}),IsUUID(),IsOptional()],GetUserActionsDto.prototype,"companyId",2);__decorateClass([ApiPropertyOptional({description:"Branch ID to filter by branch (ignored when enableCompanyFeature is false)"}),IsUUID(),IsOptional()],GetUserActionsDto.prototype,"branchId",2);var GetUserRolesDto=class{static{__name(this,"GetUserRolesDto")}companyId;branchId};__decorateClass([ApiPropertyOptional({description:"Company ID (ignored when enableCompanyFeature is false)"}),IsUUID(),IsOptional()],GetUserRolesDto.prototype,"companyId",2);__decorateClass([ApiPropertyOptional({description:"Branch ID to filter by branch (ignored when enableCompanyFeature is false)"}),IsUUID(),IsOptional()],GetUserRolesDto.prototype,"branchId",2);var UserActionResponseDto=class{static{__name(this,"UserActionResponseDto")}id;userId;actionId;actionCode;actionName;branchId;createdAt};__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"id",2);__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"userId",2);__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"actionId",2);__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"actionCode",2);__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"actionName",2);__decorateClass([ApiPropertyOptional()],UserActionResponseDto.prototype,"branchId",2);__decorateClass([ApiProperty()],UserActionResponseDto.prototype,"createdAt",2);var RoleActionResponseDto=class{static{__name(this,"RoleActionResponseDto")}id;roleId;actionId;actionCode;actionName;createdAt};__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"id",2);__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"roleId",2);__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"actionId",2);__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"actionCode",2);__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"actionName",2);__decorateClass([ApiProperty()],RoleActionResponseDto.prototype,"createdAt",2);var CompanyActionResponseDto=class{static{__name(this,"CompanyActionResponseDto")}id;companyId;actionId;actionCode;actionName;createdAt};__decorateClass([ApiProperty({description:"Permission ID"})],CompanyActionResponseDto.prototype,"id",2);__decorateClass([ApiProperty({description:"Company ID"})],CompanyActionResponseDto.prototype,"companyId",2);__decorateClass([ApiProperty({description:"Action ID"})],CompanyActionResponseDto.prototype,"actionId",2);__decorateClass([ApiProperty({description:"Action Code"})],CompanyActionResponseDto.prototype,"actionCode",2);__decorateClass([ApiProperty({description:"Action Name"})],CompanyActionResponseDto.prototype,"actionName",2);__decorateClass([ApiProperty({description:"When this permission was created"})],CompanyActionResponseDto.prototype,"createdAt",2);var UserRoleResponseDto=class{static{__name(this,"UserRoleResponseDto")}id;userId;roleId;roleName;branchId;createdAt};__decorateClass([ApiProperty()],UserRoleResponseDto.prototype,"id",2);__decorateClass([ApiProperty()],UserRoleResponseDto.prototype,"userId",2);__decorateClass([ApiProperty()],UserRoleResponseDto.prototype,"roleId",2);__decorateClass([ApiProperty()],UserRoleResponseDto.prototype,"roleName",2);__decorateClass([ApiPropertyOptional()],UserRoleResponseDto.prototype,"branchId",2);__decorateClass([ApiProperty()],UserRoleResponseDto.prototype,"createdAt",2);var FrontendActionDto=class{static{__name(this,"FrontendActionDto")}id;code;name;description};__decorateClass([ApiProperty()],FrontendActionDto.prototype,"id",2);__decorateClass([ApiProperty()],FrontendActionDto.prototype,"code",2);__decorateClass([ApiProperty()],FrontendActionDto.prototype,"name",2);__decorateClass([ApiPropertyOptional()],FrontendActionDto.prototype,"description",2);var MyPermissionsQueryDto=class{static{__name(this,"MyPermissionsQueryDto")}parentCodes};__decorateClass([ApiPropertyOptional({description:"Filter by parent action codes",example:["user","role"],type:[String]}),IsArray(),IsString({each:true}),IsOptional()],MyPermissionsQueryDto.prototype,"parentCodes",2);var MyPermissionsResponseDto=class{static{__name(this,"MyPermissionsResponseDto")}frontendActions;cachedEndpoints};__decorateClass([ApiProperty({type:[FrontendActionDto]})],MyPermissionsResponseDto.prototype,"frontendActions",2);__decorateClass([ApiProperty({description:"Number of endpoint actions cached for PermissionGuard"})],MyPermissionsResponseDto.prototype,"cachedEndpoints",2);var PermissionOperationResultDto=class{static{__name(this,"PermissionOperationResultDto")}success;added;removed;message};__decorateClass([ApiProperty()],PermissionOperationResultDto.prototype,"success",2);__decorateClass([ApiProperty()],PermissionOperationResultDto.prototype,"added",2);__decorateClass([ApiProperty()],PermissionOperationResultDto.prototype,"removed",2);__decorateClass([ApiProperty()],PermissionOperationResultDto.prototype,"message",2);init_action_entity();init_permission_with_company_entity();init_role_with_company_entity();init_role_entity();init_user_iam_permission_entity();init_action_type_enum();init_permission_type_enum();import{Inject as Inject3,Injectable as Injectable4,Logger as Logger2}from"@nestjs/common";var PermissionCacheService=class{constructor(cacheManager){this.cacheManager=cacheManager}logger=new Logger2(PermissionCacheService.name);TTL=36e5;ACTION_CODE_TTL=72e5;CACHE_PREFIX="permissions";MY_PERMISSIONS_PREFIX="my-permissions";ACTION_CODE_PREFIX="action-codes";generateCacheKey(options){const{userId,companyId,branchId,enableCompanyFeature}=options;if(enableCompanyFeature&&companyId){return`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId||"null"}:user:${userId}`}return`${this.CACHE_PREFIX}:user:${userId}`}generateMyPermissionsCacheKey(options){const{userId,companyId,branchId,enableCompanyFeature}=options;if(enableCompanyFeature&&companyId){return`${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId||"null"}:user:${userId}`}return`${this.MY_PERMISSIONS_PREFIX}:user:${userId}`}async setPermissions(options,permissions){try{const key=this.generateCacheKey(options);await this.cacheManager.set(key,permissions,this.TTL);this.logger.debug(`Cached ${permissions.length} permissions for key: ${key}`)}catch(error){this.logger.error(`Failed to cache permissions: ${error}`)}}async getPermissions(options){try{const key=this.generateCacheKey(options);const result=await this.cacheManager.get(key);return result||null}catch(error){this.logger.error(`Failed to get permissions from cache: ${error}`);return null}}async setMyPermissions(options,data){try{const key=this.generateMyPermissionsCacheKey(options);await this.cacheManager.set(key,data,this.TTL);this.logger.debug(`Cached my-permissions for key: ${key} (${data.frontendActions.length} frontend, ${data.backendCodes.length} backend)`)}catch(error){this.logger.error(`Failed to cache my-permissions: ${error}`)}}async getMyPermissions(options){try{const key=this.generateMyPermissionsCacheKey(options);const result=await this.cacheManager.get(key);if(result){this.logger.debug(`Cache hit for my-permissions: ${key}`)}return result||null}catch(error){this.logger.error(`Failed to get my-permissions from cache: ${error}`);return null}}async setActionCodeMap(codeToIdMap){try{const key=`${this.ACTION_CODE_PREFIX}:map`;await this.cacheManager.set(key,codeToIdMap,this.ACTION_CODE_TTL);this.logger.debug(`Cached ${Object.keys(codeToIdMap).length} action code mappings`)}catch(error){this.logger.error(`Failed to cache action code map: ${error}`)}}async getActionIdsByCodes(codes){try{const key=`${this.ACTION_CODE_PREFIX}:map`;const fullMap=await this.cacheManager.get(key);if(!fullMap){return null}const result={};for(const code of codes){if(fullMap[code]){result[code]=fullMap[code]}}return Object.keys(result).length>0?result:null}catch(error){this.logger.error(`Failed to get action IDs from cache: ${error}`);return null}}async invalidateActionCodeCache(){try{const key=`${this.ACTION_CODE_PREFIX}:map`;await this.cacheManager.del(key);this.logger.debug("Invalidated action code cache")}catch(error){this.logger.warn(`Failed to invalidate action code cache: ${error}`)}}async invalidateUser(userId,companyId,branchIds){try{const keysToDelete=[`${this.CACHE_PREFIX}:user:${userId}`,`${this.MY_PERMISSIONS_PREFIX}:user:${userId}`];if(companyId){const branches=branchIds?.length?branchIds:[null];for(const branchId of branches){keysToDelete.push(`${this.CACHE_PREFIX}:company:${companyId}:branch:${branchId||"null"}:user:${userId}`,`${this.MY_PERMISSIONS_PREFIX}:company:${companyId}:branch:${branchId||"null"}:user:${userId}`)}}await Promise.all(keysToDelete.map(key=>this.cacheManager.del(key)));this.logger.debug(`Invalidated ${keysToDelete.length} cache keys for user ${userId}`)}catch(error){this.logger.warn(`Failed to invalidate user cache for ${userId}: ${error}`)}}async invalidateUsers(userIds,companyId,branchIds){if(userIds.length===0){return 0}const results=await Promise.allSettled(userIds.map(userId=>this.invalidateUser(userId,companyId,branchIds)));const successCount=results.filter(r=>r.status==="fulfilled").length;const failedCount=results.filter(r=>r.status==="rejected").length;if(failedCount>0){this.logger.warn(`Failed to invalidate cache for ${failedCount} users`)}if(successCount>0){this.logger.log(`Invalidated cache for ${successCount} users`)}return successCount}async invalidateCompany(companyId){this.logger.warn(`invalidateCompany called for ${companyId}, but pattern matching is not supported. Use invalidateUsers() with specific user IDs instead.`);return 0}async invalidateRole(roleId,userIds,companyId,branchIds){if(userIds.length===0){this.logger.debug(`No users found for role ${roleId}`);return 0}const count=await this.invalidateUsers(userIds,companyId,branchIds);if(count>0){this.logger.log(`Invalidated cache for ${count} users with role ${roleId}`)}return count}async clearAll(){try{await this.cacheManager.reset();await this.cacheManager.resetL2();this.logger.warn("Cleared all cache entries (memory and redis)")}catch(error){this.logger.error(`Failed to clear all caches: ${error}`)}}};__name(PermissionCacheService,"PermissionCacheService");PermissionCacheService=__decorateClass([Injectable4(),__decorateParam(0,Inject3("CACHE_INSTANCE"))],PermissionCacheService);var PermissionService=class{constructor(permissionEvaluator,permissionCacheService,iamConfigService,dataSourceProvider){this.permissionEvaluator=permissionEvaluator;this.permissionCacheService=permissionCacheService;this.iamConfigService=iamConfigService;this.dataSourceProvider=dataSourceProvider}logger=new Logger3(PermissionService.name);async getPermissionRepository(){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const entity=enableCompanyFeature?UserIamPermissionWithCompany:UserIamPermission;return this.dataSourceProvider.getRepository(entity)}async getActionRepository(){return this.dataSourceProvider.getRepository(Action)}async getRoleRepository(){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const entity=enableCompanyFeature?RoleWithCompany:Role;return this.dataSourceProvider.getRepository(entity)}async assignUserActions(dto){const permissionRepo=await this.getPermissionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const branchId=dto.branchId??null;const companyId=dto.companyId??null;const itemsToAdd=dto.items.filter(item=>item.action==="add");const itemsToRemove=dto.items.filter(item=>item.action==="remove");let added=0;let removed=0;if(itemsToAdd.length>0){const actionIdsToAdd=itemsToAdd.map(item=>item.id);const whereFind={permissionType:"user_action",sourceType:"user",sourceId:dto.userId,targetType:"action",targetId:In(actionIdsToAdd)};if(enableCompanyFeature){if(companyId)whereFind.companyId=companyId;if(branchId)whereFind.branchId=branchId}const existingPermissions=await permissionRepo.find({where:whereFind,select:["targetId"]});const existingActionIds=new Set(existingPermissions.map(p=>p.targetId));const newPermissions=itemsToAdd.filter(item=>!existingActionIds.has(item.id)).map(item=>({permissionType:"user_action",sourceType:"user",sourceId:dto.userId,targetType:"action",targetId:item.id,userId:dto.userId,companyId:enableCompanyFeature?companyId:null,branchId:enableCompanyFeature?branchId:null}));if(newPermissions.length>0){await permissionRepo.save(newPermissions);added=newPermissions.length}}if(itemsToRemove.length>0){const actionIdsToRemove=itemsToRemove.map(item=>item.id);const whereDelete={permissionType:"user_action",sourceType:"user",sourceId:dto.userId,targetType:"action",targetId:In(actionIdsToRemove)};if(enableCompanyFeature){if(companyId)whereDelete.companyId=companyId;if(branchId)whereDelete.branchId=branchId}const result=await permissionRepo.delete(whereDelete);removed=result.affected||0}await this.invalidateUserPermissionCache(dto.userId,branchId,companyId);return{success:true,added,removed,message:`Successfully processed ${dto.items.length} items: ${added} added, ${removed} removed`}}async getUserActions(userId,branchId,companyId){const permissionRepo=await this.getPermissionRepository();const actionRepo=await this.getActionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const where={permissionType:"user_action",sourceType:"user",sourceId:userId};if(enableCompanyFeature){if(companyId){where.companyId=companyId}if(branchId){where.branchId=branchId}else{where.branchId=null}}const permissions=await permissionRepo.find({where});if(permissions.length===0){return[]}const actionIds=permissions.map(p=>p.targetId);const actionWhere={id:In(actionIds)};const actions=await actionRepo.find({where:actionWhere});const actionMap=new Map(actions.map(a=>[a.id,a]));return permissions.filter(p=>actionMap.has(p.targetId)).map(p=>{const action=actionMap.get(p.targetId);return{id:p.id,userId:p.userId,actionId:action.id,actionCode:action.code??"",actionName:action.name,branchId:("branchId"in p?p.branchId:null)??null,createdAt:p.createdAt}})}async assignRoleActions(dto){const permissionRepo=await this.getPermissionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();let roleCompanyId=null;if(enableCompanyFeature){const roleRepo=await this.getRoleRepository();const role=await roleRepo.findOne({where:{id:dto.roleId},select:["id","companyId"]});roleCompanyId=role?.companyId??null}const itemsToAdd=dto.items.filter(item=>item.action==="add");const itemsToRemove=dto.items.filter(item=>item.action==="remove");let added=0;let removed=0;if(itemsToAdd.length>0){const actionIdsToAdd=itemsToAdd.map(item=>item.id);const existingPermissions=await permissionRepo.find({where:{permissionType:"role_action",sourceType:"role",sourceId:dto.roleId,targetType:"action",targetId:In(actionIdsToAdd)},select:["targetId"]});const existingActionIds=new Set(existingPermissions.map(p=>p.targetId));const newPermissions=itemsToAdd.filter(item=>!existingActionIds.has(item.id)).map(item=>({permissionType:"role_action",sourceType:"role",sourceId:dto.roleId,targetType:"action",targetId:item.id,userId:null,companyId:enableCompanyFeature?roleCompanyId:null,branchId:null}));if(newPermissions.length>0){await permissionRepo.save(newPermissions);added=newPermissions.length}}if(itemsToRemove.length>0){const actionIdsToRemove=itemsToRemove.map(item=>item.id);const result=await permissionRepo.delete({permissionType:"role_action",sourceType:"role",sourceId:dto.roleId,targetType:"action",targetId:In(actionIdsToRemove)});removed=result.affected||0}const affectedUsers=await this.invalidateRoleMembersCache(dto.roleId);return{success:true,added,removed,message:`Successfully processed ${dto.items.length} items: ${added} added, ${removed} removed. Invalidated cache for ${affectedUsers} users.`}}async getRoleActions(roleId){const permissionRepo=await this.getPermissionRepository();const actionRepo=await this.getActionRepository();const permissions=await permissionRepo.find({where:{permissionType:"role_action",sourceType:"role",sourceId:roleId}});if(permissions.length===0){return[]}const actionIds=permissions.map(p=>p.targetId);const actionWhere={id:In(actionIds)};const actions=await actionRepo.find({where:actionWhere});const actionMap=new Map(actions.map(a=>[a.id,a]));return permissions.filter(p=>actionMap.has(p.targetId)).map(p=>{const action=actionMap.get(p.targetId);return{id:p.id,roleId:p.sourceId,actionId:action.id,actionCode:action.code??"",actionName:action.name,createdAt:p.createdAt}})}async assignCompanyActions(dto){const permissionRepo=await this.getPermissionRepository();const dataSource=permissionRepo.manager.connection;const itemsToAdd=dto.items.filter(item=>item.action==="add");const itemsToRemove=dto.items.filter(item=>item.action==="remove");let added=0;let removed=0;let removedRoleActions=0;let removedUserActions=0;await dataSource.transaction(async manager=>{const transactionalPermissionRepo=manager.getRepository(permissionRepo.target);if(itemsToAdd.length>0){added=await this.addCompanyActions(transactionalPermissionRepo,dto.companyId,itemsToAdd.map(item=>item.id))}if(itemsToRemove.length>0){const actionIdsToRemove=itemsToRemove.map(item=>item.id);const cascadeResult=await this.removeCompanyActionsWithCascade(manager,dto.companyId,actionIdsToRemove);removed=cascadeResult.removedCompanyActions;removedRoleActions=cascadeResult.removedRoleActions;removedUserActions=cascadeResult.removedUserActions}});const affectedCacheEntries=await this.invalidateCompanyMembersCache(dto.companyId);const cascadeInfo=removedRoleActions>0||removedUserActions>0?` Cascaded removal: ${removedRoleActions} role permissions, ${removedUserActions} user permissions.`:"";return{success:true,added,removed,message:`Successfully processed ${dto.items.length} items: ${added} added, ${removed} removed.${cascadeInfo} Invalidated ${affectedCacheEntries} cache entries.`}}async addCompanyActions(permissionRepo,companyId,actionIds){const existingPermissions=await permissionRepo.find({where:{permissionType:"company_action",sourceType:"company",sourceId:companyId,targetType:"action",targetId:In(actionIds)},select:["targetId"]});const existingActionIds=new Set(existingPermissions.map(p=>p.targetId));const newActionIds=actionIds.filter(id=>!existingActionIds.has(id));if(newActionIds.length===0){return 0}const newPermissions=newActionIds.map(actionId=>permissionRepo.create({permissionType:"company_action",sourceType:"company",sourceId:companyId,targetType:"action",targetId:actionId,userId:null}));await permissionRepo.save(newPermissions);return newPermissions.length}async removeCompanyActionsWithCascade(manager,companyId,actionIds){const permissionEntity=this.iamConfigService.isCompanyFeatureEnabled()?UserIamPermissionWithCompany:UserIamPermission;const permissionRepo=manager.getRepository(permissionEntity);const companyResult=await permissionRepo.delete({permissionType:"company_action",sourceType:"company",sourceId:companyId,targetType:"action",targetId:In(actionIds)});const roleEntity=this.iamConfigService.isCompanyFeatureEnabled()?RoleWithCompany:Role;const roleRepo=manager.getRepository(roleEntity);const companyRoles=await roleRepo.find({where:{companyId,deletedAt:IsNull()},select:["id"]});let removedRoleActions=0;let removedUserActions=0;if(companyRoles.length>0){const roleIds=companyRoles.map(role=>role.id);const roleResult=await permissionRepo.delete({permissionType:"role_action",sourceType:"role",sourceId:In(roleIds),targetType:"action",targetId:In(actionIds)});removedRoleActions=roleResult.affected||0}if(this.iamConfigService.isCompanyFeatureEnabled()){const userResult=await permissionRepo.delete({permissionType:"user_action",companyId,targetType:"action",targetId:In(actionIds)});removedUserActions=userResult.affected||0}if(removedRoleActions>0||removedUserActions>0){this.logger.log(`Cascade deleted for company ${companyId}: ${removedRoleActions} role actions, ${removedUserActions} user actions`)}return{removedCompanyActions:companyResult.affected||0,removedRoleActions,removedUserActions}}async getCompanyActions(companyId){const permissionRepo=await this.getPermissionRepository();const actionRepo=await this.getActionRepository();const permissions=await permissionRepo.find({where:{permissionType:"company_action",sourceType:"company",sourceId:companyId}});if(permissions.length===0){return[]}const actionIds=permissions.map(p=>p.targetId);const actions=await actionRepo.find({where:{id:In(actionIds)}});const actionMap=new Map(actions.map(a=>[a.id,a]));return permissions.filter(p=>actionMap.has(p.targetId)).map(p=>{const action=actionMap.get(p.targetId);return{id:p.id,companyId,actionId:action.id,actionCode:action.code??"",actionName:action.name,createdAt:p.createdAt}})}async getCompanyActionIds(companyId){const permissionRepo=await this.getPermissionRepository();const permissions=await permissionRepo.find({where:{permissionType:"company_action",sourceType:"company",sourceId:companyId},select:["targetId"]});return permissions.map(p=>p.targetId)}async assignUserRoles(dto){const permissionRepo=await this.getPermissionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const branchId=dto.branchId??null;const companyId=dto.companyId??null;const itemsToAdd=dto.items.filter(item=>item.action==="add");const itemsToRemove=dto.items.filter(item=>item.action==="remove");let added=0;let removed=0;if(itemsToAdd.length>0){const roleIdsToAdd=itemsToAdd.map(item=>item.id);const whereFind={permissionType:"user_role",sourceType:"user",sourceId:dto.userId,targetType:"role",targetId:In(roleIdsToAdd)};if(enableCompanyFeature){if(companyId)whereFind.companyId=companyId;if(branchId)whereFind.branchId=branchId}const existingPermissions=await permissionRepo.find({where:whereFind,select:["targetId"]});const existingRoleIds=new Set(existingPermissions.map(p=>p.targetId));const newPermissions=itemsToAdd.filter(item=>!existingRoleIds.has(item.id)).map(item=>({permissionType:"user_role",sourceType:"user",sourceId:dto.userId,targetType:"role",targetId:item.id,userId:dto.userId,companyId:enableCompanyFeature?companyId:null,branchId:enableCompanyFeature?branchId:null}));if(newPermissions.length>0){await permissionRepo.save(newPermissions);added=newPermissions.length}}if(itemsToRemove.length>0){const roleIdsToRemove=itemsToRemove.map(item=>item.id);const whereDelete={permissionType:"user_role",sourceType:"user",sourceId:dto.userId,targetType:"role",targetId:In(roleIdsToRemove)};if(enableCompanyFeature){if(companyId)whereDelete.companyId=companyId;if(branchId)whereDelete.branchId=branchId}const result=await permissionRepo.delete(whereDelete);removed=result.affected||0}await this.invalidateUserPermissionCache(dto.userId,branchId,companyId);return{success:true,added,removed,message:`Successfully processed ${dto.items.length} items: ${added} added, ${removed} removed`}}async getUserRoles(userId,branchId,companyId){const permissionRepo=await this.getPermissionRepository();const roleRepo=await this.getRoleRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const where={permissionType:"user_role",sourceType:"user",sourceId:userId};if(enableCompanyFeature){if(companyId){where.companyId=companyId}if(branchId){where.branchId=branchId}else{where.branchId=null}}const permissions=await permissionRepo.find({where});if(permissions.length===0){return[]}const roleIds=permissions.map(p=>p.targetId);const roleWhere={id:In(roleIds)};const roles=await roleRepo.find({where:roleWhere});const roleMap=new Map(roles.map(r=>[r.id,r]));return permissions.filter(p=>roleMap.has(p.targetId)).map(p=>{const role=roleMap.get(p.targetId);const permissionEntity=p;return{id:p.id,userId:p.userId,roleId:role.id,roleName:role.name,branchId:enableCompanyFeature?permissionEntity.branchId??null:null,createdAt:p.createdAt}})}async getMyPermissions(userId,branchId,companyId,parentCodes){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const cacheOptions={userId,companyId,branchId,enableCompanyFeature};const cachedData=await this.permissionCacheService.getMyPermissions(cacheOptions);if(cachedData){return this.buildResponseFromCache(cachedData,parentCodes)}const freshData=await this.fetchAndCachePermissions(userId,branchId,companyId);return this.buildResponseFromCache(freshData,parentCodes)}async buildResponseFromCache(cachedData,parentCodes){let frontendActions=cachedData.frontendActions;if(parentCodes?.length){const parentIds=await this.getParentIdsByCodesWithCache(parentCodes);if(parentIds.size>0){frontendActions=frontendActions.filter(a=>a.parentId&&parentIds.has(a.parentId))}else{frontendActions=[]}}return{frontendActions:frontendActions.map(a=>({id:a.id,code:a.code,name:a.name,description:a.description})),cachedEndpoints:cachedData.backendCodes.length}}async getParentIdsByCodesWithCache(codes){const cachedMap=await this.permissionCacheService.getActionIdsByCodes(codes);if(cachedMap){return new Set(Object.values(cachedMap))}const actionRepo=await this.getActionRepository();const allActions=await actionRepo.find({select:["id","code"]});const fullMap={};for(const action of allActions){if(action.code){fullMap[action.code]=action.id}}await this.permissionCacheService.setActionCodeMap(fullMap);return new Set(codes.map(code=>fullMap[code]).filter(Boolean))}async fetchAndCachePermissions(userId,branchId,companyId){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const permissionMode=this.iamConfigService.getPermissionMode();const cacheOptions={userId,companyId,branchId,enableCompanyFeature};const emptyData={frontendActions:[],backendCodes:[]};const allActionIds=new Set;if(permissionMode===1||permissionMode===3){const userRoleIds=await this.getUserRoleIds(userId,branchId,companyId);if(userRoleIds.length>0){const roleActionIds=await this.getRoleActionIds(userRoleIds);roleActionIds.forEach(id=>allActionIds.add(id))}}if(permissionMode===2||permissionMode===3){const userActionIds=await this.getUserActionIds(userId,branchId,companyId);userActionIds.forEach(id=>allActionIds.add(id))}if(allActionIds.size===0){await this.permissionCacheService.setMyPermissions(cacheOptions,emptyData);return emptyData}if(enableCompanyFeature&&companyId){const companyActionIds=await this.getCompanyActionIds(companyId);if(companyActionIds.length>0){const allowedActionIds=new Set(companyActionIds);for(const actionId of allActionIds){if(!allowedActionIds.has(actionId)){allActionIds.delete(actionId)}}}}if(allActionIds.size===0){await this.permissionCacheService.setMyPermissions(cacheOptions,emptyData);return emptyData}const actionRepo=await this.getActionRepository();const actions=await actionRepo.find({where:{id:In(Array.from(allActionIds))}});const backendActions=actions.filter(a=>a.actionType==="backend"||a.actionType==="both");const frontendActions=actions.filter(a=>a.actionType==="frontend"||a.actionType==="both");const backendCodes=backendActions.map(a=>a.code).filter(c=>!!c);const cacheData={frontendActions:frontendActions.map(a=>({id:a.id,code:a.code??"",name:a.name,description:a.description,parentId:a.parentId})),backendCodes};await Promise.all([this.permissionCacheService.setMyPermissions(cacheOptions,cacheData),this.permissionCacheService.setPermissions(cacheOptions,backendCodes)]);return cacheData}async getUserRoleIds(userId,branchId,companyId){const permissionRepo=await this.getPermissionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();if(!enableCompanyFeature){const permissions=await permissionRepo.find({where:{permissionType:"user_role",sourceType:"user",sourceId:userId}});return permissions.map(p=>p.targetId)}const roleIds=new Set;const companyWidePermissions=await permissionRepo.find({where:{permissionType:"user_role",sourceType:"user",sourceId:userId,branchId:IsNull(),companyId}});companyWidePermissions.forEach(p=>roleIds.add(p.targetId));if(branchId){const branchPermissions=await permissionRepo.find({where:{permissionType:"user_role",sourceType:"user",sourceId:userId,branchId,companyId}});branchPermissions.forEach(p=>roleIds.add(p.targetId))}return Array.from(roleIds)}async getRoleActionIds(roleIds){const permissionRepo=await this.getPermissionRepository();const permissions=await permissionRepo.find({where:{permissionType:"role_action",sourceType:"role",sourceId:In(roleIds)}});return permissions.map(p=>p.targetId)}async getUserActionIds(userId,branchId,companyId){const permissionRepo=await this.getPermissionRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();if(!enableCompanyFeature){const permissions=await permissionRepo.find({where:{permissionType:"user_action",sourceType:"user",sourceId:userId}});return permissions.map(p=>p.targetId)}const actionIds=new Set;const companyWideWhere={permissionType:"user_action",sourceType:"user",sourceId:userId,branchId:IsNull()};if(companyId){companyWideWhere.companyId=companyId}const companyWidePermissions=await permissionRepo.find({where:companyWideWhere});companyWidePermissions.forEach(p=>actionIds.add(p.targetId));if(branchId){const branchWhere={permissionType:"user_action",sourceType:"user",sourceId:userId,branchId};if(companyId){branchWhere.companyId=companyId}const branchPermissions=await permissionRepo.find({where:branchWhere});branchPermissions.forEach(p=>actionIds.add(p.targetId))}return Array.from(actionIds)}async invalidateUserPermissionCache(userId,branchId,companyId){const branchIds=branchId!==void 0?[branchId]:[null];await this.permissionCacheService.invalidateUser(userId,companyId,branchIds)}async invalidateRoleMembersCache(roleId){const permissionRepo=await this.getPermissionRepository();const roleRepo=await this.getRoleRepository();const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();const userRoles=await permissionRepo.find({where:{permissionType:"user_role",sourceType:"user",targetType:"role",targetId:roleId}});const userIds=[...new Set(userRoles.map(ur=>ur.sourceId))];if(userIds.length===0){return 0}const role=await roleRepo.findOne({where:{id:roleId}});const companyId=role?.companyId||null;let branchIds=[null];if(enableCompanyFeature&&companyId){const userBranches=await permissionRepo.createQueryBuilder("p").select("DISTINCT p.branch_id","branchId").where("p.user_id IN (:...userIds)",{userIds}).andWhere("p.company_id = :companyId",{companyId}).getRawMany();branchIds=[...new Set(userBranches.map(p=>p.branchId))]}return await this.permissionCacheService.invalidateRole(roleId,userIds,companyId,branchIds)}async invalidateCompanyMembersCache(companyId){if(!this.iamConfigService.isCompanyFeatureEnabled()){return 0}const permissionRepo=await this.getPermissionRepository();const userPermissions=await permissionRepo.createQueryBuilder("p").select("DISTINCT p.user_id","userId").addSelect("p.branch_id","branchId").where("p.company_id = :companyId",{companyId}).andWhere("p.user_id IS NOT NULL").getRawMany();const userIds=[...new Set(userPermissions.map(p=>p.userId).filter(Boolean))];const branchIds=[...new Set(userPermissions.map(p=>p.branchId))];if(userIds.length===0){return 0}return await this.permissionCacheService.invalidateUsers(userIds,companyId,branchIds)}};__name(PermissionService,"PermissionService");PermissionService=__decorateClass([Injectable5({scope:Scope2.REQUEST}),__decorateParam(0,Inject4(PermissionEvaluatorHelper)),__decorateParam(1,Inject4(PermissionCacheService)),__decorateParam(2,Inject4(IAMConfigService)),__decorateParam(3,Inject4(IAMDataSourceProvider))],PermissionService);var ActionService=class extends RequestScopedApiService{constructor(cacheManager,utilsService,iamConfigService,dataSourceProvider,permissionService){super("action",null,cacheManager,utilsService,ActionService.name,true);this.cacheManager=cacheManager;this.utilsService=utilsService;this.iamConfigService=iamConfigService;this.dataSourceProvider=dataSourceProvider;this.permissionService=permissionService}logger=new Logger4(ActionService.name);resolveEntity(){return Action}getDataSourceProvider(){return this.dataSourceProvider}async convertSingleDtoToEntity(dto,_user){if(!("id"in dto)||!dto.id){return dto}const existingAction=await this.repository.findOne({where:{id:dto.id}});if(!existingAction){throw new NotFoundException(`Action with ID ${dto.id} not found`)}return{...existingAction,...dto}}async getSelectQuery(query,_user,select){if(!select||!select.length){select=["id","name","code","description","actionType","permissionLogic","isActive","parentId","serial","createdAt"]}const selectFields=select.map(field=>`${this.entityName}.${field}`);query.select(selectFields);return{query,isRaw:false}}async getGlobalSearchQuery(query,search,_user){query.andWhere("(action.name LIKE :search OR action.code LIKE :search OR action.description LIKE :search)",{search:`%${search}%`});return{query,isRaw:false}}convertEntityToResponseDto(entity,_isRaw){return{id:entity.id,readOnly:entity.readOnly,name:entity.name,description:entity.description,code:entity.code,actionType:entity.actionType,permissionLogic:entity.permissionLogic,serial:entity.serial,isActive:entity.isActive,parentId:entity.parentId,metadata:entity.metadata,createdAt:entity.createdAt,updatedAt:entity.updatedAt,deletedAt:entity.deletedAt,createdById:entity.createdById,updatedById:entity.updatedById,deletedById:entity.deletedById}}async getActionsForPermission(user){await this.ensureRepositoryInitialized();if(!user){throw new Error("User is required for getActionsForPermission")}const selectFields=["id","code","name","description","actionType","permissionLogic","isActive","parentId","serial"];const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();if(enableCompanyFeature&&user.companyId){const companyActionIds=await this.permissionService.getCompanyActionIds(user.companyId);if(companyActionIds.length===0){return[]}const actions2=await this.repository.find({where:{id:In2(companyActionIds)},select:selectFields});return actions2.map(action=>this.convertEntityToResponseDto(action,false))}const actions=await this.repository.find({select:selectFields});return actions.map(action=>this.convertEntityToResponseDto(action,false))}async getActionTree(user,search,isActive,withDeleted=false){await this.ensureRepositoryInitialized();if(!user){throw new Error("User is required for getActionTree")}const query=this.repository.createQueryBuilder("action");if(!withDeleted){query.andWhere("action.deletedAt IS NULL")}if(isActive!==void 0){query.andWhere("action.isActive = :isActive",{isActive})}if(search?.trim()){query.andWhere("(action.name LIKE :search OR action.code LIKE :search)",{search:`%${search.trim()}%`})}const actions=await query.orderBy("action.serial","ASC").getMany();return this.buildActionTree(actions)}buildActionTree(actions){if(!actions?.length){return[]}const map=new Map;const rootNodes=[];for(const action of actions){const treeNode={...this.convertEntityToResponseDto(action,false),children:[]};map.set(action.id,treeNode)}for(const action of actions){const node=map.get(action.id);if(!node){continue}if(action.parentId&&map.has(action.parentId)){const parent=map.get(action.parentId);if(parent?.children){parent.children.push(node)}}else{rootNodes.push(node)}}return rootNodes}};__name(ActionService,"ActionService");ActionService=__decorateClass([Injectable6({scope:Scope3.REQUEST}),__decorateParam(0,Inject5("CACHE_INSTANCE")),__decorateParam(1,Inject5(UtilsService)),__decorateParam(2,Inject5(IAMConfigService)),__decorateParam(3,Inject5(IAMDataSourceProvider)),__decorateParam(4,Inject5(PermissionService))],ActionService);init_role_with_company_entity();init_role_entity();import{RequestScopedApiService as RequestScopedApiService2}from"@flusys/nestjs-shared/classes";import{UtilsService as UtilsService2}from"@flusys/nestjs-shared/modules";import{Inject as Inject6,Injectable as Injectable7,Logger as Logger5,NotFoundException as NotFoundException2,Scope as Scope4}from"@nestjs/common";var RoleService=class extends RequestScopedApiService2{constructor(cacheManager,utilsService,iamConfigService,dataSourceProvider){super("role",null,cacheManager,utilsService,RoleService.name,true);this.cacheManager=cacheManager;this.utilsService=utilsService;this.iamConfigService=iamConfigService;this.dataSourceProvider=dataSourceProvider}logger=new Logger5(RoleService.name);resolveEntity(){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();return enableCompanyFeature?RoleWithCompany:Role}getDataSourceProvider(){return this.dataSourceProvider}async convertSingleDtoToEntity(dto,user){const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();let role={};let isUpdate=false;if("id"in dto&&dto.id&&typeof dto.id==="string"){const dbData=await this.repository.findOne({where:{id:dto.id}});if(!dbData){throw new NotFoundException2("Role not found")}role=dbData;isUpdate=true}role={...role,...dto};if(enableCompanyFeature){if(isUpdate){if(dto.companyId!==void 0){role.companyId=dto.companyId}if(!("companyId"in role)||role.companyId===void 0){role.companyId=user?.companyId??null}}else{role.companyId=dto.companyId??user?.companyId??null}}return role}async getSelectQuery(query,_user,select){if(!select||!select.length){select=["id","name","description","isActive","companyId","serial","createdAt"]}const selectFields=select.map(field=>`${this.entityName}.${field}`);query.select(selectFields);return{query,isRaw:false}}async getGlobalSearchQuery(query,search,_user){query.andWhere("(role.name LIKE :search OR role.description LIKE :search)",{search:`%${search}%`});return{query,isRaw:false}}async getExtraManipulateQuery(query,filterDto,user){const result=await super.getExtraManipulateQuery(query,filterDto,user);const enableCompanyFeature=this.iamConfigService.isCompanyFeatureEnabled();if(enableCompanyFeature&&user?.companyId){query.andWhere("role.companyId = :companyId",{companyId:user.companyId})}return result}convertEntityToResponseDto(entity,_isRaw){return{id:entity.id,readOnly:entity.readOnly,name:entity.name,description:entity.description,isActive:entity.isActive,serial:entity.serial,companyId:("companyId"in entity?entity.companyId:null)??null,metadata:entity.metadata,createdAt:entity.createdAt,updatedAt:entity.updatedAt,deletedAt:entity.deletedAt,createdById:entity.createdById,updatedById:entity.updatedById,deletedById:entity.deletedById}}};__name(RoleService,"RoleService");RoleService=__decorateClass([Injectable7({scope:Scope4.REQUEST}),__decorateParam(0,Inject6("CACHE_INSTANCE")),__decorateParam(1,Inject6(UtilsService2)),__decorateParam(2,Inject6(IAMConfigService)),__decorateParam(3,Inject6(IAMDataSourceProvider))],RoleService);export{ActionService,IAMConfigService,IAMDataSourceProvider,PermissionCacheService,PermissionService,RoleService};
|
package/fesm/types-index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var LogicOperator=(LogicOperator2=>{LogicOperator2["AND"]="AND";LogicOperator2["OR"]="OR";return LogicOperator2})(LogicOperator||{});var LogicNodeType=(LogicNodeType2=>{LogicNodeType2["GROUP"]="group";LogicNodeType2["ACTION"]="action";return LogicNodeType2})(LogicNodeType||{});export{LogicNodeType,LogicOperator};
|