@lenne.tech/nest-server 10.3.0 → 10.3.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.
Files changed (112) hide show
  1. package/dist/config.env.js +24 -3
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/decorators/restricted.decorator.d.ts +1 -0
  4. package/dist/core/common/decorators/restricted.decorator.js +5 -2
  5. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  6. package/dist/core/common/inputs/combined-filter.input.js +5 -0
  7. package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
  8. package/dist/core/common/inputs/filter.input.js +5 -0
  9. package/dist/core/common/inputs/filter.input.js.map +1 -1
  10. package/dist/core/common/inputs/single-filter.input.js +10 -0
  11. package/dist/core/common/inputs/single-filter.input.js.map +1 -1
  12. package/dist/core/common/inputs/sort.input.js +5 -0
  13. package/dist/core/common/inputs/sort.input.js.map +1 -1
  14. package/dist/core/common/interceptors/check-response.interceptor.d.ts +11 -0
  15. package/dist/core/common/interceptors/check-response.interceptor.js +22 -2
  16. package/dist/core/common/interceptors/check-response.interceptor.js.map +1 -1
  17. package/dist/core/common/interfaces/server-options.interface.d.ts +8 -1
  18. package/dist/core/common/models/core-persistence.model.js +13 -0
  19. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  20. package/dist/core/modules/auth/core-auth.controller.js +7 -0
  21. package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
  22. package/dist/core/modules/auth/core-auth.model.js +6 -0
  23. package/dist/core/modules/auth/core-auth.model.js.map +1 -1
  24. package/dist/core/modules/auth/core-auth.resolver.js +7 -0
  25. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  26. package/dist/core/modules/auth/inputs/core-auth-sign-in.input.js +7 -0
  27. package/dist/core/modules/auth/inputs/core-auth-sign-in.input.js.map +1 -1
  28. package/dist/core/modules/auth/inputs/core-auth-sign-up.input.js +3 -0
  29. package/dist/core/modules/auth/inputs/core-auth-sign-up.input.js.map +1 -1
  30. package/dist/core/modules/file/core-file-info.model.js +14 -0
  31. package/dist/core/modules/file/core-file-info.model.js.map +1 -1
  32. package/dist/core/modules/file/core-file.controller.js +4 -0
  33. package/dist/core/modules/file/core-file.controller.js.map +1 -1
  34. package/dist/core/modules/file/core-file.resolver.js +7 -0
  35. package/dist/core/modules/file/core-file.resolver.js.map +1 -1
  36. package/dist/core/modules/health-check/core-health-check-result.model.js +7 -0
  37. package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -1
  38. package/dist/core/modules/health-check/core-health-check.controller.js +4 -0
  39. package/dist/core/modules/health-check/core-health-check.controller.js.map +1 -1
  40. package/dist/core/modules/user/core-user.model.js +15 -0
  41. package/dist/core/modules/user/core-user.model.js.map +1 -1
  42. package/dist/core/modules/user/inputs/core-user-create.input.js +4 -0
  43. package/dist/core/modules/user/inputs/core-user-create.input.js.map +1 -1
  44. package/dist/core/modules/user/inputs/core-user.input.js +6 -0
  45. package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
  46. package/dist/server/common/models/persistence.model.js +5 -0
  47. package/dist/server/common/models/persistence.model.js.map +1 -1
  48. package/dist/server/modules/auth/auth.controller.js +3 -0
  49. package/dist/server/modules/auth/auth.controller.js.map +1 -1
  50. package/dist/server/modules/auth/auth.model.js +4 -0
  51. package/dist/server/modules/auth/auth.model.js.map +1 -1
  52. package/dist/server/modules/auth/auth.resolver.js +5 -0
  53. package/dist/server/modules/auth/auth.resolver.js.map +1 -1
  54. package/dist/server/modules/auth/inputs/auth-sign-in.input.js +3 -0
  55. package/dist/server/modules/auth/inputs/auth-sign-in.input.js.map +1 -1
  56. package/dist/server/modules/auth/inputs/auth-sign-up.input.js +5 -0
  57. package/dist/server/modules/auth/inputs/auth-sign-up.input.js.map +1 -1
  58. package/dist/server/modules/file/file-info.model.js +3 -0
  59. package/dist/server/modules/file/file-info.model.js.map +1 -1
  60. package/dist/server/modules/file/file.controller.js +4 -0
  61. package/dist/server/modules/file/file.controller.js.map +1 -1
  62. package/dist/server/modules/user/avatar.controller.js +1 -0
  63. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  64. package/dist/server/modules/user/inputs/user-create.input.js +3 -0
  65. package/dist/server/modules/user/inputs/user-create.input.js.map +1 -1
  66. package/dist/server/modules/user/inputs/user.input.js +3 -0
  67. package/dist/server/modules/user/inputs/user.input.js.map +1 -1
  68. package/dist/server/modules/user/outputs/find-and-count-users-result.output.js +5 -0
  69. package/dist/server/modules/user/outputs/find-and-count-users-result.output.js.map +1 -1
  70. package/dist/server/modules/user/user.model.d.ts +1 -0
  71. package/dist/server/modules/user/user.model.js +14 -0
  72. package/dist/server/modules/user/user.model.js.map +1 -1
  73. package/dist/server/server.controller.js +2 -0
  74. package/dist/server/server.controller.js.map +1 -1
  75. package/dist/tsconfig.build.tsbuildinfo +1 -1
  76. package/package.json +1 -1
  77. package/src/config.env.ts +24 -3
  78. package/src/core/common/decorators/restricted.decorator.ts +8 -2
  79. package/src/core/common/inputs/combined-filter.input.ts +5 -0
  80. package/src/core/common/inputs/filter.input.ts +5 -0
  81. package/src/core/common/inputs/single-filter.input.ts +10 -0
  82. package/src/core/common/inputs/sort.input.ts +5 -0
  83. package/src/core/common/interceptors/check-response.interceptor.ts +18 -1
  84. package/src/core/common/interfaces/server-options.interface.ts +40 -2
  85. package/src/core/common/models/core-persistence.model.ts +9 -0
  86. package/src/core/modules/auth/core-auth.controller.ts +7 -0
  87. package/src/core/modules/auth/core-auth.model.ts +6 -0
  88. package/src/core/modules/auth/core-auth.resolver.ts +7 -0
  89. package/src/core/modules/auth/inputs/core-auth-sign-in.input.ts +7 -0
  90. package/src/core/modules/auth/inputs/core-auth-sign-up.input.ts +3 -0
  91. package/src/core/modules/file/core-file-info.model.ts +10 -0
  92. package/src/core/modules/file/core-file.controller.ts +4 -0
  93. package/src/core/modules/file/core-file.resolver.ts +7 -0
  94. package/src/core/modules/health-check/core-health-check-result.model.ts +7 -0
  95. package/src/core/modules/health-check/core-health-check.controller.ts +4 -0
  96. package/src/core/modules/user/core-user.model.ts +15 -0
  97. package/src/core/modules/user/inputs/core-user-create.input.ts +4 -0
  98. package/src/core/modules/user/inputs/core-user.input.ts +6 -0
  99. package/src/server/common/models/persistence.model.ts +5 -0
  100. package/src/server/modules/auth/auth.controller.ts +3 -0
  101. package/src/server/modules/auth/auth.model.ts +4 -0
  102. package/src/server/modules/auth/auth.resolver.ts +5 -0
  103. package/src/server/modules/auth/inputs/auth-sign-in.input.ts +3 -0
  104. package/src/server/modules/auth/inputs/auth-sign-up.input.ts +5 -0
  105. package/src/server/modules/file/file-info.model.ts +3 -0
  106. package/src/server/modules/file/file.controller.ts +4 -0
  107. package/src/server/modules/user/avatar.controller.ts +1 -0
  108. package/src/server/modules/user/inputs/user-create.input.ts +3 -0
  109. package/src/server/modules/user/inputs/user.input.ts +3 -0
  110. package/src/server/modules/user/outputs/find-and-count-users-result.output.ts +5 -0
  111. package/src/server/modules/user/user.model.ts +15 -0
  112. package/src/server/server.controller.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "10.3.0",
