@lenne.tech/nest-server 10.0.2 → 10.0.4

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 (219) hide show
  1. package/README.md +9 -0
  2. package/dist/config.env.js +47 -17
  3. package/dist/config.env.js.map +1 -1
  4. package/dist/core/common/args/filter.args.js +3 -3
  5. package/dist/core/common/args/filter.args.js.map +1 -1
  6. package/dist/core/common/args/pagination.args.js +6 -6
  7. package/dist/core/common/args/pagination.args.js.map +1 -1
  8. package/dist/core/common/decorators/restricted.decorator.js +15 -17
  9. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  10. package/dist/core/common/filters/http-exception-log.filter.js +1 -3
  11. package/dist/core/common/filters/http-exception-log.filter.js.map +1 -1
  12. package/dist/core/common/helpers/db.helper.js +14 -14
  13. package/dist/core/common/helpers/db.helper.js.map +1 -1
  14. package/dist/core/common/helpers/file.helper.js +2 -2
  15. package/dist/core/common/helpers/file.helper.js.map +1 -1
  16. package/dist/core/common/helpers/filter.helper.d.ts +2 -2
  17. package/dist/core/common/helpers/filter.helper.js +1 -1
  18. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  19. package/dist/core/common/helpers/graphql.helper.js +1 -1
  20. package/dist/core/common/helpers/graphql.helper.js.map +1 -1
  21. package/dist/core/common/helpers/input.helper.js +31 -38
  22. package/dist/core/common/helpers/input.helper.js.map +1 -1
  23. package/dist/core/common/helpers/model.helper.js +7 -7
  24. package/dist/core/common/helpers/model.helper.js.map +1 -1
  25. package/dist/core/common/helpers/service.helper.js +2 -2
  26. package/dist/core/common/helpers/service.helper.js.map +1 -1
  27. package/dist/core/common/inputs/combined-filter.input.js +3 -3
  28. package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
  29. package/dist/core/common/inputs/core-input.input.js +1 -1
  30. package/dist/core/common/inputs/core-input.input.js.map +1 -1
  31. package/dist/core/common/inputs/filter.input.js +3 -3
  32. package/dist/core/common/inputs/filter.input.js.map +1 -1
  33. package/dist/core/common/inputs/single-filter.input.js +4 -4
  34. package/dist/core/common/inputs/single-filter.input.js.map +1 -1
  35. package/dist/core/common/inputs/sort.input.js +1 -1
  36. package/dist/core/common/inputs/sort.input.js.map +1 -1
  37. package/dist/core/common/interceptors/check-security.interceptor.d.ts +1 -1
  38. package/dist/core/common/interceptors/check-security.interceptor.js +2 -2
  39. package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
  40. package/dist/core/common/interfaces/server-options.interface.d.ts +28 -0
  41. package/dist/core/common/models/core-model.model.js.map +1 -1
  42. package/dist/core/common/models/core-persistence.model.js +3 -3
  43. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  44. package/dist/core/common/pipes/map-and-validate.pipe.d.ts +1 -1
  45. package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
  46. package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
  47. package/dist/core/common/scalars/any.scalar.js +2 -2
  48. package/dist/core/common/scalars/any.scalar.js.map +1 -1
  49. package/dist/core/common/scalars/date-timestamp.scalar.js +1 -1
  50. package/dist/core/common/scalars/date-timestamp.scalar.js.map +1 -1
  51. package/dist/core/common/scalars/date.scalar.js +1 -1
  52. package/dist/core/common/scalars/date.scalar.js.map +1 -1
  53. package/dist/core/common/scalars/json.scalar.js +2 -2
  54. package/dist/core/common/scalars/json.scalar.js.map +1 -1
  55. package/dist/core/common/services/config.service.js +7 -7
  56. package/dist/core/common/services/config.service.js.map +1 -1
  57. package/dist/core/common/services/core-cron-jobs.service.js +5 -5
  58. package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
  59. package/dist/core/common/services/crud.service.js +1 -1
  60. package/dist/core/common/services/crud.service.js.map +1 -1
  61. package/dist/core/common/services/mailjet.service.js +5 -5
  62. package/dist/core/common/services/mailjet.service.js.map +1 -1
  63. package/dist/core/common/services/model-doc.service.d.ts +16 -0
  64. package/dist/core/common/services/model-doc.service.js +107 -0
  65. package/dist/core/common/services/model-doc.service.js.map +1 -0
  66. package/dist/core/common/services/module.service.js.map +1 -1
  67. package/dist/core/common/services/template.service.js +3 -3
  68. package/dist/core/common/services/template.service.js.map +1 -1
  69. package/dist/core/common/types/core-model-constructor.type.d.ts +2 -2
  70. package/dist/core/modules/auth/core-auth.module.js +3 -3
  71. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  72. package/dist/core/modules/auth/core-auth.resolver.js +5 -5
  73. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  74. package/dist/core/modules/auth/guards/auth.guard.js +4 -4
  75. package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
  76. package/dist/core/modules/auth/guards/roles.guard.js +1 -1
  77. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  78. package/dist/core/modules/auth/services/core-auth.service.js +5 -5
  79. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  80. package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
  81. package/dist/core/modules/auth/tokens.decorator.js +2 -2
  82. package/dist/core/modules/auth/tokens.decorator.js.map +1 -1
  83. package/dist/core/modules/file/core-file-info.model.js +2 -2
  84. package/dist/core/modules/file/core-file-info.model.js.map +1 -1
  85. package/dist/core/modules/file/core-file.controller.d.ts +1 -2
  86. package/dist/core/modules/file/core-file.controller.js +3 -6
  87. package/dist/core/modules/file/core-file.controller.js.map +1 -1
  88. package/dist/core/modules/file/core-file.service.js +1 -1
  89. package/dist/core/modules/file/core-file.service.js.map +1 -1
  90. package/dist/core/modules/file/interfaces/file-upload.interface.d.ts +1 -1
  91. package/dist/core/modules/health-check/core-health-check-result.model.d.ts +8 -0
  92. package/dist/core/modules/health-check/core-health-check-result.model.js +53 -0
  93. package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -0
  94. package/dist/core/modules/health-check/core-health-check.controller.d.ts +6 -0
  95. package/dist/core/modules/health-check/core-health-check.controller.js +33 -0
  96. package/dist/core/modules/health-check/core-health-check.controller.js.map +1 -0
  97. package/dist/core/modules/health-check/core-health-check.module.d.ts +2 -0
  98. package/dist/core/modules/health-check/core-health-check.module.js +24 -0
  99. package/dist/core/modules/health-check/core-health-check.module.js.map +1 -0
  100. package/dist/core/modules/health-check/core-health-check.resolver.d.ts +6 -0
  101. package/dist/core/modules/health-check/core-health-check.resolver.js +38 -0
  102. package/dist/core/modules/health-check/core-health-check.resolver.js.map +1 -0
  103. package/dist/core/modules/health-check/core-health-check.service.d.ts +11 -0
  104. package/dist/core/modules/health-check/core-health-check.service.js +52 -0
  105. package/dist/core/modules/health-check/core-health-check.service.js.map +1 -0
  106. package/dist/core/modules/user/core-user.model.js +5 -5
  107. package/dist/core/modules/user/core-user.model.js.map +1 -1
  108. package/dist/core/modules/user/core-user.service.js +2 -2
  109. package/dist/core/modules/user/core-user.service.js.map +1 -1
  110. package/dist/core/modules/user/inputs/core-user.input.js +1 -1
  111. package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
  112. package/dist/core.module.js +14 -5
  113. package/dist/core.module.js.map +1 -1
  114. package/dist/index.d.ts +6 -0
  115. package/dist/index.js +6 -0
  116. package/dist/index.js.map +1 -1
  117. package/dist/main.js +1 -1
  118. package/dist/main.js.map +1 -1
  119. package/dist/server/modules/auth/auth.service.js +1 -1
  120. package/dist/server/modules/auth/auth.service.js.map +1 -1
  121. package/dist/server/modules/file/file.controller.js +1 -1
  122. package/dist/server/modules/file/file.controller.js.map +1 -1
  123. package/dist/server/modules/file/file.resolver.js +2 -2
  124. package/dist/server/modules/file/file.resolver.js.map +1 -1
  125. package/dist/server/modules/file/file.service.js +1 -1
  126. package/dist/server/modules/file/file.service.js.map +1 -1
  127. package/dist/server/modules/file/multer-config.service.js +1 -1
  128. package/dist/server/modules/file/multer-config.service.js.map +1 -1
  129. package/dist/server/modules/user/avatar.controller.js +1 -1
  130. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  131. package/dist/server/modules/user/user.resolver.js +1 -1
  132. package/dist/server/modules/user/user.resolver.js.map +1 -1
  133. package/dist/server/modules/user/user.service.js +3 -3
  134. package/dist/server/modules/user/user.service.js.map +1 -1
  135. package/dist/templates/index.ejs +2 -0
  136. package/dist/templates/password-reset.ejs +3 -0
  137. package/dist/templates/welcome.ejs +3 -0
  138. package/dist/test/test.helper.d.ts +1 -1
  139. package/dist/test/test.helper.js +7 -7
  140. package/dist/test/test.helper.js.map +1 -1
  141. package/dist/tsconfig.build.tsbuildinfo +1 -1
  142. package/package.json +32 -26
  143. package/src/config.env.ts +50 -20
  144. package/src/core/common/args/filter.args.ts +4 -4
  145. package/src/core/common/args/pagination.args.ts +7 -7
  146. package/src/core/common/decorators/graphql-service-options.decorator.ts +2 -2
  147. package/src/core/common/decorators/graphql-user.decorator.ts +1 -1
  148. package/src/core/common/decorators/rest-user.decorator.ts +1 -1
  149. package/src/core/common/decorators/restricted.decorator.ts +18 -18
  150. package/src/core/common/filters/http-exception-log.filter.ts +4 -4
  151. package/src/core/common/helpers/db.helper.ts +35 -40
  152. package/src/core/common/helpers/decorator.helper.ts +1 -1
  153. package/src/core/common/helpers/file.helper.ts +2 -2
  154. package/src/core/common/helpers/filter.helper.ts +7 -8
  155. package/src/core/common/helpers/graphql.helper.ts +6 -6
  156. package/src/core/common/helpers/input.helper.ts +54 -61
  157. package/src/core/common/helpers/model.helper.ts +33 -41
  158. package/src/core/common/helpers/service.helper.ts +8 -8
  159. package/src/core/common/inputs/combined-filter.input.ts +4 -4
  160. package/src/core/common/inputs/core-input.input.ts +2 -2
  161. package/src/core/common/inputs/filter.input.ts +4 -4
  162. package/src/core/common/inputs/single-filter.input.ts +4 -4
  163. package/src/core/common/inputs/sort.input.ts +1 -1
  164. package/src/core/common/interceptors/check-response.interceptor.ts +1 -1
  165. package/src/core/common/interceptors/check-security.interceptor.ts +5 -5
  166. package/src/core/common/interfaces/server-options.interface.ts +109 -0
  167. package/src/core/common/models/core-model.model.ts +6 -4
  168. package/src/core/common/models/core-persistence.model.ts +3 -3
  169. package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
  170. package/src/core/common/scalars/any.scalar.ts +2 -2
  171. package/src/core/common/scalars/date-timestamp.scalar.ts +1 -2
  172. package/src/core/common/scalars/date.scalar.ts +1 -2
  173. package/src/core/common/scalars/json.scalar.ts +4 -4
  174. package/src/core/common/services/config.service.ts +16 -16
  175. package/src/core/common/services/core-cron-jobs.service.ts +7 -7
  176. package/src/core/common/services/crud.service.ts +22 -22
  177. package/src/core/common/services/email.service.ts +1 -1
  178. package/src/core/common/services/mailjet.service.ts +8 -8
  179. package/src/core/common/services/model-doc.service.ts +140 -0
  180. package/src/core/common/services/module.service.ts +5 -6
  181. package/src/core/common/services/template.service.ts +4 -4
  182. package/src/core/common/types/core-model-constructor.type.ts +2 -2
  183. package/src/core/modules/auth/core-auth.controller.ts +2 -2
  184. package/src/core/modules/auth/core-auth.module.ts +4 -4
  185. package/src/core/modules/auth/core-auth.resolver.ts +9 -9
  186. package/src/core/modules/auth/guards/auth.guard.ts +8 -7
  187. package/src/core/modules/auth/guards/roles.guard.ts +1 -1
  188. package/src/core/modules/auth/services/core-auth.service.ts +9 -9
  189. package/src/core/modules/auth/strategies/jwt-refresh.strategy.ts +1 -1
  190. package/src/core/modules/auth/strategies/jwt.strategy.ts +1 -1
  191. package/src/core/modules/auth/tokens.decorator.ts +6 -7
  192. package/src/core/modules/file/core-file-info.model.ts +2 -2
  193. package/src/core/modules/file/core-file.controller.ts +2 -4
  194. package/src/core/modules/file/core-file.service.ts +6 -5
  195. package/src/core/modules/file/interfaces/file-upload.interface.ts +1 -1
  196. package/src/core/modules/health-check/core-health-check-result.model.ts +46 -0
  197. package/src/core/modules/health-check/core-health-check.controller.ts +24 -0
  198. package/src/core/modules/health-check/core-health-check.module.ts +17 -0
  199. package/src/core/modules/health-check/core-health-check.resolver.ts +32 -0
  200. package/src/core/modules/health-check/core-health-check.service.ts +62 -0
  201. package/src/core/modules/user/core-user.model.ts +6 -6
  202. package/src/core/modules/user/core-user.service.ts +10 -9
  203. package/src/core/modules/user/inputs/core-user.input.ts +1 -2
  204. package/src/core.module.ts +23 -12
  205. package/src/index.ts +11 -0
  206. package/src/main.ts +2 -2
  207. package/src/server/modules/auth/auth.controller.ts +1 -1
  208. package/src/server/modules/auth/auth.resolver.ts +3 -3
  209. package/src/server/modules/auth/auth.service.ts +2 -2
  210. package/src/server/modules/file/file.controller.ts +1 -2
  211. package/src/server/modules/file/file.module.ts +1 -1
  212. package/src/server/modules/file/file.resolver.ts +4 -3
  213. package/src/server/modules/file/file.service.ts +1 -1
  214. package/src/server/modules/file/multer-config.service.ts +1 -1
  215. package/src/server/modules/user/avatar.controller.ts +3 -3
  216. package/src/server/modules/user/user.model.ts +1 -1
  217. package/src/server/modules/user/user.resolver.ts +4 -4
  218. package/src/server/modules/user/user.service.ts +4 -4
  219. package/src/test/test.helper.ts +11 -11
