mongodb-dynamic-api 2.1.5 → 2.1.7

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 (64) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/package.json +2 -2
  3. package/src/builders/index.d.ts +0 -1
  4. package/src/builders/index.js +0 -1
  5. package/src/builders/route-decorators/route-decorators.builder.d.ts +0 -1
  6. package/src/decorators/index.d.ts +0 -1
  7. package/src/decorators/index.js +0 -1
  8. package/src/dynamic-api.module.d.ts +2 -0
  9. package/src/dynamic-api.module.js +39 -29
  10. package/src/guards/base-policies.guard.d.ts +7 -8
  11. package/src/guards/base-policies.guard.js +17 -22
  12. package/src/helpers/controller-ability-predicates.helper.d.ts +2 -2
  13. package/src/helpers/controller-mixin.helper.d.ts +4 -28
  14. package/src/helpers/controller-mixin.helper.js +6 -16
  15. package/src/helpers/format.helper.d.ts +2 -0
  16. package/src/helpers/format.helper.js +6 -1
  17. package/src/interfaces/dynamic-api-ability.interface.d.ts +9 -0
  18. package/src/interfaces/dynamic-api-ability.interface.js +2 -0
  19. package/src/interfaces/dynamic-api-controller-options.interface.d.ts +1 -1
  20. package/src/interfaces/dynamic-api-policy-handler.interface.d.ts +4 -10
  21. package/src/interfaces/dynamic-api-route-config.interface.d.ts +2 -2
  22. package/src/interfaces/index.d.ts +1 -1
  23. package/src/interfaces/index.js +1 -1
  24. package/src/mixins/create-policies-guard.mixin.d.ts +3 -2
  25. package/src/mixins/create-policies-guard.mixin.js +9 -6
  26. package/src/modules/auth/mixins/auth-controller.mixin.js +6 -1
  27. package/src/modules/auth/mixins/auth-register-policies-guard.mixin.d.ts +2 -3
  28. package/src/modules/auth/mixins/auth-register-policies-guard.mixin.js +6 -35
  29. package/src/modules/auth/services/base-auth.service.d.ts +0 -1
  30. package/src/modules/auth/services/base-auth.service.js +3 -6
  31. package/src/routes/create-many/create-many-controller.mixin.js +0 -2
  32. package/src/routes/create-many/create-many.helper.js +2 -2
  33. package/src/routes/create-one/create-one-controller.mixin.js +0 -2
  34. package/src/routes/create-one/create-one.helper.js +2 -2
  35. package/src/routes/delete-many/delete-many-controller.mixin.js +0 -2
  36. package/src/routes/delete-many/delete-many.helper.js +2 -2
  37. package/src/routes/delete-one/delete-one-controller.mixin.js +0 -2
  38. package/src/routes/delete-one/delete-one.helper.js +2 -2
  39. package/src/routes/duplicate-many/duplicate-many-controller.mixin.js +0 -2
  40. package/src/routes/duplicate-many/duplicate-many.helper.js +2 -2
  41. package/src/routes/duplicate-one/duplicate-one-controller.mixin.js +0 -2
  42. package/src/routes/duplicate-one/duplicate-one.helper.js +2 -2
  43. package/src/routes/get-many/get-many-controller.mixin.js +9 -6
  44. package/src/routes/get-many/get-many.helper.js +2 -2
  45. package/src/routes/get-one/get-one-controller.mixin.js +1 -4
  46. package/src/routes/get-one/get-one.helper.js +2 -2
  47. package/src/routes/replace-one/replace-one-controller.mixin.js +1 -3
  48. package/src/routes/replace-one/replace-one.helper.js +2 -2
  49. package/src/routes/update-many/update-many-controller.mixin.js +1 -3
  50. package/src/routes/update-many/update-many.helper.js +2 -2
  51. package/src/routes/update-one/update-one-controller.mixin.js +1 -3
  52. package/src/routes/update-one/update-one.helper.js +2 -2
  53. package/src/services/base/base.service.d.ts +7 -1
  54. package/src/services/base/base.service.js +32 -0
  55. package/src/version.json +1 -1
  56. package/tsconfig.tsbuildinfo +1 -1
  57. package/src/builders/casl/casl-ability.builder.d.ts +0 -5
  58. package/src/builders/casl/casl-ability.builder.js +0 -17
  59. package/src/decorators/check-policies.decorator.d.ts +0 -5
  60. package/src/decorators/check-policies.decorator.js +0 -8
  61. package/src/interfaces/dynamic-api-casl-ability.interface.d.ts +0 -12
  62. package/src/interfaces/dynamic-api-casl-ability.interface.js +0 -5
  63. package/src/routes/delete-many/delete-many.presenter.d.ts +0 -3
  64. package/src/routes/delete-many/delete-many.presenter.js +0 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  Changelog