3
+ "version": "10.3.2",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
package/src/config.env.ts CHANGED
@@ -89,7 +89,14 @@ const config: { [env: string]: IServerOptions } = {
89
89
  },
90
90
  port: 3000,
91
91
  security: {
92
- checkResponseInterceptor: true,
92
+ checkResponseInterceptor: {
93
+ checkObjectItself: false,
94
+ debug: false,
95
+ ignoreUndefined: true,
96
+ mergeRoles: true,
97
+ removeUndefinedFromResultArray: true,
98
+ throwError: false,
99
+ },
93
100
  checkSecurityInterceptor: true,
94
101
  mapAndValidatePipe: true,
95
102
  },
@@ -196,7 +203,14 @@ const config: { [env: string]: IServerOptions } = {
196
203
  },
197
204
  port: 3000,
198
205
  security: {
199
- checkResponseInterceptor: true,
206
+ checkResponseInterceptor: {
207
+ checkObjectItself: false,
208
+ debug: false,
209
+ ignoreUndefined: true,
210
+ mergeRoles: true,
211
+ removeUndefinedFromResultArray: true,
212
+ throwError: false,
213
+ },
200
214
  checkSecurityInterceptor: true,
201
215
  mapAndValidatePipe: true,
202
216
  },
@@ -292,7 +306,14 @@ const config: { [env: string]: IServerOptions } = {
292
306
  },
