@flusys/nestjs-shared 1.0.0-beta → 1.0.0-rc

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 (90) hide show
  1. package/README.md +56 -110
  2. package/cjs/classes/api-controller.class.js +9 -24
  3. package/cjs/classes/index.js +1 -0
  4. package/cjs/constants/index.js +14 -0
  5. package/cjs/constants/permissions.js +174 -0
  6. package/cjs/decorators/api-response.decorator.js +1 -1
  7. package/cjs/decorators/index.js +1 -0
  8. package/cjs/decorators/sanitize-html.decorator.js +36 -0
  9. package/cjs/dtos/filter-and-pagination.dto.js +24 -34
  10. package/cjs/dtos/pagination.dto.js +4 -8
  11. package/cjs/dtos/response-payload.dto.js +0 -41
  12. package/cjs/entities/identity.js +4 -4
  13. package/cjs/entities/user-root.js +13 -14
  14. package/cjs/guards/permission.guard.js +39 -94
  15. package/cjs/interceptors/index.js +1 -0
  16. package/cjs/interceptors/set-create-by-on-body.interceptor.js +2 -30
  17. package/cjs/interceptors/set-delete-by-on-body.interceptor.js +2 -30
  18. package/cjs/interceptors/set-update-by-on-body.interceptor.js +2 -30
  19. package/cjs/interceptors/set-user-field-on-body.interceptor.js +43 -0
  20. package/cjs/interceptors/slug.interceptor.js +30 -9
  21. package/cjs/interfaces/datasource.interface.js +4 -0
  22. package/cjs/interfaces/index.js +2 -1
  23. package/cjs/interfaces/module-config.interface.js +4 -0
  24. package/cjs/modules/cache/cache.module.js +3 -3
  25. package/cjs/modules/datasource/multi-tenant-datasource.service.js +30 -110
  26. package/cjs/modules/utils/utils.service.js +63 -145
  27. package/cjs/utils/error-handler.util.js +91 -13
  28. package/cjs/utils/html-sanitizer.util.js +74 -0
  29. package/cjs/utils/index.js +2 -0
  30. package/cjs/utils/query-helpers.util.js +53 -0
  31. package/classes/api-controller.class.d.ts +5 -5
  32. package/classes/api-service.class.d.ts +5 -5
  33. package/classes/index.d.ts +1 -0
  34. package/classes/request-scoped-api.service.d.ts +3 -2
  35. package/constants/index.d.ts +1 -0
  36. package/constants/permissions.d.ts +167 -0
  37. package/decorators/index.d.ts +1 -0
  38. package/decorators/sanitize-html.decorator.d.ts +2 -0
  39. package/dtos/filter-and-pagination.dto.d.ts +0 -2
  40. package/dtos/response-payload.dto.d.ts +0 -7
  41. package/fesm/classes/api-controller.class.js +9 -24
  42. package/fesm/classes/index.js +2 -0
  43. package/fesm/constants/index.js +2 -0
  44. package/fesm/constants/permissions.js +121 -0
  45. package/fesm/decorators/api-response.decorator.js +1 -1
  46. package/fesm/decorators/index.js +1 -0
  47. package/fesm/decorators/sanitize-html.decorator.js +45 -0
  48. package/fesm/dtos/filter-and-pagination.dto.js +26 -47
  49. package/fesm/dtos/pagination.dto.js +4 -8
  50. package/fesm/dtos/response-payload.dto.js +0 -38
  51. package/fesm/entities/identity.js +4 -4
  52. package/fesm/entities/user-root.js +13 -14
  53. package/fesm/guards/permission.guard.js +39 -94
  54. package/fesm/interceptors/index.js +1 -0
  55. package/fesm/interceptors/set-create-by-on-body.interceptor.js +4 -30
  56. package/fesm/interceptors/set-delete-by-on-body.interceptor.js +4 -30
  57. package/fesm/interceptors/set-update-by-on-body.interceptor.js +4 -30
  58. package/fesm/interceptors/set-user-field-on-body.interceptor.js +36 -0
  59. package/fesm/interceptors/slug.interceptor.js +31 -10
  60. package/fesm/interfaces/datasource.interface.js +20 -0
  61. package/fesm/interfaces/index.js +2 -1
  62. package/fesm/interfaces/module-config.interface.js +5 -0
  63. package/fesm/modules/cache/cache.module.js +2 -2
  64. package/fesm/modules/datasource/multi-tenant-datasource.service.js +30 -110
  65. package/fesm/modules/utils/utils.service.js +50 -143
  66. package/fesm/utils/error-handler.util.js +93 -14
  67. package/fesm/utils/html-sanitizer.util.js +82 -0
  68. package/fesm/utils/index.js +2 -0
  69. package/fesm/utils/query-helpers.util.js +78 -0
  70. package/interceptors/index.d.ts +1 -0
  71. package/interceptors/set-create-by-on-body.interceptor.d.ts +1 -5
  72. package/interceptors/set-delete-by-on-body.interceptor.d.ts +1 -5
  73. package/interceptors/set-update-by-on-body.interceptor.d.ts +1 -5
  74. package/interceptors/set-user-field-on-body.interceptor.d.ts +2 -0
  75. package/interceptors/slug.interceptor.d.ts +2 -1
  76. package/interfaces/api.interface.d.ts +2 -2
  77. package/interfaces/datasource.interface.d.ts +5 -0
  78. package/interfaces/identity.interface.d.ts +4 -4
  79. package/interfaces/index.d.ts +2 -1
  80. package/interfaces/module-config.interface.d.ts +6 -0
  81. package/interfaces/permission.interface.d.ts +0 -1
  82. package/modules/utils/utils.service.d.ts +10 -4
  83. package/package.json +4 -4
  84. package/utils/error-handler.util.d.ts +23 -13
  85. package/utils/html-sanitizer.util.d.ts +3 -0
  86. package/utils/index.d.ts +2 -0
  87. package/utils/query-helpers.util.d.ts +16 -0
  88. package/cjs/interfaces/base-query.interface.js +0 -6
  89. package/fesm/interfaces/base-query.interface.js +0 -3
  90. package/interfaces/base-query.interface.d.ts +0 -7