2
2
 
3
+ ## [2.1.7](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.6...v2.1.7) (2024-04-01)
4
+
5
+ ## [2.1.6](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.5...v2.1.6) (2024-03-31)
6
+
3
7
  ## [2.1.5](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.4...v2.1.5) (2024-03-29)
4
8
 
5
9
  ## [2.1.4](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.3...v2.1.4) (2024-03-29)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mongodb-dynamic-api",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "Auto generated CRUD API for MongoDB using NestJS",
5
5
  "readmeFilename": "README.md",
6
6
  "main": "index.js",
@@ -38,7 +38,6 @@
38
38
  },
39
39
  "homepage": "https://mikedev75015.github.io",
40
40
  "dependencies": {
41
- "@casl/ability": "^6.7.0",
42
41
  "@nestjs/cache-manager": "^2.2.1",
43
42
  "@nestjs/common": "^10.3.2",
44
43
  "@nestjs/core": "^10.3.2",
@@ -84,6 +83,7 @@
84
83
  "eslint-plugin-prettier": "^5.1.3",
85
84
  "jest": "^29.7.0",
86
85
  "jest-junit": "^16.0.0",
86
+ "jest-mock-extended": "^3.0.5",
87
87
  "jest-sonar-reporter": "^2.0.0",
88
88
  "prettier": "^3.2.5",
89
89
  "release-it": "^17.1.1",
@@ -1,3 +1,2 @@
1
- export * from './casl/casl-ability.builder';
2
1
  export * from './route-decorators/auth-decorators.builder';
3
2
  export * from './route-decorators/route-decorators.builder';
@@ -14,6 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./casl/casl-ability.builder"), exports);
18
17
  __exportStar(require("./route-decorators/auth-decorators.builder"), exports);
19
18
  __exportStar(require("./route-decorators/route-decorators.builder"), exports);
@@ -12,7 +12,6 @@ declare class RouteDecoratorsBuilder<Entity extends BaseEntity> implements Dynam
12
12
  private readonly bodyRouteTypeIsOptional;
13
13
  constructor(routeType: RouteType, entity: Type<Entity>, version: string | undefined, description: string | undefined, isPublic: boolean | undefined, dTOs?: {
14
14
  param?: Type;
15
- query?: Type;
16
15
  body?: Type;
17
16
  presenter?: Type;
18
17
  });
@@ -1,3 +1,2 @@
1
- export * from './check-policies.decorator';
2
1
  export * from './public.decorator';
3
2
  export * from './schema-options.decorator';
@@ -14,6 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./check-policies.decorator"), exports);
18
17
  __exportStar(require("./public.decorator"), exports);
19
18
  __exportStar(require("./schema-options.decorator"), exports);
@@ -6,5 +6,7 @@ export declare class DynamicApiModule {
6
6
  static readonly state: DynamicApiGlobalStateService;
7
7
  static forRoot(uri: string, { useGlobalCache, cacheOptions, useAuth, }?: DynamicApiForRootOptions): DynamicModule;
8
8
  static forFeature<Entity extends BaseEntity>({ entity, controllerOptions, routes, }: DynamicApiForFeatureOptions<Entity>): Promise<DynamicModule>;
9
+ private static buildStateFromOptions;
10
+ private static initializeAuthOptions;
9
11
  private static setDefaultRoutesIfNotConfigured;
10
12
  }
@@ -27,19 +27,8 @@ let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
27
27
  throw new Error('You must provide a valid mongodb uri in the forRoot method to use MongoDB Dynamic API');
28
28
  }
29
29
  this.state.set([
30
- 'partial', {
31
- initialized: true,
32
- isGlobalCacheEnabled: useGlobalCache,
33
- ...(cacheOptions?.excludePaths ? { cacheExcludedPaths: cacheOptions?.excludePaths } : {}),
34
- ...(useAuth?.user ? {
35
- isAuthEnabled: true,
36
- credentials: {
37
- loginField: !useAuth.user.loginField ? 'email' : String(useAuth.user.loginField),
38
- passwordField: !useAuth.user.passwordField ? 'password' : String(useAuth.user.passwordField),
39
- },
40
- jwtSecret: useAuth.jwt?.secret ?? 'dynamic-api-jwt-secret',
41
- } : {}),
42
- },
30
+ 'partial',
31
+ this.buildStateFromOptions(useGlobalCache, cacheOptions, useAuth),
43
32
  ]);