@@ -28,7 +28,7 @@ export class CoreAuthController {
28
28
  @CurrentUser() currentUser: ICoreAuthUser,
29
29
  @Tokens('token') token: string,
30
30
  @Res() res: ResponseType,
31
- @Param('allDevices', ParseBoolPipe) allDevices?: boolean
31
+ @Param('allDevices', ParseBoolPipe) allDevices?: boolean,
32
32
  ): Promise<boolean> {
33
33
  const result = await this.authService.logout(token, { currentUser, allDevices });
34
34
  return this.processCookies(res, result);
@@ -42,7 +42,7 @@ export class CoreAuthController {
42
42
  async refreshToken(
43
43
  @CurrentUser() user: ICoreAuthUser,
44
44
  @Tokens('refreshToken') refreshToken: string,
45
- @Res() res: ResponseType
45
+ @Res() res: ResponseType,
46
46
  ): Promise<CoreAuthModel> {
47
47
  const result = await this.authService.refreshTokens(user, refreshToken);
48
48
  return this.processCookies(res, result);
@@ -2,13 +2,13 @@ import { DynamicModule, ForwardReference, Module, Provider, Type } from '@nestjs
2
2
  import { APP_GUARD } from '@nestjs/core';
3
3
  import { JwtModule, JwtModuleOptions } from '@nestjs/jwt';
4
4
  import { PassportModule } from '@nestjs/passport';
5
+ import { PubSub } from 'graphql-subscriptions';
5
6
  import { AuthGuardStrategy } from './auth-guard-strategy.enum';
6
7
  import { RolesGuard } from './guards/roles.guard';
7
8
  import { JwtRefreshStrategy } from './strategies/jwt-refresh.strategy';
8
9
  import { JwtStrategy } from './strategies/jwt.strategy';
9
10
  import { CoreAuthUserService } from './services/core-auth-user.service';
10
11
  import { CoreAuthService } from './services/core-auth.service';
11
- import { PubSub } from 'graphql-subscriptions';
12
12
 
13
13
  /**
14
14
  * CoreAuthModule to handle user authentication and enables Roles
@@ -28,7 +28,7 @@ export class CoreAuthModule {
28
28
  jwtRefreshStrategy?: Type<JwtRefreshStrategy>;
29
29
  imports?: Array<Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
30
30
  providers?: Provider[];
31
- }
31
+ },
32
32
  ): DynamicModule {
33
33
  // Process imports
34
34
  let imports: any[] = [
@@ -75,8 +75,8 @@ export class CoreAuthModule {
75
75
  // Return CoreAuthModule
76
76
  return {
77
77
  module: CoreAuthModule,
78
- imports: imports,
79
- providers: providers,
78
+ imports,
79
+ providers,
80
80
  exports: [CoreAuthService, JwtModule, JwtStrategy, JwtRefreshStrategy, PassportModule, UserModule],
81
81
  };
82
82
  }
@@ -17,7 +17,7 @@ import { Tokens } from './tokens.decorator';
17
17
  /**
18
18
  * Authentication resolver for the sign in
19
19
  */
20
- @Resolver((of) => CoreAuthModel, { isAbstract: true })
20
+ @Resolver(of => CoreAuthModel, { isAbstract: true })
21
21
  export class CoreAuthResolver {
22
22
  /**
23
23
  * Import services
@@ -32,12 +32,12 @@ export class CoreAuthResolver {
32
32
  * Logout user (from specific device)
33
33
  */
34
34
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
35
- @Mutation((returns) => Boolean, { description: 'Logout user (from specific device)' })
35
+ @Mutation(returns => Boolean, { description: 'Logout user (from specific device)' })
36
36
  async logout(
37
37
  @CurrentUser() currentUser: ICoreAuthUser,
38
38
  @Context() ctx: { res: ResponseType },
39
39
  @Tokens('token') token: string,
40
- @Args('allDevices', { nullable: true }) allDevices?: boolean
40
+ @Args('allDevices', { nullable: true }) allDevices?: boolean,
41
41
  ): Promise<boolean> {
42
42
  const result = await this.authService.logout(token, { currentUser, allDevices });
43
43
  return this.processCookies(ctx, result);
@@ -47,11 +47,11 @@ export class CoreAuthResolver {
47
47
  * Refresh token (for specific device)
48
48
  */
49
49
  @UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
50
- @Mutation((returns) => CoreAuthModel, { description: 'Refresh tokens (for specific device)' })
50
+ @Mutation(returns => CoreAuthModel, { description: 'Refresh tokens (for specific device)' })
51
51
  async refreshToken(
52
52
  @CurrentUser() user: ICoreAuthUser,
53
53
  @Tokens('refreshToken') refreshToken: string,
54
- @Context() ctx: { res: ResponseType }
54
+ @Context() ctx: { res: ResponseType },
55
55
  ): Promise<CoreAuthModel> {
56
56
  const result = await this.authService.refreshTokens(user, refreshToken);
57
57
  return this.processCookies(ctx, result);
@@ -60,13 +60,13 @@ export class CoreAuthResolver {
60
60
  /**
61
61
  * Sign in user via email and password (on specific device)
62
62
  */
63
- @Mutation((returns) => CoreAuthModel, {
63
+ @Mutation(returns => CoreAuthModel, {
64
64
  description: 'Sign in user via email and password and get JWT tokens (for specific device)',
65
65
  })
66
66
  async signIn(
67
67
  @GraphQLServiceOptions({ gqlPath: 'signIn.user' }) serviceOptions: ServiceOptions,
68
68
  @Context() ctx: { res: ResponseType },
69
- @Args('input') input: CoreAuthSignInInput
69
+ @Args('input') input: CoreAuthSignInInput,
70
70
  ): Promise<CoreAuthModel> {
71
71
  const result = await this.authService.signIn(input, serviceOptions);
72
72
  return this.processCookies(ctx, result);
@@ -75,11 +75,11 @@ export class CoreAuthResolver {
75
75
  /**
76
76
  * Register a new user account (on specific device)
77
77
  */
78
- @Mutation((returns) => CoreAuthModel, { description: 'Register a new user account (on specific device)' })
78
+ @Mutation(returns => CoreAuthModel, { description: 'Register a new user account (on specific device)' })
79
79
  async signUp(
80
80
  @GraphQLServiceOptions({ gqlPath: 'signUp.user' }) serviceOptions: ServiceOptions,
81
81
  @Context() ctx: { res: ResponseType },
82
- @Args('input') input: CoreAuthSignUpInput
82
+ @Args('input') input: CoreAuthSignUpInput,
83
83
  ): Promise<CoreAuthModel> {
84
84
  const result = await this.authService.signUp(input, serviceOptions);
85
85
  return this.processCookies(ctx, result);
@@ -1,4 +1,4 @@
1
- import { CanActivate, ExecutionContext, Logger, mixin, Optional } from '@nestjs/common';
1
+ import { CanActivate, ExecutionContext, Logger, Optional, mixin } from '@nestjs/common';
2
2
  import { GqlExecutionContext } from '@nestjs/graphql';
3
3
  import { AuthModuleOptions, Type } from '@nestjs/passport';
4
4
  import { defaultOptions } from '@nestjs/passport/dist/options';
@@ -12,9 +12,9 @@ import { InvalidTokenException } from '../exceptions/invalid-token.exception';
12
12
  /**
13
13
  * Missing strategy error
14
14
  */
15
- const NO_STRATEGY_ERROR =
16
- 'In order to use "defaultStrategy", please, ensure to import PassportModule in each ' +
17
- "place where AuthGuard() is being used. Otherwise, passport won't work correctly.";
15
+ const NO_STRATEGY_ERROR
16
+ = 'In order to use "defaultStrategy", please, ensure to import PassportModule in each '
17
+ + 'place where AuthGuard() is being used. Otherwise, passport won\'t work correctly.';
18
18
 
19
19
  /**
20
20
  * Interface for auth guard
@@ -37,7 +37,7 @@ const createPassportContext = (request, response) => (type, options, callback: (
37
37
  } catch (err) {
38
38
  reject(err);
39
39
  }
40
- })(request, response, (err) => (err ? reject(err) : resolve))
40
+ })(request, response, err => (err ? reject(err) : resolve)),
41
41
  );
42
42
 
43
43
  /**
@@ -73,7 +73,7 @@ function createAuthGuard(type?: string): Type<CanActivate> {
73
73
  const request = this.getRequest(context);
74
74
  const passportFn = createPassportContext(request, response);
75
75
  const user = await passportFn(type || this.options.defaultStrategy, options, (err, currentUser, info) =>
76
- this.handleRequest(err, currentUser, info, context)
76
+ this.handleRequest(err, currentUser, info, context),
77
77
  );
78
78
  request[options.property || defaultOptions.property] = user;
79
79
  return true;
@@ -100,12 +100,13 @@ function createAuthGuard(type?: string): Type<CanActivate> {
100
100
  */
101
101
  async logIn<TRequest extends { logIn: (...params) => any } = any>(request: TRequest) {
102
102
  const user = request[this.options.property || defaultOptions.property];
103
- await new Promise<void>((resolve, reject) => request.logIn(user, (err) => (err ? reject(err) : resolve())));
103
+ await new Promise<void>((resolve, reject) => request.logIn(user, err => (err ? reject(err) : resolve())));
104
104
  }
105
105
 
106
106
  /**
107
107
  * Process request
108
108
  */
109
+ // eslint-disable-next-line unused-imports/no-unused-vars
109
110
  handleRequest(err, user, info, context): TUser {
110
111
  if (err) {
111
112
  throw new InvalidTokenException();
@@ -41,7 +41,7 @@ export class RolesGuard extends AuthGuard(AuthGuardStrategy.JWT) {
41
41
  }
42
42
 
43
43
  // Check roles
44
- if (!roles || !roles.some((value) => !!value)) {
44
+ if (!roles || !roles.some(value => !!value)) {
45
45
  return user;
46
46
  }
47
47
 
@@ -1,7 +1,7 @@
1
+ import { randomUUID } from 'crypto';
1
2
  import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
2
3
  import { JwtService } from '@nestjs/jwt';
3
4
  import bcrypt = require('bcrypt');
4
- import { randomUUID } from 'crypto';
5
5
  import { sha256 } from 'js-sha256';
6
6
  import { getStringIds } from '../../../common/helpers/db.helper';
7
7
  import { prepareServiceOptions } from '../../../common/helpers/service.helper';
@@ -25,7 +25,7 @@ export class CoreAuthService {
25
25
  constructor(
26
26
  protected readonly userService: CoreAuthUserService,
27
27
  protected readonly jwtService: JwtService,
28
- protected readonly configService: ConfigService
28
+ protected readonly configService: ConfigService,
29
29
  ) {}
30
30
 
31
31
  /**
@@ -40,7 +40,7 @@ export class CoreAuthService {
40
40
  */
41
41
  async logout(
42
42
  tokenOrRefreshToken: string,
43
- serviceOptions: ServiceOptions & { allDevices?: boolean }
43
+ serviceOptions: ServiceOptions & { allDevices?: boolean },
44
44
  ): Promise<boolean> {
45
45
  // Check authentication
46
46
  const user = serviceOptions.currentUser;
@@ -162,7 +162,7 @@ export class CoreAuthService {
162
162
  protected async getResult(
163
163
  user: ICoreAuthUser,
164
164
  data?: { [key: string]: any; deviceId?: string },
165
- currentRefreshToken?: string
165
+ currentRefreshToken?: string,
166
166
  ) {
167
167
  // Create new tokens
168
168
  const tokens = await this.createTokens(user.id, data);
@@ -186,10 +186,10 @@ export class CoreAuthService {
186
186
  path += '.refresh';
187
187
  }
188
188
  return (
189
- this.configService.getFastButReadOnly(path + '.signInOptions.secret') ||
190
- this.configService.getFastButReadOnly(path + '.signInOptions.secretOrPrivateKey') ||
191
- this.configService.getFastButReadOnly(path + '.secret') ||
192
- this.configService.getFastButReadOnly(path + '.secretOrPrivateKey')
189
+ this.configService.getFastButReadOnly(`${path}.signInOptions.secret`)
190
+ || this.configService.getFastButReadOnly(`${path}.signInOptions.secretOrPrivateKey`)
191
+ || this.configService.getFastButReadOnly(`${path}.secret`)
192
+ || this.configService.getFastButReadOnly(`${path}.secretOrPrivateKey`)
193
193
  );
194
194
  }
195
195
 
@@ -226,7 +226,7 @@ export class CoreAuthService {
226
226
  user: ICoreAuthUser,
227
227
  currentRefreshToken: string,
228
228
  newRefreshToken: string,
229
- data?: Record<string, any>
229
+ data?: Record<string, any>,
230
230
  ): Promise<string> {
231
231
  // Check if the update of the update token is allowed
232
232
  let deviceId: string;
@@ -1,6 +1,6 @@
1
1
  import { Injectable, UnauthorizedException } from '@nestjs/common';
2
2
  import { PassportStrategy } from '@nestjs/passport';
3
- import { Request as RequestType, Request } from 'express';
3
+ import { Request, Request as RequestType } from 'express';
4
4
  import { ExtractJwt, Strategy } from 'passport-jwt';
5
5
  import { ConfigService } from '../../../common/services/config.service';
6
6
  import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
@@ -1,11 +1,11 @@
1
1
  import { Injectable, UnauthorizedException } from '@nestjs/common';
2
2
  import { PassportStrategy } from '@nestjs/passport';
3
3
  import { ExtractJwt, Strategy } from 'passport-jwt';
4
+ import { Request as RequestType } from 'express';
4
5
  import { ConfigService } from '../../../common/services/config.service';
5
6
  import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
6
7
  import { JwtPayload } from '../interfaces/jwt-payload.interface';
7
8
  import { CoreAuthService } from '../services/core-auth.service';
8
- import { Request as RequestType } from 'express';
9
9
 
10
10
  /**
11
11
  * Use JWT strategy for passport
@@ -1,5 +1,4 @@
1
- import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
- import { GqlExecutionContext } from '@nestjs/graphql';
1
+ import { ExecutionContext, createParamDecorator } from '@nestjs/common';
3
2
  import { getContextData } from '../../common/helpers/context.helper';
4
3
 
5
4
  /**
@@ -8,15 +7,15 @@ import { getContextData } from '../../common/helpers/context.helper';
8
7
  export const Tokens = createParamDecorator(
9
8
  (
10
9
  tokenId: 'token' | 'refreshToken' | undefined,
11
- ctx: ExecutionContext
10
+ ctx: ExecutionContext,
12
11
  ): string | { token: string; refreshToken: string } => {
13
12
  // Get prepared context (REST or GraphQL)
14
13
  const context = getContextData(ctx);
15
14
 
16
15
  // Get token from cookie or authorization header
17
- const token =
18
- context?.request?.cookies?.['token'] ||
19
- context?.request
16
+ const token
17
+ = context?.request?.cookies?.['token']
18
+ || context?.request
20
19
  ?.get('Authorization')
21
20
  ?.replace(/bearer/i, '')
22
21
  .trim();
@@ -32,5 +31,5 @@ export const Tokens = createParamDecorator(
32
31
  return tokens[tokenId];
33
32
  }
34
33
  return tokens;
35
- }
34
+ },
36
35
  );
@@ -25,8 +25,8 @@ export class CoreFileInfo extends CoreModel {
25
25
 
26
26
  @Field(() => Number, {
27
27
  description:
28
- 'The size of each chunk in bytes. GridFS divides the document into chunks of size chunkSize, ' +
29
- 'except for the last, which is only as large as needed. The default size is 255 kilobytes (kB)',
28
+ 'The size of each chunk in bytes. GridFS divides the document into chunks of size chunkSize, '
29
+ + 'except for the last, which is only as large as needed. The default size is 255 kilobytes (kB)',
30
30
  nullable: true,
31
31
  })
32
32
  @Prop({ type: Number, required: false })
@@ -1,6 +1,4 @@
1
1
  import { BadRequestException, Controller, Get, NotFoundException, Param, Res } from '@nestjs/common';
2
- import { CurrentUser } from '../../common/decorators/current-user.decorator';
3
- import { CoreUserModel } from '../user/core-user.model';
4
2
  import { CoreFileService } from './core-file.service';
5
3
 
6
4
  /**
@@ -17,7 +15,7 @@ export abstract class CoreFileController {
17
15
  * Download file
18
16
  */
19
17
  @Get(':filename')
20
- async getFile(@Param('filename') filename: string, @Res() res, @CurrentUser() user: CoreUserModel) {
18
+ async getFile(@Param('filename') filename: string, @Res() res) {
21
19
  if (!filename) {
22
20
  throw new BadRequestException('Missing filename for download');
23
21
  }
@@ -28,7 +26,7 @@ export abstract class CoreFileController {
28
26
  }
29
27
  const filestream = await this.fileService.getFileStream(file.id);
30
28
  res.header('Content-Type', file.contentType);
31
- res.header('Content-Disposition', 'attachment; filename=' + file.filename);
29
+ res.header('Content-Disposition', `attachment; filename=${file.filename}`);
32
30
  return filestream.pipe(res);
33
31
  }
34
32
  }
@@ -1,7 +1,7 @@
1
1
  import { NotFoundException } from '@nestjs/common';
2
2
  import { GridFSBucket, GridFSBucketReadStream, GridFSBucketReadStreamOptions } from 'mongodb';
3
3
  import { Connection, Types } from 'mongoose';
4
- import { createBucket, MongoGridFSOptions, MongooseGridFS } from 'mongoose-gridfs';
4
+ import { MongoGridFSOptions, MongooseGridFS, createBucket } from 'mongoose-gridfs';
5
5
  import { FilterArgs } from '../../common/args/filter.args';
6
6
  import { getObjectIds, getStringIds } from '../../common/helpers/db.helper';
7
7
  import { convertFilterArgsToQuery } from '../../common/helpers/filter.helper';
@@ -38,6 +38,7 @@ export abstract class CoreFileService {
38
38
  return null;
39
39
  }
40
40
  return await new Promise(async (resolve, reject) => {
41
+ // eslint-disable-next-line unused-imports/no-unused-vars
41
42
  const { filename, mimetype, encoding, createReadStream } = await file;
42
43
  const readStream = createReadStream();
43
44
  const options: MongoGridFSOptions = { filename, contentType: mimetype };
@@ -123,7 +124,7 @@ export abstract class CoreFileService {
123
124
  */
124
125
  async getFileStreamByName(
125
126
  filename: string,
126
- serviceOptions?: FileServiceOptions
127
+ serviceOptions?: FileServiceOptions,
127
128
  ): Promise<GridFSBucketReadStreamOptions> {
128
129
  if (!(await this.checkRights(filename, { ...serviceOptions, checkInputType: 'filename' }))) {
129
130
  return null;
@@ -182,7 +183,7 @@ export abstract class CoreFileService {
182
183
  }
183
184
  const fileInfo = await this.getFileInfoByName(filename);
184
185
  if (!fileInfo) {
185
- throw new NotFoundException('File not found with filename ' + filename);
186
+ throw new NotFoundException(`File not found with filename ${filename}`);
186
187
  }
187
188
  return await this.deleteFile(fileInfo.id, serviceOptions);
188
189
  }
@@ -196,8 +197,8 @@ export abstract class CoreFileService {
196
197
  * Can throw an exception if the rights do not fit
197
198
  */
198
199
  protected checkRights(
199
- input: any,
200
- options?: FileServiceOptions & { checkInputType: FileInputCheckType }
200
+ input: any, // eslint-disable-line unused-imports/no-unused-vars
201
+ options?: FileServiceOptions & { checkInputType: FileInputCheckType }, // eslint-disable-line unused-imports/no-unused-vars
201
202
  ): MaybePromise<boolean> {
202
203
  return true;
203
204
  }
@@ -1,5 +1,5 @@
1
- import { WriteStream } from 'fs-capacitor';
2
1
  import { Readable } from 'stream';
2
+ import { WriteStream } from 'fs-capacitor';
3
3
 
4
4
  /**
5
5
  * Interface for file uploads
@@ -0,0 +1,46 @@
1
+ import { Field, ObjectType } from '@nestjs/graphql';
2
+ import { CoreModel } from '../../common/models/core-model.model';
3
+ import { JSON } from '../../common/scalars/json.scalar';
4
+
5
+ /**
6
+ * User model
7
+ */
8
+ @ObjectType({ description: 'Health check result' })
9
+ export abstract class CoreHealthCheckResult extends CoreModel {
10
+ // ===================================================================================================================
11
+ // Properties
12
+ // ===================================================================================================================
13
+
14
+ /**
15
+ * The overall status of the Health Check
16
+ */
17
+ @Field({ description: 'The overall status of the Health Check', nullable: false })
18
+ status: 'error' | 'ok' | 'shutting_down' = undefined;
19
+
20
+ /**
21
+ * The info object contains information of each health indicator which is of status “up”
22
+ */
23
+ @Field(type => JSON, {
24
+ description: 'The info object contains information of each health indicator which is of status “up”',
25
+ nullable: true,
26
+ })
27
+ info: JSON = undefined;
28
+
29
+ /**
30
+ * The error object contains information of each health indicator which is of status “down”
31
+ */
32
+ @Field(type => JSON, {
33
+ description: 'The error object contains information of each health indicator which is of status “down”',
34
+ nullable: true,
35
+ })
36
+ error: JSON = undefined;
37
+
38
+ /**
39
+ * The details object contains information of every health indicator
40
+ */
41
+ @Field(type => JSON, {
42
+ description: 'The details object contains information of every health indicator',
43
+ nullable: false,
44
+ })
45
+ details: JSON = undefined;
46
+ }
@@ -0,0 +1,24 @@
1
+ import { Controller, Get } from '@nestjs/common';
2
+ import { CoreHealthCheckService } from './core-health-check.service';
3
+
4
+ /**
5
+ * The HealthController class checks the health of various components including the database, memory, and disk.
6
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
7
+ */
8
+ @Controller()
9
+ export class CoreHealthCheckController {
10
+ constructor(protected readonly healthCheckService: CoreHealthCheckService) {}
11
+
12
+ /**
13
+ * The function checks the health of various components including the database, memory, and storage.
14
+ * @returns The function is returning the result of calling the `healthCheck()` method
15
+ * with an array of functions as arguments. Each function in the array is a check for a different
16
+ * aspect of the system's health, including the status of the database, memory usage, and disk
17
+ * storage. The `healthCheck()` method will return a Promise that resolves with an array of objects
18
+ * representing the results of each check
19
+ */
20
+ @Get('health-check')
21
+ async healthCheck() {
22
+ return this.healthCheckService.healthCheck();
23
+ }
24
+ }
@@ -0,0 +1,17 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TerminusModule } from '@nestjs/terminus';
3
+ import { CoreHealthCheckController } from './core-health-check.controller';
4
+ import { CoreHealthCheckResolver } from './core-health-check.resolver';
5
+ import { CoreHealthCheckService } from './core-health-check.service';
6
+
7
+ /**
8
+ * This is a module that imports the TerminusModule and includes a HealthController.
9
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
10
+ */
11
+ @Module({
12
+ imports: [TerminusModule],
13
+ controllers: [CoreHealthCheckController],
14
+ providers: [CoreHealthCheckService, CoreHealthCheckResolver],
15
+ })
16
+ export class CoreHealthCheckModule {
17
+ }
@@ -0,0 +1,32 @@
1
+ import { Query, Resolver } from '@nestjs/graphql';
2
+ import { RoleEnum } from '../../common/enums/role.enum';
3
+ import { Roles } from '../../common/decorators/roles.decorator';
4
+ import { CoreHealthCheckResult } from './core-health-check-result.model';
5
+ import { CoreHealthCheckService } from './core-health-check.service';
6
+
7
+
8
+ /**
9
+ * Resolver to process with user data
10
+ */
11
+ @Resolver(() => CoreHealthCheckResult)
12
+ @Roles(RoleEnum.ADMIN)
13
+ export class CoreHealthCheckResolver {
14
+ /**
15
+ * Import services
16
+ */
17
+ constructor(protected readonly healthCheckService: CoreHealthCheckService) {
18
+ }
19
+
20
+ // ===========================================================================
21
+ // Queries
22
+ // ===========================================================================
23
+
24
+ /**
25
+ * Get heath check result
26
+ */
27
+ @Roles(RoleEnum.S_EVERYONE)
28
+ @Query(() => CoreHealthCheckResult, { description: 'Get health check result' })
29
+ async healthCheck() {
30
+ return this.healthCheckService.healthCheck();
31
+ }
32
+ }
@@ -0,0 +1,62 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import {
3
+ DiskHealthIndicator, HealthCheckResult,
4
+ HealthCheckService,
5
+ MemoryHealthIndicator,
6
+ MongooseHealthIndicator,
7
+ } from '@nestjs/terminus';
8
+ import { MongoosePingCheckSettings } from '@nestjs/terminus/dist/health-indicator/database/mongoose.health';
9
+ import { DiskHealthIndicatorOptions } from '@nestjs/terminus/dist/health-indicator/disk/disk-health-options.type';
10
+ import { ConfigService } from '../../common/services/config.service';
11
+
12
+ /**
13
+ * Core health check service
14
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
15
+ */
16
+ @Injectable()
17
+ export class CoreHealthCheckService {
18
+
19
+ constructor(
20
+ protected config: ConfigService,
21
+ protected db: MongooseHealthIndicator,
22
+ protected disk: DiskHealthIndicator,
23
+ protected health: HealthCheckService,
24
+ protected memory: MemoryHealthIndicator,
25
+ ) {
26
+ }
27
+
28
+ healthCheck(): Promise<HealthCheckResult> {
29
+ const healthIndicatorFunctions = [];
30
+ if (this.config.get<boolean>('healthCheck.configs.database.enabled')) {
31
+ healthIndicatorFunctions.push(() =>
32
+ this.db.pingCheck(
33
+ this.config.get<string>('healthCheck.configs.database.key') ?? 'database',
34
+ this.config.get<MongoosePingCheckSettings>('healthCheck.configs.database.options') ?? { timeout: 300 },
35
+ ));
36
+ }
37
+ if (this.config.get<boolean>('healthCheck.configs.memoryHeap.enabled')) {
38
+ healthIndicatorFunctions.push(() => this.memory.checkHeap(
39
+ this.config.get<string>('healthCheck.configs.memoryHeap.key') ?? 'memoryHeap',
40
+ // memory in bytes (4GB default)
41
+ this.config.get<number>('healthCheck.configs.memoryHeap.heapUsedThreshold') ?? 4 * 1024 * 1024 * 1024,
42
+ ));
43
+ }
44
+ if (this.config.get<boolean>('healthCheck.configs.memoryRss.enabled')) {
45
+ healthIndicatorFunctions.push(() => this.memory.checkRSS(
46
+ this.config.get<string>('healthCheck.configs.memoryRss.key') ?? 'memoryRss',
47
+ // memory in bytes (4GB default)
48
+ this.config.get<number>('healthCheck.configs.memoryRss.rssThreshold') ?? 4 * 1024 * 1024 * 1024,
49
+ ));
50
+ }
51
+ if (this.config.get<boolean>('healthCheck.configs.storage.enabled')) {
52
+ healthIndicatorFunctions.push(() => this.disk.checkStorage(
53
+ this.config.get<string>('healthCheck.configs.storage.key') ?? 'storage',
54
+ this.config.get<DiskHealthIndicatorOptions>('healthCheck.configs.storage.options') ?? {
55
+ thresholdPercent: 0.8,
56
+ path: '/',
57
+ },
58
+ ));
59
+ }
60
+ return this.health.check(healthIndicatorFunctions);
61
+ }
62
+ }
@@ -1,5 +1,5 @@
1
1
  import { Field, ObjectType } from '@nestjs/graphql';
2
- import { Prop, raw, Schema as MongooseSchema } from '@nestjs/mongoose';
2
+ import { Schema as MongooseSchema, Prop, raw } from '@nestjs/mongoose';
3
3
  import { IsEmail, IsOptional } from 'class-validator';
4
4
  import { Document } from 'mongoose';
5
5
  import { CorePersistenceModel } from '../../common/models/core-persistence.model';
@@ -50,9 +50,9 @@ export abstract class CoreUserModel extends CorePersistenceModel {
50
50
  /**
51
51
  * Roles of the user
52
52
  */
53
- @Field((type) => [String], { description: 'Roles of the user', nullable: true })
53
+ @Field(type => [String], { description: 'Roles of the user', nullable: true })
54
54
  @IsOptional()
55
- @Prop()
55
+ @Prop([String])
56
56
  roles: string[] = undefined;
57
57
 
58
58
  /**
@@ -89,7 +89,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
89
89
  /**
90
90
  * Verification of the user
91
91
  */
92
- @Field((type) => Boolean, { description: 'Verification state of the user', nullable: true })
92
+ @Field(type => Boolean, { description: 'Verification state of the user', nullable: true })
93
93
  @Prop({ type: Boolean })
94
94
  verified: boolean = undefined;
95
95
 
@@ -114,7 +114,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
114
114
  if (!this.roles || this.roles.length < 1) {
115
115
  return false;
116
116
  }
117
- return !roles || roles.length < 1 ? true : this.roles.some((role) => roles.includes(role));
117
+ return !roles || roles.length < 1 ? true : this.roles.some(role => roles.includes(role));
118
118
  }
119
119
 
120
120
  /**
@@ -127,7 +127,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
127
127
  if (!this.roles || this.roles.length < 1) {
128
128
  return false;
129
129
  }
130
- return !roles ? true : roles.every((role) => this.roles.includes(role));
130
+ return !roles ? true : roles.every(role => this.roles.includes(role));
131
131
  }
132
132
 
133
133
  /**