@flusys/nestjs-iam 0.1.0-alpha.1

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.
Files changed (72) hide show
  1. package/cjs/config-index.js +1 -0
  2. package/cjs/controllers-index.js +1 -0
  3. package/cjs/docs-index.js +79 -0
  4. package/cjs/dtos-index.js +1 -0
  5. package/cjs/entities-index.js +1 -0
  6. package/cjs/enums-index.js +1 -0
  7. package/cjs/helpers-index.js +1 -0
  8. package/cjs/index.js +79 -0
  9. package/cjs/interfaces-index.js +1 -0
  10. package/cjs/modules-index.js +1 -0
  11. package/cjs/services-index.js +1 -0
  12. package/cjs/types-index.js +1 -0
  13. package/config/iam.constants.d.ts +1 -0
  14. package/config/index.d.ts +1 -0
  15. package/controllers/action.controller.d.ts +20 -0
  16. package/controllers/company-action-permission.controller.d.ts +9 -0
  17. package/controllers/index.d.ts +6 -0
  18. package/controllers/my-permission.controller.d.ts +8 -0
  19. package/controllers/role-permission.controller.d.ts +11 -0
  20. package/controllers/role.controller.d.ts +17 -0
  21. package/controllers/user-action-permission.controller.d.ts +9 -0
  22. package/docs/iam-swagger.config.d.ts +3 -0
  23. package/docs/index.d.ts +1 -0
  24. package/dtos/action.dto.d.ts +52 -0
  25. package/dtos/index.d.ts +3 -0
  26. package/dtos/permission.dto.d.ts +92 -0
  27. package/dtos/role.dto.d.ts +36 -0
  28. package/entities/action-base.entity.d.ts +17 -0
  29. package/entities/action.entity.d.ts +3 -0
  30. package/entities/index.d.ts +16 -0
  31. package/entities/permission-base.entity.d.ts +30 -0
  32. package/entities/permission-with-company.entity.d.ts +5 -0
  33. package/entities/role-base.entity.d.ts +9 -0
  34. package/entities/role-with-company.entity.d.ts +4 -0
  35. package/entities/role.entity.d.ts +3 -0
  36. package/entities/user-iam-permission.entity.d.ts +4 -0
  37. package/enums/action-type.enum.d.ts +5 -0
  38. package/enums/index.d.ts +2 -0
  39. package/enums/permission-type.enum.d.ts +5 -0
  40. package/fesm/config-index.js +1 -0
  41. package/fesm/controllers-index.js +1 -0
  42. package/fesm/docs-index.js +79 -0
  43. package/fesm/dtos-index.js +1 -0
  44. package/fesm/entities-index.js +1 -0
  45. package/fesm/enums-index.js +1 -0
  46. package/fesm/helpers-index.js +1 -0
  47. package/fesm/index.js +79 -0
  48. package/fesm/interfaces-index.js +0 -0
  49. package/fesm/modules-index.js +1 -0
  50. package/fesm/services-index.js +1 -0
  51. package/fesm/types-index.js +1 -0
  52. package/helpers/index.d.ts +2 -0
  53. package/helpers/permission-evaluator.helper.d.ts +26 -0
  54. package/helpers/permission-mode.helper.d.ts +5 -0
  55. package/index.d.ts +11 -0
  56. package/interfaces/action.interface.d.ts +24 -0
  57. package/interfaces/iam-module-async-options.interface.d.ts +11 -0
  58. package/interfaces/iam-module-options.interface.d.ts +12 -0
  59. package/interfaces/index.d.ts +4 -0
  60. package/interfaces/role.interface.d.ts +16 -0
  61. package/modules/iam.module.d.ts +13 -0
  62. package/modules/index.d.ts +1 -0
  63. package/package.json +95 -0
  64. package/services/action.service.d.ts +35 -0
  65. package/services/iam-config.service.d.ts +15 -0
  66. package/services/iam-datasource.provider.d.ts +25 -0
  67. package/services/index.d.ts +6 -0
  68. package/services/permission-cache.service.d.ts +41 -0
  69. package/services/permission.service.d.ts +37 -0
  70. package/services/role.service.d.ts +35 -0
  71. package/types/index.d.ts +1 -0
  72. package/types/logic-node.type.d.ts +15 -0