44
33
  return {
45
34
  module: DynamicApiModule_1,
@@ -48,22 +37,7 @@ let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
48
37
  cache_manager_1.CacheModule.register({ isGlobal: true, ...cacheOptions }),
49
38
  mongoose_1.MongooseModule.forRoot(uri, { connectionName: this.state.get('connectionName') }),
50
39
  ...(useAuth?.user ? [
51
- modules_1.AuthModule.forRoot({
52
- user: {
53
- entity: useAuth.user.entity,
54
- loginField: useAuth.user.loginField ?? 'email',
55
- passwordField: useAuth.user.passwordField ?? 'password',
56
- requestAdditionalFields: useAuth.user.requestAdditionalFields ?? [],
57
- },
58
- jwt: {
59
- secret: useAuth.jwt?.secret ?? 'dynamic-api-jwt-secret',
60
- expiresIn: useAuth.jwt?.expiresIn ?? '1d',
61
- },
62
- register: useAuth.register ?? {
63
- protected: false,
64
- additionalFields: [],
65
- },
66
- }),
40
+ modules_1.AuthModule.forRoot(this.initializeAuthOptions(useAuth)),
67
41
  ] : []),
68
42
  ],
69
43
  exports: [modules_1.DynamicApiConfigModule],
@@ -144,6 +118,42 @@ let DynamicApiModule = DynamicApiModule_1 = class DynamicApiModule {
144
118
  }, 5000);
145
119
  });
146
120
  }