293
307
  port: 3000,
294
308
  security: {
295
- checkResponseInterceptor: true,
309
+ checkResponseInterceptor: {
310
+ checkObjectItself: false,
311
+ debug: false,
312
+ ignoreUndefined: true,
313
+ mergeRoles: true,
314
+ removeUndefinedFromResultArray: true,
315
+ throwError: false,
316
+ },
296
317
  checkSecurityInterceptor: true,
297
318
  mapAndValidatePipe: true,
298
319
  },
@@ -67,15 +67,20 @@ export const checkRestricted = (
67
67
  dbObject?: any;
68
68
  debug?: boolean;
69
69
  ignoreUndefined?: boolean;
70
+ mergeRoles?: boolean;
70
71
  processType?: ProcessType;
71
72
  removeUndefinedFromResultArray?: boolean;
72
73
  throwError?: boolean;
73
74
  } = {},
74
75
  processedObjects: any[] = [],
75
76
  ) => {
77
+ // Act like Roles handling: checkObjectItself = false & mergeRoles = true
78
+ // For Input: throwError = true
79
+ // For Output: throwError = false
76
80
  const config = {
77
- checkObjectItself: true,
81
+ checkObjectItself: false,
78
82
  ignoreUndefined: true,
83
+ mergeRoles: true,
79
84
  removeUndefinedFromResultArray: true,
80
85
  throwError: true,
81
86
  ...options,
@@ -220,7 +225,8 @@ export const checkRestricted = (
220
225
 
221
226
  // Check restricted
222
227
  const restricted = getRestricted(data, propertyKey) || [];
223
- const valid = validateRestricted(restricted);
228
+ const concatenatedRestrictions = config.mergeRoles ? _.uniq(objectRestrictions.concat(restricted)) : restricted;
229
+ const valid = validateRestricted(concatenatedRestrictions);
224
230
 
225
231
  // Check rights
226
232
  if (valid) {
@@ -1,10 +1,13 @@
1
1
  import { Field, InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../decorators/restricted.decorator';
3
4
  import { LogicalOperatorEnum } from '../enums/logical-operator.enum';
5
+ import { RoleEnum } from '../enums/role.enum';
4
6
  import { maps } from '../helpers/model.helper';
5
7
  import { CoreInput } from './core-input.input';
6
8
  import { FilterInput } from './filter.input';
7
9
 
10
+ @Restricted(RoleEnum.S_EVERYONE)
8
11
  @InputType({
9
12
  description: 'Combination of multiple filters via logical operator',
10
13
  })
@@ -12,6 +15,7 @@ export class CombinedFilterInput extends CoreInput {
12
15
  /**
13
16
  * Logical Operator to combine filters
14
17
  */
18
+ @Restricted(RoleEnum.S_EVERYONE)
15
19
  @Field(type => LogicalOperatorEnum, {
16
20
  description: 'Logical Operator to combine filters',
17
21
  })
@@ -20,6 +24,7 @@ export class CombinedFilterInput extends CoreInput {
20
24
  /**
21
25
  * Filters to combine via logical operator
22
26
  */
27
+ @Restricted(RoleEnum.S_EVERYONE)
23
28
  @Field(type => [FilterInput], {
24
29
  description: 'Filters to combine via logical operator',
25
30
  })
@@ -1,5 +1,7 @@
1
1
  import { Field, InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../decorators/restricted.decorator';
4
+ import { RoleEnum } from '../enums/role.enum';
3
5
  import { CombinedFilterInput } from './combined-filter.input';
4
6
  import { CoreInput } from './core-input.input';
5
7
  import { SingleFilterInput } from './single-filter.input';
@@ -7,6 +9,7 @@ import { SingleFilterInput } from './single-filter.input';
7
9
  /**
8
10
  * Input for filtering. The `singleFilter` will be ignored if the `combinedFilter` is set.
9
11
  */
12
+ @Restricted(RoleEnum.S_EVERYONE)
10
13
  @InputType({
11
14
  description: 'Input for filtering. The `singleFilter` will be ignored if the `combinedFilter` is set.',
12
15
  })
@@ -14,6 +17,7 @@ export class FilterInput extends CoreInput {
14
17
  /**
15
18
  * Combination of multiple filters via logical operator
16
19
  */
20
+ @Restricted(RoleEnum.S_EVERYONE)
17
21
  @Field(type => CombinedFilterInput, {
18
22
  description: 'Combination of multiple filters via logical operator',
19
23
  nullable: true,
@@ -23,6 +27,7 @@ export class FilterInput extends CoreInput {
23
27
  /**
24
28
  * Filter for a single property
25
29
  */
30
+ @Restricted(RoleEnum.S_EVERYONE)
26
31
  @Field(type => SingleFilterInput, {
27
32
  description: 'Filter for a single property',
28
33
  nullable: true,
@@ -1,17 +1,21 @@
1
1
  import { Field, InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../decorators/restricted.decorator';
3
4
  import { ComparisonOperatorEnum } from '../enums/comparison-operator.enum';
5
+ import { RoleEnum } from '../enums/role.enum';
4
6
  import { JSON } from '../scalars/json.scalar';
5
7
  import { CoreInput } from './core-input.input';
6
8
 
7
9
  /**
8
10
  * Input for a configuration of a filter
9
11
  */
12
+ @Restricted(RoleEnum.S_EVERYONE)
10
13
  @InputType({ description: 'Input for a configuration of a filter' })
11
14
  export class SingleFilterInput extends CoreInput {
12
15
  /**
13
16
  * Convert value to ObjectId
14
17
  */
18
+ @Restricted(RoleEnum.S_EVERYONE)
15
19
  @Field({
16
20
  description: 'Convert value to ObjectId',
17
21
  nullable: true,
@@ -21,12 +25,14 @@ export class SingleFilterInput extends CoreInput {
21
25
  /**
22
26
  * Name of the property to be used for the filter
23
27
  */
28
+ @Restricted(RoleEnum.S_EVERYONE)
24
29
  @Field({ description: 'Name of the property to be used for the filter' })
25
30
  field: string = undefined;
26
31
 
27
32
  /**
28
33
  * Process value as reference
29
34
  */
35
+ @Restricted(RoleEnum.S_EVERYONE)
30
36
  @Field({
31
37
  description: 'Process value as reference',
32
38
  nullable: true,
@@ -36,6 +42,7 @@ export class SingleFilterInput extends CoreInput {
36
42
  /**
37
43
  * [Negate operator](https://docs.mongodb.com/manual/reference/operator/query/not/)
38
44
  */
45
+ @Restricted(RoleEnum.S_EVERYONE)
39
46
  @Field({
40
47
  description: '[Negate operator](https://docs.mongodb.com/manual/reference/operator/query/not/)',
41
48
  nullable: true,
@@ -45,6 +52,7 @@ export class SingleFilterInput extends CoreInput {
45
52
  /**
46
53
  * [Comparison operator](https://docs.mongodb.com/manual/reference/operator/query-comparison/)
47
54
  */
55
+ @Restricted(RoleEnum.S_EVERYONE)
48
56
  @Field(type => ComparisonOperatorEnum, {
49
57
  description: '[Comparison operator](https://docs.mongodb.com/manual/reference/operator/query-comparison/)',
50
58
  })
@@ -54,6 +62,7 @@ export class SingleFilterInput extends CoreInput {
54
62
  * [Options](https://docs.mongodb.com/manual/reference/operator/query/regex/#op._S_options) for
55
63
  * [REGEX](https://docs.mongodb.com/manual/reference/operator/query/regex/) operator
56
64
  */
65
+ @Restricted(RoleEnum.S_EVERYONE)
57
66
  @Field({
58
67
  description:
59
68
  '[Options](https://docs.mongodb.com/manual/reference/operator/query/regex/#op._S_options) for '
@@ -62,6 +71,7 @@ export class SingleFilterInput extends CoreInput {
62
71
  })
63
72
  options?: string = undefined;
64
73
 
74
+ @Restricted(RoleEnum.S_EVERYONE)
65
75
  @Field(type => JSON, { description: 'Value of the property' })
66
76
  value: any = undefined;
67
77
  }
@@ -1,22 +1,27 @@
1
1
  import { Field, InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../decorators/restricted.decorator';
4
+ import { RoleEnum } from '../enums/role.enum';
3
5
  import { SortOrderEnum } from '../enums/sort-order.emum';
4
6
  import { CoreInput } from './core-input.input';
5
7
 
6
8
  /**
7
9
  * Sorting the returned elements
8
10
  */
11
+ @Restricted(RoleEnum.S_EVERYONE)
9
12
  @InputType({ description: 'Sorting the returned elements' })
10
13
  export class SortInput extends CoreInput {
11
14
  /**
12
15
  * Field that is to be used for sorting
13
16
  */
17
+ @Restricted(RoleEnum.S_EVERYONE)
14
18
  @Field({ description: 'Field that is to be used for sorting' })
15
19
  field: string = undefined;
16
20
 
17
21
  /**
18
22
  * SortInput order of the field
19
23
  */
24
+ @Restricted(RoleEnum.S_EVERYONE)
20
25
  @Field(type => SortOrderEnum, { description: 'SortInput order of the field' })
21
26
  order: SortOrderEnum = undefined;
22
27
  }
@@ -4,12 +4,29 @@ import { map } from 'rxjs/operators';
4
4
 
5
5
  import { checkRestricted } from '../decorators/restricted.decorator';
6
6
  import { getContextData } from '../helpers/context.helper';
7
+ import { ConfigService } from '../services/config.service';
7
8
 
8
9
  /**
9
10
  * Interceptor to check the response data for current user
10
11
  */
11
12
  @Injectable()
12
13
  export class CheckResponseInterceptor implements NestInterceptor {
14
+ config = {
15
+ checkObjectItself: false,
16
+ debug: false,
17
+ ignoreUndefined: true,
18
+ mergeRoles: true,
19
+ removeUndefinedFromResultArray: true,
20
+ throwError: false,
21
+ };
22
+
23
+ constructor(private readonly configService: ConfigService) {
24
+ const configuration = this.configService.getFastButReadOnly('security.checkResponseInterceptor');
25
+ if (typeof configuration === 'object') {
26
+ this.config = { ...this.config, ...configuration };
27
+ }
28
+ }
29
+
13
30
  /**
14
31
  * Interception
15
32
  */
@@ -21,7 +38,7 @@ export class CheckResponseInterceptor implements NestInterceptor {
21
38
  return next.handle().pipe(
22
39
  map((data) => {
23
40
  // Prepare response data for current user
24
- return checkRestricted(data, currentUser, { throwError: false });
41
+ return checkRestricted(data, currentUser, this.config);
25
42
  }),
26
43
  );
27
44
  }
@@ -410,9 +410,47 @@ export interface IServerOptions {
410
410
  /**
411
411
  * Check restrictions for output (models and output objects)
412
412
  * See @lenne.tech/nest-server/src/core/common/interceptors/check-response.interceptor.ts
413
- * default = true
414
413
  */
415
- checkResponseInterceptor?: boolean;
414
+ checkResponseInterceptor?:
415
+ | {
416
+ /**
417
+ * Check the object itself for restrictions
418
+ * (the class restriction is not only default for properties but object itself)
419
+ * default = false (to act like Roles)
420
+ */
421
+ checkObjectItself?: boolean;
422
+
423
+ /**
424
+ * Whether to log if a restricted field is found
425
+ * default = false
426
+ */
427
+ debug?: boolean;
428
+
429
+ /**
430
+ * Whether to ignore fields with undefined values
431
+ * default = true
432
+ */
433
+ ignoreUndefined?: boolean;
434
+
435
+ /**
436
+ * Merge roles of object and properties
437
+ * default = true (to act like Roles)
438
+ */
439
+ mergeRoles?: boolean;
440
+
441
+ /**
442
+ * Remove undefined values from result array
443
+ * default = true
444
+ */
445
+ removeUndefinedFromResultArray?: boolean;
446
+
447
+ /**
448
+ * Whether to throw an error if a restricted field is found
449
+ * default = false (for output objects)
450
+ */
451
+ throwError?: boolean;
452
+ }
453
+ | boolean;
416
454
 
417
455
  /**
418
456
  * Process securityCheck() methode of Object before response
@@ -2,6 +2,8 @@ import { Field, ID, ObjectType } from '@nestjs/graphql';
2
2
  import { Prop, Schema } from '@nestjs/mongoose';
3
3
  import { Types } from 'mongoose';
4
4
 
5
+ import { Restricted } from '../decorators/restricted.decorator';
6
+ import { RoleEnum } from '../enums/role.enum';
5
7
  import { CoreModel } from './core-model.model';
6
8
 
7
9
  /**
@@ -16,6 +18,7 @@ import { CoreModel } from './core-model.model';
16
18
  * with undefined if possible. If necessary and useful, the init method can then be used deliberately:
17
19
  * const corePersistenceModel = item ? CorePersistenceModel.map(item).init() : CorePersistenceModel.init();
18
20
  */
21
+ @Restricted(RoleEnum.S_EVERYONE)
19
22
  @ObjectType({
20
23
  description: 'Persistence model which will be saved in DB',
21
24
  isAbstract: true,
@@ -26,6 +29,7 @@ export abstract class CorePersistenceModel extends CoreModel {
26
29
  // Getter
27
30
  // ===========================================================================
28
31
 
32
+ @Restricted(RoleEnum.S_EVERYONE)
29
33
  get _id() {
30
34
  return new Types.ObjectId(this.id);
31
35
  }
@@ -37,6 +41,7 @@ export abstract class CorePersistenceModel extends CoreModel {
37
41
  /**
38
42
  * ID of the persistence object as string
39
43
  */
44
+ @Restricted(RoleEnum.S_EVERYONE)
40
45
  @Field(type => ID, {
41
46
  description: 'ID of the persistence object',
42
47
  nullable: true,
@@ -46,6 +51,7 @@ export abstract class CorePersistenceModel extends CoreModel {
46
51
  /**
47
52
  * Created date, is set automatically by mongoose
48
53
  */
54
+ @Restricted(RoleEnum.S_EVERYONE)
49
55
  @Field({ description: 'Created date', nullable: true })
50
56
  @Prop({ onCreate: () => new Date() })
51
57
  createdAt: Date = undefined;
@@ -53,6 +59,7 @@ export abstract class CorePersistenceModel extends CoreModel {
53
59
  /**
54
60
  * Labels of the object
55
61
  */
62
+ @Restricted(RoleEnum.S_EVERYONE)
56
63
  @Field(type => [String], {
57
64
  description: 'Labels of the object',
58
65
  nullable: true,
@@ -63,6 +70,7 @@ export abstract class CorePersistenceModel extends CoreModel {
63
70
  /**
64
71
  * Tags for the object
65
72
  */
73
+ @Restricted(RoleEnum.S_EVERYONE)
66
74
  @Field(type => [String], {
67
75
  description: 'Tags for the object',
68
76
  nullable: true,
@@ -73,6 +81,7 @@ export abstract class CorePersistenceModel extends CoreModel {
73
81
  /**
74
82
  * Updated date is set automatically by mongoose
75
83
  */
84
+ @Restricted(RoleEnum.S_EVERYONE)
76
85
  @Field({ description: 'Updated date', nullable: true })
77
86
  @Prop({ onUpdate: () => new Date() })
78
87
  updatedAt: Date = undefined;
@@ -3,6 +3,8 @@ import { Args } from '@nestjs/graphql';
3
3
  import { Response as ResponseType } from 'express';
4
4
 
5
5
  import { CurrentUser } from '../../common/decorators/current-user.decorator';
6
+ import { Roles } from '../../common/decorators/roles.decorator';
7
+ import { RoleEnum } from '../../common/enums/role.enum';
6
8
  import { ConfigService } from '../../common/services/config.service';
7
9
  import { AuthGuardStrategy } from './auth-guard-strategy.enum';
8
10
  import { CoreAuthModel } from './core-auth.model';
@@ -13,6 +15,7 @@ import { ICoreAuthUser } from './interfaces/core-auth-user.interface';
13
15
  import { CoreAuthService } from './services/core-auth.service';
14
16
  import { Tokens } from './tokens.decorator';
15
17
 
18
+ @Roles(RoleEnum.ADMIN)
16
19
  @Controller('auth')
17
20
  export class CoreAuthController {
18
21
  /**
@@ -26,6 +29,7 @@ export class CoreAuthController {
26
29
  /**
27
30
  * Logout user (from specific device)
28
31
  */
32
+ @Roles(RoleEnum.S_EVERYONE)
29
33
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
30
34
  @Get()
31
35
  async logout(
@@ -41,6 +45,7 @@ export class CoreAuthController {
41
45
  /**
42
46
  * Refresh token (for specific device)
43
47
  */
48
+ @Roles(RoleEnum.S_EVERYONE)
44
49
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
45
50
  @Get()
46
51
  async refreshToken(
@@ -55,6 +60,7 @@ export class CoreAuthController {
55
60
  /**
56
61
  * Sign in user via email and password (on specific device)
57
62
  */
63
+ @Roles(RoleEnum.S_EVERYONE)
58
64
  @Post()
59
65
  async signIn(@Res() res: ResponseType, @Body('input') input: CoreAuthSignInInput): Promise<CoreAuthModel> {
60
66
  const result = await this.authService.signIn(input);
@@ -64,6 +70,7 @@ export class CoreAuthController {
64
70
  /**
65
71
  * Register a new user account (on specific device)
66
72
  */
73
+ @Roles(RoleEnum.S_EVERYONE)
67
74
  @Post()
68
75
  async signUp(@Res() res: ResponseType, @Args('input') input: CoreAuthSignUpInput): Promise<CoreAuthModel> {
69
76
  const result = await this.authService.signUp(input);
@@ -1,11 +1,14 @@
1
1
  import { Field, ObjectType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../../common/decorators/restricted.decorator';
4
+ import { RoleEnum } from '../../common/enums/role.enum';
3
5
  import { CoreModel } from '../../common/models/core-model.model';
4
6
  import { CoreUserModel } from '../user/core-user.model';
5
7
 
6
8
  /**
7
9
  * CoreAuth model for the response after the sign in
8
10
  */
11
+ @Restricted(RoleEnum.S_EVERYONE)
9
12
  @ObjectType({ description: 'CoreAuth', isAbstract: true })
10
13
  export class CoreAuthModel extends CoreModel {
11
14
  // ===================================================================================================================
@@ -15,18 +18,21 @@ export class CoreAuthModel extends CoreModel {
15
18
  /**
16
19
  * JavaScript Web Token (JWT)
17
20
  */
21
+ @Restricted(RoleEnum.S_EVERYONE)
18
22
  @Field({ description: 'JavaScript Web Token (JWT)', nullable: true })
19
23
  token?: string = undefined;
20
24
 
21
25
  /**
22
26
  * Refresh token
23
27
  */
28
+ @Restricted(RoleEnum.S_EVERYONE)
24
29
  @Field({ description: 'Refresh token', nullable: true })
25
30
  refreshToken?: string = undefined;
26
31
 
27
32
  /**
28
33
  * Current user
29
34
  */
35
+ @Restricted(RoleEnum.S_EVERYONE)
30
36
  @Field({ description: 'Current user' })
31
37
  user: CoreUserModel = undefined;
32
38
 
@@ -4,6 +4,8 @@ import { Response as ResponseType } from 'express';
4
4
 
5
5
  import { CurrentUser } from '../../common/decorators/current-user.decorator';
6
6
  import { GraphQLServiceOptions } from '../../common/decorators/graphql-service-options.decorator';
7
+ import { Roles } from '../../common/decorators/roles.decorator';
8
+ import { RoleEnum } from '../../common/enums/role.enum';
7
9
  import { ServiceOptions } from '../../common/interfaces/service-options.interface';
8
10
  import { ConfigService } from '../../common/services/config.service';
9
11
  import { AuthGuardStrategy } from './auth-guard-strategy.enum';
@@ -18,6 +20,7 @@ import { Tokens } from './tokens.decorator';
18
20
  /**
19
21
  * Authentication resolver for the sign in
20
22
  */
23
+ @Roles(RoleEnum.ADMIN)
21
24
  @Resolver(of => CoreAuthModel, { isAbstract: true })
22
25
  export class CoreAuthResolver {
23
26
  /**
@@ -35,6 +38,7 @@ export class CoreAuthResolver {
35
38
  /**
36
39
  * Logout user (from specific device)
37
40
  */
41
+ @Roles(RoleEnum.S_EVERYONE)
38
42
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
39
43
  @Mutation(returns => Boolean, { description: 'Logout user (from specific device)' })
40
44
  async logout(
@@ -50,6 +54,7 @@ export class CoreAuthResolver {
50
54
  /**
51
55
  * Refresh token (for specific device)
52
56
  */
57
+ @Roles(RoleEnum.S_EVERYONE)
53
58
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
54
59
  @Mutation(returns => CoreAuthModel, { description: 'Refresh tokens (for specific device)' })
55
60
  async refreshToken(
@@ -64,6 +69,7 @@ export class CoreAuthResolver {
64
69
  /**
65
70
  * Sign in user via email and password (on specific device)
66
71
  */
72
+ @Roles(RoleEnum.S_EVERYONE)
67
73
  @Mutation(returns => CoreAuthModel, {
68
74
  description: 'Sign in user via email and password and get JWT tokens (for specific device)',
69
75
  })
@@ -79,6 +85,7 @@ export class CoreAuthResolver {
79
85
  /**
80
86
  * Register a new user account (on specific device)
81
87
  */
88
+ @Roles(RoleEnum.S_EVERYONE)
82
89
  @Mutation(returns => CoreAuthModel, { description: 'Register a new user account (on specific device)' })
83
90
  async signUp(
84
91
  @GraphQLServiceOptions({ gqlPath: 'signUp.user' }) serviceOptions: ServiceOptions,
@@ -1,25 +1,32 @@
1
1
  import { Field, InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../../../common/decorators/restricted.decorator';
4
+ import { RoleEnum } from '../../../common/enums/role.enum';
3
5
  import { CoreInput } from '../../../common/inputs/core-input.input';
4
6
 
5
7
  /**
6
8
  * SignIn input
7
9
  */
10
+ @Restricted(RoleEnum.S_EVERYONE)
8
11
  @InputType({ description: 'Sign-in input' })
9
12
  export class CoreAuthSignInInput extends CoreInput {
10
13
  // ===================================================================================================================
11
14
  // Properties
12
15
  // ===================================================================================================================
13
16
 
17
+ @Restricted(RoleEnum.S_EVERYONE)
14
18
  @Field({ description: 'Device ID (is created automatically if it is not set)', nullable: true })
15
19
  deviceId?: string = undefined;
16
20
 
21
+ @Restricted(RoleEnum.S_EVERYONE)
17
22
  @Field({ description: 'Device description', nullable: true })
18
23
  deviceDescription?: string = undefined;
19
24
 
25
+ @Restricted(RoleEnum.S_EVERYONE)
20
26
  @Field({ description: 'Email', nullable: false })
21
27
  email: string = undefined;
22
28
 
29
+ @Restricted(RoleEnum.S_EVERYONE)
23
30
  @Field({ description: 'Password', nullable: false })
24
31
  password: string = undefined;
25
32
  }
@@ -1,9 +1,12 @@
1
1
  import { InputType } from '@nestjs/graphql';
2
2
 
3
+ import { Restricted } from '../../../common/decorators/restricted.decorator';
4
+ import { RoleEnum } from '../../../common/enums/role.enum';
3
5
  import { CoreAuthSignInInput } from './core-auth-sign-in.input';
4
6
 
5
7
  /**
6
8
  * SignUp input
7
9
  */
10
+ @Restricted(RoleEnum.S_EVERYONE)
8
11
  @InputType({ description: 'Sign-up input' })
9
12
  export class CoreAuthSignUpInput extends CoreAuthSignInInput {}
@@ -2,17 +2,21 @@ import { Field, ObjectType } from '@nestjs/graphql';
2
2
  import { Prop } from '@nestjs/mongoose';
3
3
  import { Types } from 'mongoose';
4
4
 
5
+ import { Restricted } from '../../common/decorators/restricted.decorator';
6
+ import { RoleEnum } from '../../common/enums/role.enum';
5
7
  import { CoreModel } from '../../common/models/core-model.model';
6
8
 
7
9
  /**
8
10
  * File info
9
11
  */
12
+ @Restricted(RoleEnum.S_EVERYONE)
10
13
  @ObjectType({ description: 'Information about file' })
11
14
  export class CoreFileInfo extends CoreModel {
12
15
  // ===========================================================================
13
16
  // Getter
14
17
  // ===========================================================================
15
18
 
19
+ @Restricted(RoleEnum.S_EVERYONE)
16
20
  get _id() {
17
21
  return new Types.ObjectId(this.id);
18
22
  }
@@ -21,9 +25,11 @@ export class CoreFileInfo extends CoreModel {
21
25
  // Properties
22
26
  // ===========================================================================
23
27
 
28
+ @Restricted(RoleEnum.S_EVERYONE)
24
29
  @Field(() => String, { description: 'ID of the file' })
25
30
  id: string = undefined;
26
31
 
32
+ @Restricted(RoleEnum.S_EVERYONE)
27
33
  @Field(() => Number, {
28
34
  description:
29
35
  'The size of each chunk in bytes. GridFS divides the document into chunks of size chunkSize, '
@@ -33,18 +39,22 @@ export class CoreFileInfo extends CoreModel {
33
39
  @Prop({ required: false, type: Number })
34
40
  chunkSize: number = undefined;
35
41
 
42
+ @Restricted(RoleEnum.S_EVERYONE)
36
43
  @Field(() => String, { description: 'Content type', nullable: true })
37
44
  @Prop({ required: false, type: String })
38
45
  contentType?: string = undefined;
39
46
 
47
+ @Restricted(RoleEnum.S_EVERYONE)
40
48
  @Field(() => String, { description: 'Name of the file', nullable: true })
41
49
  @Prop({ required: false, type: String })
42
50
  filename?: string = undefined;
43
51
 
52
+ @Restricted(RoleEnum.S_EVERYONE)
44
53
  @Field(() => Number, { description: 'The size of the document in bytes', nullable: true })
45
54
  @Prop({ required: false, type: Number })
46
55
  length: number = undefined;
47
56
 
57
+ @Restricted(RoleEnum.S_EVERYONE)
48
58
  @Field(() => Date, { description: 'The date the file was first stored', nullable: true })
49
59
  @Prop({ required: false, type: Date })
50
60
  uploadDate: Date = undefined;
@@ -1,10 +1,13 @@
1
1
  import { BadRequestException, Controller, Get, NotFoundException, Param, Res } from '@nestjs/common';
2
2
 
3
+ import { Roles } from '../../common/decorators/roles.decorator';
4
+ import { RoleEnum } from '../../common/enums/role.enum';
3
5
  import { CoreFileService } from './core-file.service';
4
6
 
5
7
  /**
6
8
  * File controller
7
9
  */
10
+ @Roles(RoleEnum.ADMIN)
8
11
  @Controller('files')
9
12
  export abstract class CoreFileController {
10
13
  /**
@@ -15,6 +18,7 @@ export abstract class CoreFileController {
15
18
  /**
16
19
  * Download file
17
20
  */
21
+ @Roles(RoleEnum.S_EVERYONE)
18
22
  @Get(':filename')
19
23
  async getFile(@Param('filename') filename: string, @Res() res) {
20
24
  if (!filename) {