package/README.md CHANGED
@@ -121,7 +121,6 @@ nestjs-shared/
121
121
  │ │
122
122
  │ ├── interfaces/ # TypeScript interfaces
123
123
  │ │ ├── api.interface.ts
124
- │ │ ├── base-query.interface.ts
125
124
  │ │ ├── identity.interface.ts
126
125
  │ │ ├── logged-user-info.interface.ts
127
126
  │ │ ├── logger.interface.ts
@@ -298,7 +297,7 @@ override async getExtraManipulateQuery(
298
297
 
299
298
  ## ApiController - Generic CRUD Controller
300
299
 
301
- The `createApiController` factory creates standardized REST API controllers.
300
+ The `createApiController` factory creates standardized POST-only RPC controllers.
302
301
 
303
302
  ### Basic Usage
304
303
 
@@ -516,100 +515,56 @@ The shared package provides two guards for authentication and authorization:
516
515
 
517
516
  ### JwtAuthGuard
518
517
 
519
- **Location:** `@flusys/nestjs-shared/guards/jwt-auth.guard.ts`
520
-
521
- The `JwtAuthGuard` validates JWT tokens for protected routes. It extends Passport's `AuthGuard('jwt')` and respects the `@Public()` decorator.
522
-
523
- **Why in shared module:**
524
- - All feature modules (auth, iam, storage) need JWT authentication
525
- - Keeps feature modules independent (no cross-dependencies)
526
- - JwtStrategy registration remains in auth module
527
- - This guard just validates tokens using the registered strategy
528
-
529
- **Usage:**
518
+ Validates JWT tokens for protected routes. Extends Passport's `AuthGuard('jwt')` and respects `@Public()` decorator.
530
519
 
531
520
  ```typescript
532
521
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
533
- import { UseGuards } from '@nestjs/common';
534
522
 
535
- // Protect entire controller
523
+ // Apply globally
524
+ @Module({
525
+ providers: [{ provide: APP_GUARD, useClass: JwtAuthGuard }],
526
+ })
527
+ export class AppModule {}
528
+
529
+ // Or per controller
536
530
  @Controller('users')
537
531
  @UseGuards(JwtAuthGuard)
538
532
  export class UserController {
539
- // All routes protected
540
-
541
533
  @Post('login')
542
- @Public() // Skip JWT check for this route
534
+ @Public() // Skip JWT check
543
535
  async login() { }
544
536
  }
545
-
546
- // Or apply globally
547
- @Module({
548
- providers: [
549
- {
550
- provide: APP_GUARD,
551
- useClass: JwtAuthGuard,
552
- },
553
- ],
554
- })
555
- export class AppModule {}
556
537
  ```
557
538
 
558
- **Features:**
559
- - Validates JWT tokens from `Authorization: Bearer <token>` header
560
- - Respects `@Public()` decorator to skip authentication
561
- - Throws `UnauthorizedException` for invalid/expired tokens
562
- - Works with JwtStrategy registered in auth module
563
-
564
- **Note:** The JwtStrategy (which registers the JWT validation logic with Passport) is still in the auth module at `@flusys/nestjs-auth/strategies/jwt.strategy.ts`. This guard uses that registered strategy.
565
-
566
539
  ### PermissionGuard
567
540
 
568
- **Location:** `@flusys/nestjs-shared/guards/permission.guard.ts`
569
-
570
- The `PermissionGuard` handles permission-based access control.
541
+ Checks user permissions from cache with AND/OR/nested logic support.
571
542
 
572
543
  ```typescript
573
- import { Module } from '@nestjs/common';
574
- import { APP_GUARD } from '@nestjs/core';
575
544
  import { PermissionGuard } from '@flusys/nestjs-shared/guards';
576
545
 
546
+ // Apply globally
577
547
  @Module({
578
- providers: [
579
- {
580
- provide: APP_GUARD,
581
- useClass: PermissionGuard,
582
- },
583
- ],
548
+ providers: [{ provide: APP_GUARD, useClass: PermissionGuard }],
584
549
  })
585
550
  export class AppModule {}
586
551
  ```
587
552
 
588
- ### Permission Cache Key Format
553
+ **Cache Key Formats:**
589
554
 
590
555
  ```typescript
591
556
  // Without company feature
592
557
  `permissions:user:{userId}`
593
558
 
594
- // With company feature (includes branchId for DIRECT permissions)
559
+ // With company feature
595
560
  `permissions:company:{companyId}:branch:{branchId}:user:{userId}`
596
561
  ```
597
562
 
598
- ### Permission Guard Configuration
599
-
600
- ```typescript
601
- // Configure via PermissionModule options
602
- PermissionModule.forRoot({
603
- // Cache TTL in seconds
604
- cacheTtl: 3600,
605
-
606
- // Permission check mode
607
- mode: 'RBAC' | 'DIRECT' | 'FULL',
608
-
609
- // Custom permission resolver
610
- resolver: CustomPermissionResolver,
611
- });
612
- ```
563
+ **Features:**
564
+ - Supports AND/OR operators via `@RequirePermission` and `@RequireAnyPermission`
565
+ - Nested conditions via `@RequirePermissionCondition`
566
+ - Wildcard support (`*` and `*.suffix`)
567
+ - Company/branch scoped permissions
613
568
 
614
569
  ---
615
570
 
@@ -906,7 +861,7 @@ export class PostController {
906
861
 
907
862
  ### Slug Interceptor
908
863
 
909
- Auto-generate slugs from name field:
864
+ Auto-generate slugs from name field using UtilsService (injected via DI):
910
865
 
911
866
  ```typescript
912
867
  import { Slug } from '@flusys/nestjs-shared/interceptors';
@@ -922,6 +877,8 @@ export class ProductController {
922
877
  }
923
878
  ```
924
879
 
880
+ **Note:** Requires `UtilsModule` to be imported in your module for dependency injection.
881
+
925
882
  ---
926
883
 
927
884
  ## Caching System
@@ -1005,7 +962,7 @@ export class AppModule {}
1005
962
 
1006
963
  ## Multi-Tenant DataSource
1007
964
 
1008
- Dynamic database connection management for multi-tenant applications.
965
+ Dynamic database connection management with connection pooling and request-scoped tenant resolution.
1009
966
 
1010
967
  ### Setup
1011
968
 
@@ -1015,7 +972,7 @@ import { DataSourceModule } from '@flusys/nestjs-shared/modules';
1015
972
  @Module({
1016
973
  imports: [
1017
974
  DataSourceModule.forRoot({
1018
- // Default database config (used as template)
975
+ bootstrapAppConfig: { databaseMode: 'multi-tenant' },
1019
976
  defaultDatabaseConfig: {
1020
977
  type: 'mysql',
1021
978
  host: 'localhost',
@@ -1023,11 +980,9 @@ import { DataSourceModule } from '@flusys/nestjs-shared/modules';
1023
980
  username: 'root',
1024
981
  password: 'password',
1025
982
  },
1026
-
1027
- // Tenant configurations
1028
983
  tenants: [
1029
- { id: 'tenant1', database: 'tenant1_db', isActive: true },
1030
- { id: 'tenant2', database: 'tenant2_db', isActive: true },
984
+ { id: 'tenant1', database: 'tenant1_db' },
985
+ { id: 'tenant2', database: 'tenant2_db' },
1031
986
  ],
1032
987
  }),
1033
988
  ],
@@ -1035,41 +990,35 @@ import { DataSourceModule } from '@flusys/nestjs-shared/modules';
1035
990
  export class AppModule {}
1036
991
  ```
1037
992
 
1038
- ### Usage with Tenant Header
993
+ ### Key Methods
1039
994
 
1040
- ```typescript
1041
- // Client sends X-Tenant-ID header
1042
- // DataSource automatically switches to tenant's database
995
+ | Method | Description |
996
+ |--------|-------------|
997
+ | `getDataSource()` | Get DataSource for current tenant (from header) |
998
+ | `getDataSourceForTenant(id)` | Get DataSource for specific tenant |
999
+ | `getRepository(entity)` | Get repository for current tenant |
1000
+ | `withTenant(id, callback)` | Execute callback with specific tenant DataSource |
1001
+ | `forAllTenants(callback)` | Execute callback for all active tenants |
1002
+ | `registerTenant(config)` | Register new tenant at runtime |
1003
+ | `removeTenant(id)` | Remove tenant and close connection |
1004
+
1005
+ ### Usage
1043
1006
 
1007
+ ```typescript
1044
1008
  @Injectable()
1045
1009
  export class TenantService {
1046
- constructor(
1047
- @Inject('DATASOURCE_PROVIDER')
1048
- private dataSourceProvider: MultiTenantDataSourceService,
1049
- ) {}
1010
+ constructor(private dataSource: MultiTenantDataSourceService) {}
1050
1011
 
1051
- async getConnection(tenantId: string) {
1052
- return this.dataSourceProvider.getConnection(tenantId);
1012
+ async getUsers() {
1013
+ // Auto-resolves tenant from X-Tenant-ID header
1014
+ const repo = await this.dataSource.getRepository(User);
1015
+ return repo.find();
1053
1016
  }
1054
- }
1055
- ```
1056
-
1057
- ### Tenant Resolution
1058
1017
 
1059
- ```typescript
1060
- // Default: Resolved from X-Tenant-ID header
1061
- @Controller('users')
1062
- export class UserController {
1063
- // Automatically uses tenant-specific database
1064
- }
1065
-
1066
- // Manual tenant specification
1067
- @Injectable()
1068
- export class CrossTenantService {
1069
- async copyData(fromTenant: string, toTenant: string) {
1070
- const fromConn = await this.dataSourceProvider.getConnection(fromTenant);
1071
- const toConn = await this.dataSourceProvider.getConnection(toTenant);
1072
- // ...
1018
+ async crossTenantCopy(fromId: string, toId: string) {
1019
+ const fromDs = await this.dataSource.getDataSourceForTenant(fromId);
1020
+ const toDs = await this.dataSource.getDataSourceForTenant(toId);
1021
+ // Copy data between tenants
1073
1022
  }
1074
1023
  }
1075
1024
  ```
@@ -1092,18 +1041,15 @@ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
1092
1041
  "category": "electronics"
1093
1042
  },
1094
1043
  "pagination": {
1095
- "page": 1,
1096
- "limit": 10
1044
+ "currentPage": 0,
1045
+ "pageSize": 10
1097
1046
  },
1098
1047
  "sort": {
1099
- "field": "createdAt",
1100
- "order": "DESC"
1101
- },
1102
- "search": {
1103
- "fields": ["name", "description"],
1104
- "value": "laptop"
1048
+ "createdAt": "DESC",
1049
+ "name": "ASC"
1105
1050
  },
1106
- "select": ["id", "name", "price"]
1051
+ "select": ["id", "name", "price"],
1052
+ "withDeleted": false
1107
1053
  }
1108
1054
  ```
1109
1055
 
@@ -1418,4 +1364,4 @@ This is the shared infrastructure layer used by all other Flusys packages.
1418
1364
 
1419
1365
  ---
1420
1366
 
1421
- **Last Updated:** 2026-02-16
1367
+ **Last Updated:** 2026-02-18
@@ -8,10 +8,10 @@ Object.defineProperty(exports, "createApiController", {
8
8
  return createApiController;
9
9
  }
10
10
  });
11
- const _decorators = require("@flusys/nestjs-shared/decorators");
12
- const _dtos = require("@flusys/nestjs-shared/dtos");
13
- const _guards = require("@flusys/nestjs-shared/guards");
14
- const _interceptors = require("@flusys/nestjs-shared/interceptors");
11
+ const _decorators = require("../decorators");
12
+ const _dtos = require("../dtos");
13
+ const _guards = require("../guards");
14
+ const _interceptors = require("../interceptors");
15
15
  const _common = require("@nestjs/common");
16
16
  const _swagger = require("@nestjs/swagger");
17
17
  const _classtransformer = require("class-transformer");
@@ -104,8 +104,10 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
104
104
  // 2. It's an object with 'level' property but no endpoint keys
105
105
  const isGlobalSecurity = typeof securityConfig === 'string' || securityConfig && typeof securityConfig === 'object' && 'level' in securityConfig && !endpointKeys.some((key)=>key in securityConfig);
106
106
  // Normalize security config for each endpoint
107
+ // IMPORTANT: When per-endpoint security is specified, default to 'jwt' for unconfigured endpoints
108
+ // to prevent accidentally exposing endpoints without authentication
107
109
  const defaultSecurity = isGlobalSecurity ? normalizeSecurity(securityConfig) : {
108
- level: 'public'
110
+ level: 'jwt'
109
111
  };
110
112
  const security = {
111
113
  insert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insert),
@@ -347,16 +349,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
347
349
  (0, _common.HttpCode)(_common.HttpStatus.OK),
348
350
  (0, _swagger.ApiOperation)({
349
351
  summary: 'Get all items with filters and pagination',
350
- description: `
351
- Retrieves items with support for:
352
- - **filter**: Apply field-based filters (e.g., \`{ "isActive": true }\`)
353
- - **pagination**: Control page and page size
354
- - **sort**: Order by any field (e.g., \`{ "createdAt": "DESC" }\`)
355
- - **select**: Choose specific fields to return
356
- - **withDeleted**: Include soft-deleted items
357
- - **extraKey**: Include additional relations
358
- - **q** (query param): Global text search
359
- `
352
+ description: 'Supports filter, pagination, sort, select, withDeleted, and q (search) params'
360
353
  }),
361
354
  (0, _swagger.ApiQuery)({
362
355
  name: 'q',
@@ -385,15 +378,7 @@ Retrieves items with support for:
385
378
  (0, _common.HttpCode)(_common.HttpStatus.OK),
386
379
  (0, _swagger.ApiOperation)({
387
380
  summary: 'Delete, restore, or permanently remove items',
388
- description: `
389
- Performs one of three actions:
390
-
391
- - **"delete"** (soft delete): Marks items as deleted but keeps in database
392
- - **"restore"**: Reverts soft-deleted items to active
393
- - **"permanent"**: Completely removes items from database
394
-
395
- Supports single ID or array of IDs for batch operations.
396
- `
381
+ description: 'Types: delete (soft), restore, permanent. Supports batch IDs.'
397
382
  }),
398
383
  (0, _swagger.ApiResponse)({
399
384
  status: 200,
@@ -8,6 +8,7 @@ _export_star(require("./request-scoped-api.service"), exports);
8
8
  _export_star(require("./hybrid-cache.class"), exports);
9
9
  _export_star(require("./winston-logger-adapter.class"), exports);
10
10
  _export_star(require("./winston.logger.class"), exports);
11
+ _export_star(require("../constants/permissions"), exports);
11
12
  function _export_star(from, to) {
12
13
  Object.keys(from).forEach(function(k) {
13
14
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -41,6 +41,20 @@ _export(exports, {
41
41
  return REQUEST_ID_HEADER;
42
42
  }
43
43
  });
44
+ _export_star(require("./permissions"), exports);
45
+ function _export_star(from, to) {
46
+ Object.keys(from).forEach(function(k) {
47
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
48
+ Object.defineProperty(to, k, {
49
+ enumerable: true,
50
+ get: function() {
51
+ return from[k];
52
+ }
53
+ });
54
+ }
55
+ });
56
+ return from;
57
+ }
44
58
  const IS_PUBLIC_KEY = 'isPublic';
45
59
  const PERMISSIONS_KEY = 'permissions';
46
60
  const CACHE_INSTANCE = 'CACHE_INSTANCE';
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Centralized Permission Codes
3
+ *
4
+ * Single source of truth for all permission codes used across the application.
5
+ * Use these constants instead of hardcoded strings to prevent typos and enable easy refactoring.
6
+ *
7
+ * Naming Convention: <entity>.<action>
8
+ * - entity: The resource being accessed (e.g., user, role, company)
9
+ * - action: The operation being performed (create, read, update, delete, assign)
10
+ */ // ==================== AUTH MODULE ====================
11
+ "use strict";
12
+ Object.defineProperty(exports, "__esModule", {
13
+ value: true
14
+ });
15
+ function _export(target, all) {
16
+ for(var name in all)Object.defineProperty(target, name, {
17
+ enumerable: true,
18
+ get: Object.getOwnPropertyDescriptor(all, name).get
19
+ });
20
+ }
21
+ _export(exports, {
22
+ get ACTION_PERMISSIONS () {
23
+ return ACTION_PERMISSIONS;
24
+ },
25
+ get BRANCH_PERMISSIONS () {
26
+ return BRANCH_PERMISSIONS;
27
+ },
28
+ get COMPANY_ACTION_PERMISSIONS () {
29
+ return COMPANY_ACTION_PERMISSIONS;
30
+ },
31
+ get COMPANY_PERMISSIONS () {
32
+ return COMPANY_PERMISSIONS;
33
+ },
34
+ get EMAIL_CONFIG_PERMISSIONS () {
35
+ return EMAIL_CONFIG_PERMISSIONS;
36
+ },
37
+ get EMAIL_TEMPLATE_PERMISSIONS () {
38
+ return EMAIL_TEMPLATE_PERMISSIONS;
39
+ },
40
+ get FILE_PERMISSIONS () {
41
+ return FILE_PERMISSIONS;
42
+ },
43
+ get FOLDER_PERMISSIONS () {
44
+ return FOLDER_PERMISSIONS;
45
+ },
46
+ get FORM_PERMISSIONS () {
47
+ return FORM_PERMISSIONS;
48
+ },
49
+ get PERMISSIONS () {
50
+ return PERMISSIONS;
51
+ },
52
+ get ROLE_ACTION_PERMISSIONS () {
53
+ return ROLE_ACTION_PERMISSIONS;
54
+ },
55
+ get ROLE_PERMISSIONS () {
56
+ return ROLE_PERMISSIONS;
57
+ },
58
+ get STORAGE_CONFIG_PERMISSIONS () {
59
+ return STORAGE_CONFIG_PERMISSIONS;
60
+ },
61
+ get USER_ACTION_PERMISSIONS () {
62
+ return USER_ACTION_PERMISSIONS;
63
+ },
64
+ get USER_PERMISSIONS () {
65
+ return USER_PERMISSIONS;
66
+ },
67
+ get USER_ROLE_PERMISSIONS () {
68
+ return USER_ROLE_PERMISSIONS;
69
+ }
70
+ });
71
+ const USER_PERMISSIONS = {
72
+ CREATE: 'user.create',
73
+ READ: 'user.read',
74
+ UPDATE: 'user.update',
75
+ DELETE: 'user.delete'
76
+ };
77
+ const COMPANY_PERMISSIONS = {
78
+ CREATE: 'company.create',
79
+ READ: 'company.read',
80
+ UPDATE: 'company.update',
81
+ DELETE: 'company.delete'
82
+ };
83
+ const BRANCH_PERMISSIONS = {
84
+ CREATE: 'branch.create',
85
+ READ: 'branch.read',
86
+ UPDATE: 'branch.update',
87
+ DELETE: 'branch.delete'
88
+ };
89
+ const ACTION_PERMISSIONS = {
90
+ CREATE: 'action.create',
91
+ READ: 'action.read',
92
+ UPDATE: 'action.update',
93
+ DELETE: 'action.delete'
94
+ };
95
+ const ROLE_PERMISSIONS = {
96
+ CREATE: 'role.create',
97
+ READ: 'role.read',
98
+ UPDATE: 'role.update',
99
+ DELETE: 'role.delete'
100
+ };
101
+ const ROLE_ACTION_PERMISSIONS = {
102
+ READ: 'role-action.read',
103
+ ASSIGN: 'role-action.assign'
104
+ };
105
+ const USER_ROLE_PERMISSIONS = {
106
+ READ: 'user-role.read',
107
+ ASSIGN: 'user-role.assign'
108
+ };
109
+ const USER_ACTION_PERMISSIONS = {
110
+ READ: 'user-action.read',
111
+ ASSIGN: 'user-action.assign'
112
+ };
113
+ const COMPANY_ACTION_PERMISSIONS = {
114
+ READ: 'company-action.read',
115
+ ASSIGN: 'company-action.assign'
116
+ };
117
+ const FILE_PERMISSIONS = {
118
+ CREATE: 'file.create',
119
+ READ: 'file.read',
120
+ UPDATE: 'file.update',
121
+ DELETE: 'file.delete'
122
+ };
123
+ const FOLDER_PERMISSIONS = {
124
+ CREATE: 'folder.create',
125
+ READ: 'folder.read',
126
+ UPDATE: 'folder.update',
127
+ DELETE: 'folder.delete'
128
+ };
129
+ const STORAGE_CONFIG_PERMISSIONS = {
130
+ CREATE: 'storage-config.create',
131
+ READ: 'storage-config.read',
132
+ UPDATE: 'storage-config.update',
133
+ DELETE: 'storage-config.delete'
134
+ };
135
+ const EMAIL_CONFIG_PERMISSIONS = {
136
+ CREATE: 'email-config.create',
137
+ READ: 'email-config.read',
138
+ UPDATE: 'email-config.update',
139
+ DELETE: 'email-config.delete'
140
+ };
141
+ const EMAIL_TEMPLATE_PERMISSIONS = {
142
+ CREATE: 'email-template.create',
143
+ READ: 'email-template.read',
144
+ UPDATE: 'email-template.update',
145
+ DELETE: 'email-template.delete'
146
+ };
147
+ const FORM_PERMISSIONS = {
148
+ CREATE: 'form.create',
149
+ READ: 'form.read',
150
+ UPDATE: 'form.update',
151
+ DELETE: 'form.delete'
152
+ };
153
+ const PERMISSIONS = {
154
+ // Auth
155
+ USER: USER_PERMISSIONS,
156
+ COMPANY: COMPANY_PERMISSIONS,
157
+ BRANCH: BRANCH_PERMISSIONS,
158
+ // IAM
159
+ ACTION: ACTION_PERMISSIONS,
160
+ ROLE: ROLE_PERMISSIONS,
161
+ ROLE_ACTION: ROLE_ACTION_PERMISSIONS,
162
+ USER_ROLE: USER_ROLE_PERMISSIONS,
163
+ USER_ACTION: USER_ACTION_PERMISSIONS,
164
+ COMPANY_ACTION: COMPANY_ACTION_PERMISSIONS,
165
+ // Storage
166
+ FILE: FILE_PERMISSIONS,
167
+ FOLDER: FOLDER_PERMISSIONS,
168
+ STORAGE_CONFIG: STORAGE_CONFIG_PERMISSIONS,
169
+ // Email
170
+ EMAIL_CONFIG: EMAIL_CONFIG_PERMISSIONS,
171
+ EMAIL_TEMPLATE: EMAIL_TEMPLATE_PERMISSIONS,
172
+ // Form Builder
173
+ FORM: FORM_PERMISSIONS
174
+ };
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "ApiResponseDto", {
8
8
  return ApiResponseDto;
9
9
  }
10
10
  });
11
- const _dtos = require("@flusys/nestjs-shared/dtos");
11
+ const _dtos = require("../dtos");
12
12
  const _common = require("@nestjs/common");
13
13
  const _swagger = require("@nestjs/swagger");
14
14
  const ApiResponseDto = (dto, isArray = false, arrayType = 'list')=>{
@@ -6,6 +6,7 @@ _export_star(require("./api-response.decorator"), exports);
6
6
  _export_star(require("./current-user.decorator"), exports);
7
7
  _export_star(require("./public.decorator"), exports);
8
8
  _export_star(require("./require-permission.decorator"), exports);
9
+ _export_star(require("./sanitize-html.decorator"), exports);
9
10
  function _export_star(from, to) {
10
11
  Object.keys(from).forEach(function(k) {
11
12
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get SanitizeAndTrim () {
13
+ return SanitizeAndTrim;
14
+ },
15
+ get SanitizeHtml () {
16
+ return SanitizeHtml;
17
+ }
18
+ });
19
+ const _classtransformer = require("class-transformer");
20
+ const _htmlsanitizerutil = require("../utils/html-sanitizer.util");
21
+ function SanitizeHtml() {
22
+ return (0, _classtransformer.Transform)(({ value })=>{
23
+ if (typeof value === 'string') {
24
+ return (0, _htmlsanitizerutil.escapeHtml)(value);
25
+ }
26
+ return value;
27
+ });
28
+ }
29
+ function SanitizeAndTrim() {
30
+ return (0, _classtransformer.Transform)(({ value })=>{
31
+ if (typeof value === 'string') {
32
+ return (0, _htmlsanitizerutil.escapeHtml)(value.trim());
33
+ }
34
+ return value;
35
+ });
36
+ }