@@ -0,0 +1,35 @@
1
+ import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
+ import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
3
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
4
+ import { Logger } from '@nestjs/common';
5
+ import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
6
+ import { CreateActionDto, UpdateActionDto } from '../dtos/action.dto';
7
+ import { ActionBase } from '../entities/action-base.entity';
8
+ import { IAction, IActionTree } from '../interfaces/action.interface';
9
+ import { IAMConfigService } from './iam-config.service';
10
+ import { IAMDataSourceProvider } from './iam-datasource.provider';
11
+ import { PermissionService } from './permission.service';
12
+ export declare class ActionService extends RequestScopedApiService<CreateActionDto, UpdateActionDto, IAction, ActionBase, Repository<ActionBase>> {
13
+ protected cacheManager: HybridCache;
14
+ protected utilsService: UtilsService;
15
+ private readonly iamConfigService;
16
+ private readonly dataSourceProvider;
17
+ private readonly permissionService;
18
+ protected logger: Logger;
19
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, iamConfigService: IAMConfigService, dataSourceProvider: IAMDataSourceProvider, permissionService: PermissionService);
20
+ protected resolveEntity(): EntityTarget<ActionBase>;
21
+ protected getDataSourceProvider(): IAMDataSourceProvider;
22
+ convertSingleDtoToEntity(dto: CreateActionDto | UpdateActionDto, _user: ILoggedUserInfo): Promise<ActionBase>;
23
+ getSelectQuery(query: SelectQueryBuilder<ActionBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
24
+ query: SelectQueryBuilder<ActionBase>;
25
+ isRaw: boolean;
26
+ }>;
27
+ protected getGlobalSearchQuery(query: SelectQueryBuilder<ActionBase>, search: string, _user: ILoggedUserInfo | null): Promise<{
28
+ query: SelectQueryBuilder<ActionBase>;
29
+ isRaw: boolean;
30
+ }>;
31
+ protected convertEntityToResponseDto(entity: ActionBase, _isRaw: boolean): IAction;
32
+ getActionsForPermission(user: ILoggedUserInfo): Promise<IAction[]>;
33
+ getActionTree(user: ILoggedUserInfo, search?: string, isActive?: boolean, withDeleted?: boolean): Promise<IActionTree[]>;
34
+ private buildActionTree;
35
+ }
@@ -0,0 +1,15 @@
1
+ import { DatabaseMode } from '@flusys/nestjs-core';
2
+ import { IAMPermissionMode } from '../enums/permission-type.enum';
3
+ import { IAMModuleOptions } from '../interfaces/iam-module-options.interface';
4
+ export declare class IAMConfigService {
5
+ private readonly options;
6
+ constructor(injectedOptions?: IAMModuleOptions);
7
+ getDatabaseMode(): DatabaseMode;
8
+ isMultiTenant(): boolean;
9
+ getEnableCompanyFeature(): boolean;
10
+ isCompanyFeatureEnabled(): boolean;
11
+ getPermissionMode(): IAMPermissionMode;
12
+ isRbacEnabled(): boolean;
13
+ isDirectPermissionEnabled(): boolean;
14
+ getOptions(): IAMModuleOptions;
15
+ }
@@ -0,0 +1,25 @@
1
+ import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
2
+ import { IDatabaseConfig, ITenantDatabaseConfig } from '@flusys/nestjs-core';
3
+ import { Logger } from '@nestjs/common';
4
+ import { Request } from 'express';
5
+ import { DataSource } from 'typeorm';
6
+ import { IAMModuleOptions } from '../interfaces/iam-module-options.interface';
7
+ export declare class IAMDataSourceProvider extends MultiTenantDataSourceService {
8
+ private readonly iamOptions;
9
+ protected readonly logger: Logger;
10
+ protected static readonly tenantConnections: Map<string, DataSource>;
11
+ protected static singleDataSource: DataSource | null;
12
+ protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
13
+ protected static initialized: boolean;
14
+ protected static readonly connectionLocks: Map<string, Promise<DataSource>>;
15
+ protected static singleConnectionLock: Promise<DataSource> | null;
16
+ constructor(iamOptions: IAMModuleOptions, request?: Request);
17
+ private static buildParentOptions;
18
+ getEnableCompanyFeature(): boolean;
19
+ getEnableCompanyFeatureForTenant(tenant?: ITenantDatabaseConfig): boolean;
20
+ getEnableCompanyFeatureForCurrentTenant(): boolean;
21
+ getIAMEntities(): Promise<any[]>;
22
+ protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
23
+ protected getSingleDataSource(): Promise<DataSource>;
24
+ protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
25
+ }
@@ -0,0 +1,6 @@
1
+ export * from './action.service';
2
+ export * from './iam-config.service';
3
+ export * from './iam-datasource.provider';
4
+ export * from './permission-cache.service';
5
+ export * from './permission.service';
6
+ export * from './role.service';
@@ -0,0 +1,41 @@
1
+ import { HybridCache } from '@flusys/nestjs-shared';
2
+ export interface PermissionCacheKeyOptions {
3
+ userId: string;
4
+ companyId?: string | null;
5
+ branchId?: string | null;
6
+ enableCompanyFeature: boolean;
7
+ }
8
+ export interface CachedMyPermissions {
9
+ frontendActions: Array<{
10
+ id: string;
11
+ code: string;
12
+ name: string;
13
+ description: string | null;
14
+ parentId: string | null;
15
+ }>;
16
+ backendCodes: string[];
17
+ }
18
+ export declare class PermissionCacheService {
19
+ private readonly cacheManager;
20
+ private readonly logger;
21
+ private readonly TTL;
22
+ private readonly ACTION_CODE_TTL;
23
+ private readonly CACHE_PREFIX;
24
+ private readonly MY_PERMISSIONS_PREFIX;
25
+ private readonly ACTION_CODE_PREFIX;
26
+ constructor(cacheManager: HybridCache);
27
+ generateCacheKey(options: PermissionCacheKeyOptions): string;
28
+ generateMyPermissionsCacheKey(options: PermissionCacheKeyOptions): string;
29
+ setPermissions(options: PermissionCacheKeyOptions, permissions: string[]): Promise<void>;
30
+ getPermissions(options: PermissionCacheKeyOptions): Promise<string[] | null>;
31
+ setMyPermissions(options: PermissionCacheKeyOptions, data: CachedMyPermissions): Promise<void>;
32
+ getMyPermissions(options: PermissionCacheKeyOptions): Promise<CachedMyPermissions | null>;
33
+ setActionCodeMap(codeToIdMap: Record<string, string>): Promise<void>;
34
+ getActionIdsByCodes(codes: string[]): Promise<Record<string, string> | null>;
35
+ invalidateActionCodeCache(): Promise<void>;
36
+ invalidateUser(userId: string, companyId?: string | null, branchIds?: (string | null)[]): Promise<void>;
37
+ invalidateUsers(userIds: string[], companyId?: string | null, branchIds?: (string | null)[]): Promise<number>;
38
+ invalidateCompany(companyId: string): Promise<number>;
39
+ invalidateRole(roleId: string, userIds: string[], companyId?: string | null, branchIds?: (string | null)[]): Promise<number>;
40
+ clearAll(): Promise<void>;
41
+ }
@@ -0,0 +1,37 @@
1
+ import { AssignCompanyActionsDto, AssignRoleActionsDto, AssignUserActionsDto, AssignUserRolesDto, CompanyActionResponseDto, MyPermissionsResponseDto, PermissionOperationResultDto, RoleActionResponseDto, UserActionResponseDto, UserRoleResponseDto } from '../dtos/permission.dto';
2
+ import { PermissionEvaluatorHelper } from '../helpers/permission-evaluator.helper';
3
+ import { IAMConfigService } from './iam-config.service';
4
+ import { IAMDataSourceProvider } from './iam-datasource.provider';
5
+ import { PermissionCacheService } from './permission-cache.service';
6
+ export declare class PermissionService {
7
+ private readonly permissionEvaluator;
8
+ private readonly permissionCacheService;
9
+ private readonly iamConfigService;
10
+ private readonly dataSourceProvider;
11
+ private readonly logger;
12
+ constructor(permissionEvaluator: PermissionEvaluatorHelper, permissionCacheService: PermissionCacheService, iamConfigService: IAMConfigService, dataSourceProvider: IAMDataSourceProvider);
13
+ private getPermissionRepository;
14
+ private getActionRepository;
15
+ private getRoleRepository;
16
+ assignUserActions(dto: AssignUserActionsDto): Promise<PermissionOperationResultDto>;
17
+ getUserActions(userId: string, branchId: string | undefined, companyId?: string | undefined): Promise<UserActionResponseDto[]>;
18
+ assignRoleActions(dto: AssignRoleActionsDto): Promise<PermissionOperationResultDto>;
19
+ getRoleActions(roleId: string): Promise<RoleActionResponseDto[]>;
20
+ assignCompanyActions(dto: AssignCompanyActionsDto): Promise<PermissionOperationResultDto>;
21
+ private addCompanyActions;
22
+ private removeCompanyActionsWithCascade;
23
+ getCompanyActions(companyId: string): Promise<CompanyActionResponseDto[]>;
24
+ getCompanyActionIds(companyId: string): Promise<string[]>;
25
+ assignUserRoles(dto: AssignUserRolesDto): Promise<PermissionOperationResultDto>;
26
+ getUserRoles(userId: string, branchId?: string | undefined, companyId?: string | undefined): Promise<UserRoleResponseDto[]>;
27
+ getMyPermissions(userId: string, branchId: string | null, companyId?: string | null, parentCodes?: string[]): Promise<MyPermissionsResponseDto>;
28
+ private buildResponseFromCache;
29
+ private getParentIdsByCodesWithCache;
30
+ private fetchAndCachePermissions;
31
+ private getUserRoleIds;
32
+ private getRoleActionIds;
33
+ private getUserActionIds;
34
+ private invalidateUserPermissionCache;
35
+ private invalidateRoleMembersCache;
36
+ private invalidateCompanyMembersCache;
37
+ }
@@ -0,0 +1,35 @@
1
+ import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
+ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
+ import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
5
+ import { Logger } from '@nestjs/common';
6
+ import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
7
+ import { CreateRoleDto, UpdateRoleDto } from '../dtos/role.dto';
8
+ import { RoleBase } from '../entities/role-base.entity';
9
+ import { IRole } from '../interfaces/role.interface';
10
+ import { IAMConfigService } from './iam-config.service';
11
+ import { IAMDataSourceProvider } from './iam-datasource.provider';
12
+ export declare class RoleService extends RequestScopedApiService<CreateRoleDto, UpdateRoleDto, IRole, RoleBase, Repository<RoleBase>> {
13
+ protected cacheManager: HybridCache;
14
+ protected utilsService: UtilsService;
15
+ private readonly iamConfigService;
16
+ private readonly dataSourceProvider;
17
+ protected logger: Logger;
18
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, iamConfigService: IAMConfigService, dataSourceProvider: IAMDataSourceProvider);
19
+ protected resolveEntity(): EntityTarget<RoleBase>;
20
+ protected getDataSourceProvider(): IAMDataSourceProvider;
21
+ convertSingleDtoToEntity(dto: CreateRoleDto | UpdateRoleDto, user: ILoggedUserInfo | null): Promise<RoleBase>;
22
+ getSelectQuery(query: SelectQueryBuilder<RoleBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
23
+ query: SelectQueryBuilder<RoleBase>;
24
+ isRaw: boolean;
25
+ }>;
26
+ protected getGlobalSearchQuery(query: SelectQueryBuilder<RoleBase>, search: string, _user: ILoggedUserInfo | null): Promise<{
27
+ query: SelectQueryBuilder<RoleBase>;
28
+ isRaw: boolean;
29
+ }>;
30
+ protected getExtraManipulateQuery(query: SelectQueryBuilder<RoleBase>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
31
+ query: SelectQueryBuilder<RoleBase>;
32
+ isRaw: boolean;
33
+ }>;
34
+ protected convertEntityToResponseDto(entity: RoleBase, _isRaw: boolean): IRole;
35
+ }
@@ -0,0 +1 @@
1
+ export * from './logic-node.type';
@@ -0,0 +1,15 @@
1
+ export interface LogicNode {
2
+ id: string;
3
+ type: 'group' | 'action';
4
+ operator?: 'AND' | 'OR';
5
+ actionId?: string;
6
+ children?: LogicNode[];
7
+ }
8
+ export declare enum LogicOperator {
9
+ AND = "AND",
10
+ OR = "OR"
11
+ }
12
+ export declare enum LogicNodeType {
13
+ GROUP = "group",
14
+ ACTION = "action"
15
+ }