121
+ static buildStateFromOptions(useGlobalCache, cacheOptions, useAuth) {
122
+ return {
123
+ initialized: true,
124
+ isGlobalCacheEnabled: useGlobalCache,
125
+ ...(cacheOptions?.excludePaths ? { cacheExcludedPaths: cacheOptions?.excludePaths } : {}),
126
+ ...(useAuth?.user ? {
127
+ isAuthEnabled: true,
128
+ credentials: {
129
+ loginField: !useAuth.user.loginField ? 'email' : String(useAuth.user.loginField),
130
+ passwordField: !useAuth.user.passwordField ? 'password' : String(useAuth.user.passwordField),
131
+ },
132
+ jwtSecret: useAuth.jwt?.secret ?? 'dynamic-api-jwt-secret',
133
+ } : {}),
134
+ };
135
+ }
136
+ static initializeAuthOptions(useAuth) {
137
+ return {
138
+ user: {
139
+ entity: useAuth.user.entity,
140
+ loginField: useAuth.user.loginField ?? 'email',
141
+ passwordField: useAuth.user.passwordField ?? 'password',
142
+ requestAdditionalFields: useAuth.user.requestAdditionalFields ?? [],
143
+ },
144
+ jwt: {
145
+ secret: useAuth.jwt?.secret ?? 'dynamic-api-jwt-secret',
146
+ expiresIn: useAuth.jwt?.expiresIn ?? '1d',
147
+ },
148
+ register: useAuth.register ? {
149
+ ...useAuth.register,
150
+ protected: useAuth.register.protected ?? !!useAuth.register.abilityPredicate,
151
+ } : {
152
+ protected: false,
153
+ additionalFields: [],
154
+ },
155
+ };
156
+ }
147
157
  static setDefaultRoutesIfNotConfigured(routes) {
148
158
  if (!routes.length) {
149
159
  return [
@@ -1,13 +1,12 @@
1
1
  import { CanActivate, ExecutionContext, Type } from '@nestjs/common';
2
- import { Reflector } from '@nestjs/core';
3
- import { RouteAbilityPredicate, RouteType } from '../interfaces';
2
+ import { AbilityPredicate, RouteType } from '../interfaces';
4
3
  import { BaseEntity } from '../models';
5
- export declare abstract class BasePoliciesGuard<Entity extends BaseEntity> implements CanActivate {
6
- protected readonly reflector: Reflector;
4
+ import { BaseService } from '../services';
5
+ export declare abstract class BasePoliciesGuard<Entity extends BaseEntity, Service extends BaseService<Entity>> implements CanActivate {
6
+ protected readonly service: Service;
7
7
  protected routeType: RouteType;
8
8
  protected entity: Type<Entity>;
9
- protected abilityPredicate: RouteAbilityPredicate<Entity> | undefined;
10
- protected constructor(reflector: Reflector);
11
- canActivate(context: ExecutionContext): boolean;
12
- private execPolicyHandler;
9
+ protected abilityPredicate: AbilityPredicate<Entity> | undefined;
10
+ protected constructor(service: Service);
11
+ canActivate(context: ExecutionContext): Promise<boolean>;
13
12
  }
@@ -2,31 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BasePoliciesGuard = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
- const builders_1 = require("../builders");
6
- const decorators_1 = require("../decorators");
7
5
  class BasePoliciesGuard {
8
- constructor(reflector) {
9
- this.reflector = reflector;
6
+ constructor(service) {
7
+ this.service = service;
10
8
  }
11
- canActivate(context) {
12
- const policyHandlers = this.reflector.get(decorators_1.CHECK_POLICIES_KEY, context.getHandler());
13
- if (!policyHandlers || !this.abilityPredicate) {
14
- return true;
9
+ async canActivate(context) {
10
+ let { user, query, params } = context.switchToHttp().getRequest();
11
+ if (this.abilityPredicate) {
12
+ if (!user) {
13
+ throw new common_1.ForbiddenException('Access Denied');
14
+ }
15
+ this.service.abilityPredicate = this.abilityPredicate;
16
+ this.service.user = user;
17
+ if (params?.id) {
18
+ await this.service.findOneDocument(params.id, query);
19
+ }
20
+ else {
21
+ await this.service.findManyDocuments(query);
22
+ }
15
23
  }
16
- let { user } = context.switchToHttp().getRequest();
17
- if (!user) {
18
- throw new common_1.ForbiddenException('Forbidden resource');
19
- }
20
- const ability = (0, builders_1.CaslAbilityBuilder)(this.entity, this.routeType, this.abilityPredicate, user);
21
- return policyHandlers.every((handler) => {
22
- return this.execPolicyHandler(handler, ability);
23
- });
24
- }
25
- execPolicyHandler(handler, ability) {
26
- if (typeof handler === 'function') {
27
- return handler(ability);
28
- }
29
- return handler.handle(ability);
24
+ return true;
30
25
  }
31
26
  }
32
27
  exports.BasePoliciesGuard = BasePoliciesGuard;
@@ -1,4 +1,4 @@
1
- import { ControllerAbilityPredicate, RouteAbilityPredicate, RouteType } from '../interfaces';
1
+ import { ControllerAbilityPredicate, AbilityPredicate, RouteType } from '../interfaces';
2
2
  import { BaseEntity } from '../models';
3
- declare function getPredicateFromControllerAbilityPredicates<Entity extends BaseEntity>(controllerAbilityPredicates: ControllerAbilityPredicate<Entity>[], route: RouteType): RouteAbilityPredicate<Entity>;
3
+ declare function getPredicateFromControllerAbilityPredicates<Entity extends BaseEntity>(controllerAbilityPredicates: ControllerAbilityPredicate<Entity>[], route: RouteType): AbilityPredicate<Entity>;
4
4
  export { getPredicateFromControllerAbilityPredicates };
@@ -7,60 +7,36 @@ declare function getControllerMixinData<Entity extends BaseEntity>(entity: Type<
7
7
  displayedName: string;
8
8
  description: string;
9
9
  isPublic: boolean;
10
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
10
+ abilityPredicate: import("../interfaces/dynamic-api-ability.interface").AbilityPredicate<Entity>;
11
11
  RouteBody: Type<any>;
12
12
  RoutePresenter: Type<any>;
13
13
  EntityParam?: undefined;
14
- RouteQuery?: undefined;
15
14
  } | {
16
15
  routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
17
16
  displayedName: string;
18
17
  description: string;
19
18
  isPublic: boolean;
20
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
19
+ abilityPredicate: import("../interfaces/dynamic-api-ability.interface").AbilityPredicate<Entity>;
21
20
  RoutePresenter: Type<any>;
22
21
  RouteBody?: undefined;
23
22
  EntityParam?: undefined;
24
- RouteQuery?: undefined;
25
23
  } | {
26
24
  routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
27
25
  displayedName: string;
28
26
  description: string;
29
27
  isPublic: boolean;
30
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
28
+ abilityPredicate: import("../interfaces/dynamic-api-ability.interface").AbilityPredicate<Entity>;
31
29
  EntityParam: typeof EntityParam;
32
30
  RoutePresenter: Type<any>;
33
31
  RouteBody?: undefined;
34
- RouteQuery?: undefined;
35
32
  } | {
36
33
  routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
37
34
  displayedName: string;
38
35
  description: string;
39
36
  isPublic: boolean;
40
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
37
+ abilityPredicate: import("../interfaces/dynamic-api-ability.interface").AbilityPredicate<Entity>;
41
38
  RouteBody: Type<any>;
42
39
  RoutePresenter: Type<any>;
43
40
  EntityParam: typeof EntityParam;
44
- RouteQuery?: undefined;
45
- } | {
46
- routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
47
- displayedName: string;
48
- description: string;
49
- isPublic: boolean;
50
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
51
- RouteQuery: Type<any>;
52
- RoutePresenter: Type<any>;
53
- RouteBody?: undefined;
54
- EntityParam?: undefined;
55
- } | {
56
- routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
57
- displayedName: string;
58
- description: string;
59
- isPublic: boolean;
60
- abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
61
- EntityParam: typeof EntityParam;
62
- RouteQuery: Type<any>;
63
- RoutePresenter: Type<any>;
64
- RouteBody?: undefined;
65
41
  };
66
42
  export { getControllerMixinData };
@@ -47,26 +47,17 @@ function buildDeletePresenterDTO(displayedName, version, CustomPresenter) {
47
47
  class RoutePresenter extends (CustomPresenter ?? dtos_1.DeletePresenter) {
48
48
  }
49
49
  Object.defineProperty(RoutePresenter, 'name', {
50
- value: CustomPresenter ? CustomPresenter.name : `Delete${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
50
+ value: `Delete${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
51
51
  writable: false,
52
52
  });
53
53
  return RoutePresenter;
54
54
  }
55
- function buildDefaultRouteQuery(entity, routeType, displayedName, version, CustomQuery) {
56
- class RouteQuery extends (CustomQuery ?? dtos_1.EntityQuery) {
57
- }
58
- Object.defineProperty(RouteQuery, 'name', {
59
- value: CustomQuery ? CustomQuery.name : `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Query`,
60
- writable: false,
61
- });
62
- return RouteQuery;
63
- }
64
55
  function buildDefaultRouteBody(entity, routeType, displayedName, version, CustomBody) {
65
56
  const optionalBody = routeType !== 'CreateOne' && routeType !== 'ReplaceOne';
66
57
  class RouteBody extends (CustomBody ?? (0, mixins_1.EntityBodyMixin)(entity, optionalBody)) {
67
58
  }
68
59
  Object.defineProperty(RouteBody, 'name', {
69
- value: CustomBody ? CustomBody.name : `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Dto`,
60
+ value: `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Dto`,
70
61
  writable: false,
71
62
  });
72
63
  return RouteBody;
@@ -75,18 +66,19 @@ function buildDefaultRoutePresenter(entity, routeType, displayedName, version, C
75
66
  class RoutePresenter extends (CustomPresenter ?? (0, mixins_1.EntityPresenterMixin)(entity)) {
76
67
  }
77
68
  Object.defineProperty(RoutePresenter, 'name', {
78
- value: CustomPresenter ? CustomPresenter.name : `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
69
+ value: CustomPresenter
70
+ ? `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`
71
+ : `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
79
72
  writable: false,
80
73
  });
81
74
  return RoutePresenter;
82
75
  }
83
76
  function getDTOsByRouteType(entity, routeType, displayedName, version, dTOs) {
84
- const { query: CustomQuery, body: CustomBody, presenter: CustomPresenter, } = dTOs ?? {};
77
+ const { body: CustomBody, presenter: CustomPresenter, } = dTOs ?? {};
85
78
  Object.defineProperty(dtos_1.EntityParam, 'name', {
86
79
  value: `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Param`,
87
80
  writable: false,
88
81
  });
89
- const RouteQuery = buildDefaultRouteQuery(entity, routeType, displayedName, version, CustomQuery);
90
82
  const RouteBody = buildDefaultRouteBody(entity, routeType, displayedName, version, CustomBody);
91
83
  const RoutePresenter = buildDefaultRoutePresenter(entity, routeType, displayedName, version, CustomPresenter);
92
84
  switch (routeType) {
@@ -121,13 +113,11 @@ function getDTOsByRouteType(entity, routeType, displayedName, version, dTOs) {
121
113
  };
122
114
  case 'GetMany':
123
115
  return {
124
- RouteQuery,
125
116
  RoutePresenter,
126
117
  };
127
118
  case 'GetOne':
128
119
  return {
129
120
  EntityParam: dtos_1.EntityParam,
130
- RouteQuery,
131
121
  RoutePresenter,
132
122
  };
133
123
  default:
@@ -1,3 +1,5 @@
1
+ import { RouteType } from '../interfaces';
1
2
  export declare function pascalCase(str?: string): string;
2
3
  export declare function isValidVersion(version: string): boolean;
3
4
  export declare function getFormattedApiTag<Entity>(apiTag: string | undefined, entityName: string): string;
5
+ export declare function getNamePrefix(routeType: RouteType, entityName: string, version: string | undefined): string;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFormattedApiTag = exports.isValidVersion = exports.pascalCase = void 0;
3
+ exports.getNamePrefix = exports.getFormattedApiTag = exports.isValidVersion = exports.pascalCase = void 0;
4
4
  const lodash_1 = require("lodash");
5
+ const versioning_config_helper_1 = require("./versioning-config.helper");
5
6
  function pascalCase(str) {
6
7
  return str ? (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(str)) : undefined;
7
8
  }
@@ -14,3 +15,7 @@ function getFormattedApiTag(apiTag, entityName) {
14
15
  return pascalCase(apiTag) ?? entityName;
15
16
  }
16
17
  exports.getFormattedApiTag = getFormattedApiTag;
18
+ function getNamePrefix(routeType, entityName, version) {
19
+ return `${routeType}${entityName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}`;
20
+ }
21
+ exports.getNamePrefix = getNamePrefix;
@@ -0,0 +1,9 @@
1
+ import { BaseEntity } from '../models';
2
+ import { RouteType } from './dynamic-api-route-type.type';
3
+ type AbilityPredicate<Entity extends BaseEntity, User = any> = (entity: Entity, user: User) => boolean;
4
+ type RegisterAbilityPredicate<User = any> = (user: User) => boolean;
5
+ type ControllerAbilityPredicate<Entity extends BaseEntity> = {
6
+ targets: RouteType[];
7
+ predicate: AbilityPredicate<Entity>;
8
+ };
9
+ export { ControllerAbilityPredicate, RegisterAbilityPredicate, AbilityPredicate, };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +1,6 @@
1
1
  import { ValidationPipeOptions } from '@nestjs/common';
2
2
  import { BaseEntity } from '../models';
3
- import { ControllerAbilityPredicate } from './dynamic-api-casl-ability.interface';
3
+ import { ControllerAbilityPredicate } from './dynamic-api-ability.interface';
4
4
  interface DynamicApiControllerOptions<Entity extends BaseEntity> {
5
5
  path: string;
6
6
  apiTag?: string;
@@ -1,14 +1,8 @@
1
1
  import { ExecutionContext } from '@nestjs/common';
2
- import { Reflector } from '@nestjs/core';
3
2
  import { BaseEntity } from '../models';
4
- import { AppAbility } from './dynamic-api-casl-ability.interface';
5
- interface IPolicyHandler<Entity extends BaseEntity> {
6
- handle(ability: AppAbility<Entity>): boolean;
7
- }
8
- type PolicyHandlerCallback<Entity extends BaseEntity> = (ability: AppAbility<Entity>) => boolean;
9
- type PolicyHandler<Entity extends BaseEntity> = IPolicyHandler<Entity> | PolicyHandlerCallback<Entity>;
3
+ import { BaseService } from '../services';
10
4
  interface PoliciesGuard<Entity extends BaseEntity> {
11
- canActivate(context: ExecutionContext): boolean;
5
+ canActivate(context: ExecutionContext): boolean | Promise<boolean>;
12
6
  }
13
- type PoliciesGuardConstructor<Entity extends BaseEntity> = new (reflector: Reflector) => PoliciesGuard<Entity>;
14
- export { PolicyHandler, PoliciesGuardConstructor, PoliciesGuard };
7
+ type PoliciesGuardConstructor<Entity extends BaseEntity> = new (service: BaseService<Entity>) => PoliciesGuard<Entity>;
8
+ export { PoliciesGuardConstructor, PoliciesGuard };
@@ -1,6 +1,6 @@
1
1
  import { ValidationPipeOptions } from '@nestjs/common';
2
2
  import { BaseEntity } from '../models';
3
- import { RouteAbilityPredicate } from './dynamic-api-casl-ability.interface';
3
+ import { AbilityPredicate } from './dynamic-api-ability.interface';
4
4
  import { DTOsBundle } from './dynamic-api-route-dtos-bundle.type';
5
5
  import { RouteType } from './dynamic-api-route-type.type';
6
6
  interface DynamicAPIRouteConfig<Entity extends BaseEntity> {
@@ -10,6 +10,6 @@ interface DynamicAPIRouteConfig<Entity extends BaseEntity> {
10
10
  version?: string;
11
11
  dTOs?: DTOsBundle;
12
12
  validationPipeOptions?: ValidationPipeOptions;
13
- abilityPredicate?: RouteAbilityPredicate<Entity>;
13
+ abilityPredicate?: AbilityPredicate<Entity>;
14
14
  }
15
15
  export { DynamicAPIRouteConfig };
@@ -1,7 +1,7 @@
1
1
  export * from './dynamic-api-controller-options.interface';
2
2
  export * from './dynamic-api-decorator-builder.interface';
3
3
  export * from './dynamic-api-cache-options.interface';
4
- export * from './dynamic-api-casl-ability.interface';
4
+ export * from './dynamic-api-ability.interface';
5
5
  export * from './dynamic-api-entity-mappers.interface';
6
6
  export * from './dynamic-api-global-state.interface';
7
7
  export * from './dynamic-api-options.interface';
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./dynamic-api-controller-options.interface"), exports);
18
18
  __exportStar(require("./dynamic-api-decorator-builder.interface"), exports);
19
19
  __exportStar(require("./dynamic-api-cache-options.interface"), exports);
20
- __exportStar(require("./dynamic-api-casl-ability.interface"), exports);
20
+ __exportStar(require("./dynamic-api-ability.interface"), exports);
21
21
  __exportStar(require("./dynamic-api-entity-mappers.interface"), exports);
22
22
  __exportStar(require("./dynamic-api-global-state.interface"), exports);
23
23
  __exportStar(require("./dynamic-api-options.interface"), exports);
@@ -1,5 +1,6 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { RouteAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../interfaces';
2
+ import { AbilityPredicate, PoliciesGuardConstructor, RouteType } from '../interfaces';
3
3
  import { BaseEntity } from '../models';
4
- declare function CreatePoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, routeType: RouteType, version: string | undefined, abilityPredicate: RouteAbilityPredicate<Entity> | undefined): PoliciesGuardConstructor<Entity>;
4
+ import { BaseService } from '../services';
5
+ declare function CreatePoliciesGuardMixin<Entity extends BaseEntity, Service extends BaseService<Entity>>(entity: Type<Entity>, routeType: RouteType, version: string | undefined, abilityPredicate: AbilityPredicate<Entity> | undefined): PoliciesGuardConstructor<Entity>;
5
6
  export { CreatePoliciesGuardMixin };
@@ -8,17 +8,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.CreatePoliciesGuardMixin = void 0;
13
16
  const common_1 = require("@nestjs/common");
14
- const core_1 = require("@nestjs/core");
15
17
  const guards_1 = require("../guards");
16
18
  const helpers_1 = require("../helpers");
17
19
  function CreatePoliciesGuardMixin(entity, routeType, version, abilityPredicate) {
18
20
  let RoutePoliciesGuard = class RoutePoliciesGuard extends guards_1.BasePoliciesGuard {
19
- constructor(reflector) {
20
- super(reflector);
21
- this.reflector = reflector;
21
+ constructor(service) {
22
+ super(service);
23
+ this.service = service;
22
24
  this.routeType = routeType;
23
25
  this.entity = entity;
24
26
  this.abilityPredicate = abilityPredicate;
@@ -26,10 +28,11 @@ function CreatePoliciesGuardMixin(entity, routeType, version, abilityPredicate)
26
28
  };
27
29
  RoutePoliciesGuard = __decorate([
28
30
  (0, common_1.Injectable)(),
29
- __metadata("design:paramtypes", [core_1.Reflector])
31
+ __param(0, (0, common_1.Inject)(`${(0, helpers_1.getNamePrefix)(routeType, entity.name, version)}Service`)),
32
+ __metadata("design:paramtypes", [Object])
30
33
  ], RoutePoliciesGuard);
31
34
  Object.defineProperty(RoutePoliciesGuard, 'name', {
32
- value: `${routeType}${entity.name}${(0, helpers_1.addVersionSuffix)(version)}PoliciesGuard`,
35
+ value: `${(0, helpers_1.getNamePrefix)(routeType, entity.name, version)}PoliciesGuard`,
33
36
  writable: false,
34
37
  });
35
38
  return RoutePoliciesGuard;
@@ -23,6 +23,9 @@ const guards_1 = require("../guards");
23
23
  const auth_register_policies_guard_mixin_1 = require("./auth-register-policies-guard.mixin");
24
24
  function AuthControllerMixin(userEntity, loginField, passwordField, additionalRequestFields = [], { additionalFields: additionalRegisterFields, protected: registerProtected, abilityPredicate: registerAbilityPredicate, } = {}) {
25
25
  var _a;
26
+ if (!loginField || !passwordField) {
27
+ throw new Error('Login and password fields are required');
28
+ }
26
29
  class AuthBodyPasswordFieldDto {
27
30
  }
28
31
  _a = passwordField;
@@ -36,6 +39,9 @@ function AuthControllerMixin(userEntity, loginField, passwordField, additionalRe
36
39
  }
37
40
  const additionalMandatoryFields = [];
38
41
  const additionalOptionalFields = [];
42
+ if (!additionalRegisterFields) {
43
+ additionalRegisterFields = [];
44
+ }
39
45
  additionalRegisterFields.forEach((field) => {
40
46
  if (typeof field === 'string') {
41
47
  additionalOptionalFields.push(field);
@@ -107,7 +113,6 @@ function AuthControllerMixin(userEntity, loginField, passwordField, additionalRe
107
113
  (0, swagger_1.ApiOkResponse)({ type: AuthPresenter }),
108
114
  (0, common_1.Post)('register'),
109
115
  (0, common_1.UseGuards)(AuthRegisterPoliciesGuard),
110
- (0, decorators_1.CheckPolicies)((ability) => ability.can(auth_register_policies_guard_mixin_1.registerRouteType, userEntity)),
111
116
  __param(0, (0, common_1.Body)()),
112
117
  __metadata("design:type", Function),
113
118
  __metadata("design:paramtypes", [AuthRegisterDto]),
@@ -1,6 +1,5 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { RegisterAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../../../interfaces';
2
+ import { PoliciesGuardConstructor, RegisterAbilityPredicate } from '../../../interfaces';
3
3
  import { BaseEntity } from '../../../models';
4
- declare const registerRouteType: RouteType;
5
4
  declare function AuthRegisterPoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, abilityPredicate: RegisterAbilityPredicate | undefined): PoliciesGuardConstructor<Entity>;
6
- export { AuthRegisterPoliciesGuardMixin, registerRouteType };
5
+ export { AuthRegisterPoliciesGuardMixin };
@@ -5,54 +5,25 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
8
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.registerRouteType = exports.AuthRegisterPoliciesGuardMixin = void 0;
13
- const ability_1 = require("@casl/ability");
9
+ exports.AuthRegisterPoliciesGuardMixin = void 0;
14
10
  const common_1 = require("@nestjs/common");
15
- const core_1 = require("@nestjs/core");
16
- const decorators_1 = require("../../../decorators");
17
- const registerRouteType = 'register';
18
- exports.registerRouteType = registerRouteType;
19
11
  function AuthRegisterPoliciesGuardMixin(entity, abilityPredicate) {
20
12
  let BaseAuthRegisterPoliciesGuard = class BaseAuthRegisterPoliciesGuard {
21
- constructor(reflector) {
22
- this.reflector = reflector;
13
+ constructor() {
23
14
  this.entity = entity;
24
15
  this.abilityPredicate = abilityPredicate;
25
16
  }
26
17
  canActivate(context) {
27
- const policyHandlers = this.reflector.get(decorators_1.CHECK_POLICIES_KEY, context.getHandler());
28
- if (!policyHandlers || !this.abilityPredicate) {
29
- return true;
30
- }
31
18
  let { user } = context.switchToHttp().getRequest();
32
- if (!user) {
33
- throw new common_1.ForbiddenException('Forbidden resource');
34
- }
35
- const { can, build } = new ability_1.AbilityBuilder(ability_1.createMongoAbility);
36
- if (abilityPredicate(user)) {
37
- can(registerRouteType, entity);
38
- }
39
- const ability = build({
40
- detectSubjectType: (object) => object.constructor,
41
- });
42
- return policyHandlers.every((handler) => {
43
- return this.execPolicyHandler(handler, ability);
44
- });
45
- }
46
- execPolicyHandler(handler, ability) {
47
- if (typeof handler === 'function') {
48
- return handler(ability);
19
+ if (this.abilityPredicate && (!user || !this.abilityPredicate(user))) {
20
+ throw new common_1.ForbiddenException('Access denied');
49
21
  }
50
- return handler.handle(ability);
22
+ return true;
51
23
  }
52
24
  };
53
25
  BaseAuthRegisterPoliciesGuard = __decorate([
54
- (0, common_1.Injectable)(),
55
- __metadata("design:paramtypes", [core_1.Reflector])
26
+ (0, common_1.Injectable)()
56
27
  ], BaseAuthRegisterPoliciesGuard);
57
28
  return BaseAuthRegisterPoliciesGuard;
58
29
  }