@lenne.tech/nest-server 9.2.3 → 9.2.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 (73) hide show
  1. package/dist/core/common/helpers/input.helper.js +1 -1
  2. package/dist/core/common/helpers/input.helper.js.map +1 -1
  3. package/dist/core/common/services/mailjet.service.js +1 -1
  4. package/dist/core/common/services/mailjet.service.js.map +1 -1
  5. package/dist/core/modules/auth/auth-guard-strategy.enum.d.ts +4 -0
  6. package/dist/core/modules/auth/auth-guard-strategy.enum.js +9 -0
  7. package/dist/core/modules/auth/auth-guard-strategy.enum.js.map +1 -0
  8. package/dist/core/modules/auth/core-auth.controller.d.ts +18 -0
  9. package/dist/core/modules/auth/core-auth.controller.js +111 -0
  10. package/dist/core/modules/auth/core-auth.controller.js.map +1 -0
  11. package/dist/core/modules/auth/core-auth.module.js +2 -1
  12. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  13. package/dist/core/modules/auth/core-auth.resolver.js +3 -2
  14. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  15. package/dist/core/modules/auth/exceptions/expired-refresh-token.exception.d.ts +4 -0
  16. package/dist/core/modules/auth/exceptions/expired-refresh-token.exception.js +11 -0
  17. package/dist/core/modules/auth/exceptions/expired-refresh-token.exception.js.map +1 -0
  18. package/dist/core/modules/auth/exceptions/expired-token.exception.d.ts +4 -0
  19. package/dist/core/modules/auth/exceptions/expired-token.exception.js +11 -0
  20. package/dist/core/modules/auth/exceptions/expired-token.exception.js.map +1 -0
  21. package/dist/core/modules/auth/exceptions/invalid-token.exception.d.ts +4 -0
  22. package/dist/core/modules/auth/exceptions/invalid-token.exception.js +11 -0
  23. package/dist/core/modules/auth/exceptions/invalid-token.exception.js.map +1 -0
  24. package/dist/core/modules/auth/guards/auth.guard.d.ts +2 -1
  25. package/dist/core/modules/auth/guards/auth.guard.js +14 -6
  26. package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
  27. package/dist/core/modules/auth/guards/roles.guard.js +3 -2
  28. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  29. package/dist/core/modules/auth/services/core-auth.service.js +10 -8
  30. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  31. package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js +2 -1
  32. package/dist/core/modules/auth/strategies/jwt-refresh.strategy.js.map +1 -1
  33. package/dist/core/modules/auth/strategies/jwt.strategy.js +2 -1
  34. package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
  35. package/dist/core/modules/file/core-file.service.js +1 -1
  36. package/dist/core/modules/file/core-file.service.js.map +1 -1
  37. package/dist/core/modules/user/core-user.service.js +3 -3
  38. package/dist/core/modules/user/core-user.service.js.map +1 -1
  39. package/dist/core.module.js +2 -2
  40. package/dist/core.module.js.map +1 -1
  41. package/dist/index.d.ts +5 -0
  42. package/dist/index.js +5 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/server/modules/auth/auth.controller.d.ts +8 -0
  45. package/dist/server/modules/auth/auth.controller.js +30 -0
  46. package/dist/server/modules/auth/auth.controller.js.map +1 -0
  47. package/dist/server/modules/file/file.controller.js +3 -3
  48. package/dist/server/modules/file/file.controller.js.map +1 -1
  49. package/dist/server/modules/user/user.service.js +1 -1
  50. package/dist/server/modules/user/user.service.js.map +1 -1
  51. package/dist/tsconfig.build.tsbuildinfo +1 -1
  52. package/package.json +1 -1
  53. package/src/core/common/helpers/input.helper.ts +2 -2
  54. package/src/core/common/services/mailjet.service.ts +2 -2
  55. package/src/core/modules/auth/auth-guard-strategy.enum.ts +4 -0
  56. package/src/core/modules/auth/core-auth.controller.ts +110 -0
  57. package/src/core/modules/auth/core-auth.module.ts +2 -1
  58. package/src/core/modules/auth/core-auth.resolver.ts +3 -2
  59. package/src/core/modules/auth/exceptions/expired-refresh-token.exception.ts +10 -0
  60. package/src/core/modules/auth/exceptions/expired-token.exception.ts +10 -0
  61. package/src/core/modules/auth/exceptions/invalid-token.exception.ts +10 -0
  62. package/src/core/modules/auth/guards/auth.guard.ts +14 -6
  63. package/src/core/modules/auth/guards/roles.guard.ts +3 -2
  64. package/src/core/modules/auth/services/core-auth.service.ts +10 -10
  65. package/src/core/modules/auth/strategies/jwt-refresh.strategy.ts +3 -3
  66. package/src/core/modules/auth/strategies/jwt.strategy.ts +2 -1
  67. package/src/core/modules/file/core-file.service.ts +1 -1
  68. package/src/core/modules/user/core-user.service.ts +3 -5
  69. package/src/core.module.ts +2 -2
  70. package/src/index.ts +5 -0
  71. package/src/server/modules/auth/auth.controller.ts +17 -0
  72. package/src/server/modules/file/file.controller.ts +4 -3
  73. package/src/server/modules/user/user.service.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "9.2.3",
3
+ "version": "9.2.4",
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",
@@ -1,4 +1,4 @@
1
- import { BadRequestException, UnauthorizedException } from '@nestjs/common';
1
+ import { BadRequestException, HttpException, UnauthorizedException } from '@nestjs/common';
2
2
  import { plainToInstance } from 'class-transformer';
3
3
  import { validate } from 'class-validator';
4
4
  import { ValidatorOptions } from 'class-validator/types/validation/ValidatorOptions';
@@ -362,7 +362,7 @@ export function deepFreeze(object: any) {
362
362
  * Standard error function
363
363
  */
364
364
  export function errorFunction(caller: (...params) => any, message = 'Required parameter is missing or invalid') {
365
- const err = new Error(message);
365
+ const err = new BadRequestException(message);
366
366
  Error.captureStackTrace(err, caller);
367
367
  throw err;
368
368
  }
@@ -1,4 +1,4 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { HttpException, Injectable } from '@nestjs/common';
2
2
  import { template } from 'lodash';
3
3
  import { ConfigService } from './config.service';
4
4
  // eslint-disable-next-line
@@ -86,7 +86,7 @@ export class MailjetService {
86
86
  this.configService.getFastButReadOnly('email.mailjet.api_key_public') &&
87
87
  this.configService.getFastButReadOnly('email.mailjet.api_key_private')
88
88
  ) {
89
- throw new Error('Cannot connect to mailjet.');
89
+ throw new HttpException('Cannot connect to mailjet.', 502);
90
90
  }
91
91
  console.debug(
92
92
  JSON.stringify(
@@ -0,0 +1,4 @@
1
+ export enum AuthGuardStrategy {
2
+ JWT = 'jwt',
3
+ JWT_REFRESH = 'jwt-refresh',
4
+ }
@@ -0,0 +1,110 @@
1
+ import { Body, Controller, Get, Param, ParseBoolPipe, Post, Res, UseGuards } from '@nestjs/common';
2
+ import { Args, Info } from '@nestjs/graphql';
3
+ import { Response as ResponseType } from 'express';
4
+ import { GraphQLResolveInfo } from 'graphql/index';
5
+ import { GraphQLUser } from '../../common/decorators/graphql-user.decorator';
6
+ import { RESTUser } from '../../common/decorators/rest-user.decorator';
7
+ import { ConfigService } from '../../common/services/config.service';
8
+ import { AuthGuardStrategy } from './auth-guard-strategy.enum';
9
+ import { CoreAuthModel } from './core-auth.model';
10
+ import { AuthGuard } from './guards/auth.guard';
11
+ import { CoreAuthSignInInput } from './inputs/core-auth-sign-in.input';
12
+ import { CoreAuthSignUpInput } from './inputs/core-auth-sign-up.input';
13
+ import { ICoreAuthUser } from './interfaces/core-auth-user.interface';
14
+ import { CoreAuthService } from './services/core-auth.service';
15
+ import { Tokens } from './tokens.decorator';
16
+
17
+ @Controller('auth')
18
+ export class CoreAuthController {
19
+ /**
20
+ * Import services
21
+ */
22
+ constructor(protected readonly authService: CoreAuthService, protected readonly configService: ConfigService) {}
23
+
24
+ /**
25
+ * Logout user (from specific device)
26
+ */
27
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
28
+ @Get()
29
+ async logout(
30
+ @RESTUser() currentUser: ICoreAuthUser,
31
+ @Tokens('token') token: string,
32
+ @Res() res: ResponseType,
33
+ @Param('allDevices', ParseBoolPipe) allDevices?: boolean
34
+ ): Promise<boolean> {
35
+ const result = await this.authService.logout(token, { currentUser, allDevices });
36
+ return this.processCookies(res, result);
37
+ }
38
+
39
+ /**
40
+ * Refresh token (for specific device)
41
+ */
42
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
43
+ @Get()
44
+ async refreshToken(
45
+ @GraphQLUser() user: ICoreAuthUser,
46
+ @Tokens('refreshToken') refreshToken: string,
47
+ @Res() res: ResponseType
48
+ ): Promise<CoreAuthModel> {
49
+ const result = await this.authService.refreshTokens(user, refreshToken);
50
+ return this.processCookies(res, result);
51
+ }
52
+
53
+ /**
54
+ * Sign in user via email and password (on specific device)
55
+ */
56
+ @Post()
57
+ async signIn(
58
+ @Info() info: GraphQLResolveInfo,
59
+ @Res() res: ResponseType,
60
+ @Body('input') input: CoreAuthSignInInput
61
+ ): Promise<CoreAuthModel> {
62
+ const result = await this.authService.signIn(input);
63
+ return this.processCookies(res, result);
64
+ }
65
+
66
+ /**
67
+ * Register a new user account (on specific device)
68
+ */
69
+ @Post()
70
+ async signUp(
71
+ @Info() info: GraphQLResolveInfo,
72
+ @Res() res: ResponseType,
73
+ @Args('input') input: CoreAuthSignUpInput
74
+ ): Promise<CoreAuthModel> {
75
+ const result = await this.authService.signUp(input);
76
+ return this.processCookies(res, result);
77
+ }
78
+
79
+ // ===================================================================================================================
80
+ // Helper
81
+ // ===================================================================================================================
82
+
83
+ /**
84
+ * Process cookies
85
+ */
86
+ protected processCookies(res: ResponseType, result: any) {
87
+ // Check if cookie handling is activated
88
+ if (this.configService.getFastButReadOnly('cookies')) {
89
+ // Set cookies
90
+ if (typeof result !== 'object') {
91
+ res.cookie('token', '', { httpOnly: true });
92
+ res.cookie('refreshToken', '', { httpOnly: true });
93
+ return result;
94
+ }
95
+ res.cookie('token', result?.token || '', { httpOnly: true });
96
+ res.cookie('refreshToken', result?.refreshToken || '', { httpOnly: true });
97
+
98
+ // Remove tokens from result
99
+ if (result.token) {
100
+ delete result.token;
101
+ }
102
+ if (result.refreshToken) {
103
+ delete result.refreshToken;
104
+ }
105
+ }
106
+
107
+ // Return prepared result
108
+ return result;
109
+ }
110
+ }
@@ -2,6 +2,7 @@ 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 { AuthGuardStrategy } from './auth-guard-strategy.enum';
5
6
  import { RolesGuard } from './guards/roles.guard';
6
7
  import { JwtRefreshStrategy } from './strategies/jwt-refresh.strategy';
7
8
  import { JwtStrategy } from './strategies/jwt.strategy';
@@ -32,7 +33,7 @@ export class CoreAuthModule {
32
33
  // Process imports
33
34
  let imports: any[] = [
34
35
  UserModule,
35
- PassportModule.register({ defaultStrategy: ['jwt', 'jwt-refresh'] }),
36
+ PassportModule.register({ defaultStrategy: [AuthGuardStrategy.JWT, AuthGuardStrategy.JWT_REFRESH] }),
36
37
  JwtModule.register(options),
37
38
  ];
38
39
  if (Array.isArray(options?.imports)) {
@@ -4,6 +4,7 @@ import { Response as ResponseType } from 'express';
4
4
  import { GraphQLResolveInfo } from 'graphql';
5
5
  import { GraphQLUser } from '../../common/decorators/graphql-user.decorator';
6
6
  import { ConfigService } from '../../common/services/config.service';
7
+ import { AuthGuardStrategy } from './auth-guard-strategy.enum';
7
8
  import { CoreAuthModel } from './core-auth.model';
8
9
  import { AuthGuard } from './guards/auth.guard';
9
10
  import { CoreAuthSignInInput } from './inputs/core-auth-sign-in.input';
@@ -29,7 +30,7 @@ export class CoreAuthResolver {
29
30
  /**
30
31
  * Logout user (from specific device)
31
32
  */
32
- @UseGuards(AuthGuard('jwt'))
33
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
33
34
  @Mutation((returns) => Boolean, { description: 'Logout user (from specific device)' })
34
35
  async logout(
35
36
  @GraphQLUser() currentUser: ICoreAuthUser,
@@ -44,7 +45,7 @@ export class CoreAuthResolver {
44
45
  /**
45
46
  * Refresh token (for specific device)
46
47
  */
47
- @UseGuards(AuthGuard('jwt-refresh'))
48
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT_REFRESH))
48
49
  @Mutation((returns) => CoreAuthModel, { description: 'Refresh tokens (for specific device)' })
49
50
  async refreshToken(
50
51
  @GraphQLUser() user: ICoreAuthUser,
@@ -0,0 +1,10 @@
1
+ import { UnauthorizedException } from '@nestjs/common';
2
+
3
+ /**
4
+ * Exception for expired refresh token
5
+ */
6
+ export class ExpiredRefreshTokenException extends UnauthorizedException {
7
+ constructor() {
8
+ super('Expired refresh token');
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ import { UnauthorizedException } from '@nestjs/common';
2
+
3
+ /**
4
+ * Exception for expired token
5
+ */
6
+ export class ExpiredTokenException extends UnauthorizedException {
7
+ constructor() {
8
+ super('Expired token');
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ import { UnauthorizedException } from '@nestjs/common';
2
+
3
+ /**
4
+ * Exception for invalid token
5
+ */
6
+ export class InvalidTokenException extends UnauthorizedException {
7
+ constructor() {
8
+ super('Invalid token');
9
+ }
10
+ }
@@ -5,6 +5,10 @@ import { defaultOptions } from '@nestjs/passport/dist/options';
5
5
  import { memoize } from '@nestjs/passport/dist/utils/memoize.util';
6
6
  import * as jwt from 'jsonwebtoken';
7
7
  import * as passport from 'passport';
8
+ import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
9
+ import { ExpiredRefreshTokenException } from '../exceptions/expired-refresh-token.exception';
10
+ import { ExpiredTokenException } from '../exceptions/expired-token.exception';
11
+ import { InvalidTokenException } from '../exceptions/invalid-token.exception';
8
12
 
9
13
  /**
10
14
  * Missing strategy error
@@ -105,13 +109,17 @@ function createAuthGuard(type?: string): Type<CanActivate> {
105
109
  */
106
110
  handleRequest(err, user, info, context): TUser {
107
111
  if (err) {
108
- if (err instanceof jwt.JsonWebTokenError) {
109
- throw new UnauthorizedException('Invalid token');
110
- }
111
- throw err;
112
+ throw new InvalidTokenException();
112
113
  }
113
114
  if (!user) {
114
- throw new UnauthorizedException('Invalid token');
115
+ if (info?.name === 'TokenExpiredError') {
116
+ if (type === AuthGuardStrategy.JWT_REFRESH) {
117
+ throw new ExpiredRefreshTokenException();
118
+ } else {
119
+ throw new ExpiredTokenException();
120
+ }
121
+ }
122
+ throw new InvalidTokenException();
115
123
  }
116
124
  return user;
117
125
  }
@@ -124,4 +132,4 @@ function createAuthGuard(type?: string): Type<CanActivate> {
124
132
  /**
125
133
  * Export AuthGuard
126
134
  */
127
- export const AuthGuard: (type?: string | string[]) => Type<IAuthGuard> = memoize(createAuthGuard);
135
+ export const AuthGuard: (type?: string | string[] | AuthGuardStrategy) => Type<IAuthGuard> = memoize(createAuthGuard);
@@ -2,6 +2,7 @@ import { ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/com
2
2
  import { Reflector } from '@nestjs/core';
3
3
  import { GqlExecutionContext } from '@nestjs/graphql';
4
4
  import { RoleEnum } from '../../../common/enums/role.enum';
5
+ import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
5
6
  import { AuthGuard } from './auth.guard';
6
7
 
7
8
  /**
@@ -12,7 +13,7 @@ import { AuthGuard } from './auth.guard';
12
13
  * If this is not the case, an UnauthorizedException is thrown.
13
14
  */
14
15
  @Injectable()
15
- export class RolesGuard extends AuthGuard('jwt') {
16
+ export class RolesGuard extends AuthGuard(AuthGuardStrategy.JWT) {
16
17
  /**
17
18
  * Integrate reflector
18
19
  */
@@ -53,7 +54,7 @@ export class RolesGuard extends AuthGuard('jwt') {
53
54
  }
54
55
 
55
56
  // Requester is not authorized
56
- throw new UnauthorizedException();
57
+ throw new UnauthorizedException('Missing role');
57
58
  }
58
59
 
59
60
  // Everything is ok
@@ -45,13 +45,13 @@ export class CoreAuthService {
45
45
  // Check authentication
46
46
  const user = serviceOptions.currentUser;
47
47
  if (!user || !tokenOrRefreshToken) {
48
- throw new UnauthorizedException();
48
+ throw new UnauthorizedException('Invalid token');
49
49
  }
50
50
 
51
51
  // Check authorization
52
52
  const deviceId = this.decodeJwt(tokenOrRefreshToken)?.deviceId;
53
53
  if (!deviceId || !user.refreshTokens[deviceId]) {
54
- throw new UnauthorizedException('Invalid refresh token');
54
+ throw new UnauthorizedException('Invalid token');
55
55
  }
56
56
 
57
57
  // Logout from all devices
@@ -101,11 +101,11 @@ export class CoreAuthService {
101
101
 
102
102
  // Get user
103
103
  const user = await this.userService.getViaEmail(email, serviceOptionsForUserService);
104
- if (
105
- !user ||
106
- !((await bcrypt.compare(password, user.password)) || (await bcrypt.compare(sha256(password), user.password)))
107
- ) {
108
- throw new UnauthorizedException();
104
+ if (!user) {
105
+ throw new UnauthorizedException('Unknown email');
106
+ }
107
+ if (!((await bcrypt.compare(password, user.password)) || (await bcrypt.compare(sha256(password), user.password)))) {
108
+ throw new UnauthorizedException('Wrong password');
109
109
  }
110
110
 
111
111
  // Return tokens and user
@@ -125,7 +125,7 @@ export class CoreAuthService {
125
125
  // Get and check user
126
126
  const user = await this.userService.create(input, serviceOptionsForUserService);
127
127
  if (!user) {
128
- throw new BadRequestException('Email Address already in use');
128
+ throw new BadRequestException('Email address already in use');
129
129
  }
130
130
 
131
131
  // Set device ID
@@ -233,7 +233,7 @@ export class CoreAuthService {
233
233
  if (currentRefreshToken) {
234
234
  deviceId = this.decodeJwt(currentRefreshToken)?.deviceId;
235
235
  if (!deviceId || !user.refreshTokens?.[deviceId]) {
236
- throw new UnauthorizedException('Invalid refresh token');
236
+ throw new UnauthorizedException('Invalid token');
237
237
  }
238
238
  if (!this.configService.getFastButReadOnly('jwt.refresh.renewal')) {
239
239
  // Return currentToken
@@ -254,7 +254,7 @@ export class CoreAuthService {
254
254
  // Set new token
255
255
  const payload = this.decodeJwt(newRefreshToken);
256
256
  if (!payload) {
257
- throw new UnauthorizedException();
257
+ throw new UnauthorizedException('Invalid token');
258
258
  }
259
259
  if (!deviceId) {
260
260
  deviceId = payload.deviceId;
@@ -1,13 +1,13 @@
1
- import { ForbiddenException, Injectable, UnauthorizedException } from '@nestjs/common';
1
+ import { Injectable, UnauthorizedException } from '@nestjs/common';
2
2
  import { PassportStrategy } from '@nestjs/passport';
3
- import * as bcrypt from 'bcrypt';
4
3
  import { Request as RequestType, Request } from 'express';
5
4
  import { ExtractJwt, Strategy } from 'passport-jwt';
6
5
  import { ConfigService } from '../../../common/services/config.service';
6
+ import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
7
7
  import { CoreAuthService } from '../services/core-auth.service';
8
8
 
9
9
  @Injectable()
10
- export class JwtRefreshStrategy extends PassportStrategy(Strategy, 'jwt-refresh') {
10
+ export class JwtRefreshStrategy extends PassportStrategy(Strategy, AuthGuardStrategy.JWT_REFRESH) {
11
11
  constructor(protected readonly authService: CoreAuthService, protected readonly configService: ConfigService) {
12
12
  super({
13
13
  jwtFromRequest: ExtractJwt.fromExtractors([
@@ -2,6 +2,7 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
2
2
  import { PassportStrategy } from '@nestjs/passport';
3
3
  import { ExtractJwt, Strategy } from 'passport-jwt';
4
4
  import { ConfigService } from '../../../common/services/config.service';
5
+ import { AuthGuardStrategy } from '../auth-guard-strategy.enum';
5
6
  import { JwtPayload } from '../interfaces/jwt-payload.interface';
6
7
  import { CoreAuthService } from '../services/core-auth.service';
7
8
  import { Request as RequestType } from 'express';
@@ -10,7 +11,7 @@ import { Request as RequestType } from 'express';
10
11
  * Use JWT strategy for passport
11
12
  */
12
13
  @Injectable()
13
- export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
14
+ export class JwtStrategy extends PassportStrategy(Strategy, AuthGuardStrategy.JWT) {
14
15
  /**
15
16
  * Init JWT strategy
16
17
  */
@@ -72,7 +72,7 @@ export abstract class CoreFileService {
72
72
  const filterQuery = convertFilterArgsToQuery(filterArgs);
73
73
  const cursor = this.files.find(filterQuery[0], filterQuery[1]);
74
74
  if (!cursor) {
75
- throw new Error('File collection not found');
75
+ throw new NotFoundException('File collection not found');
76
76
  }
77
77
  cursor.toArray((error, docs) => {
78
78
  error ? reject(error) : resolve(this.prepareOutput(docs, serviceOptions));
@@ -55,9 +55,7 @@ export abstract class CoreUserService<
55
55
  await createdUser.save();
56
56
  } catch (error) {
57
57
  if (error.code === 11000) {
58
- throw new UnprocessableEntityException(
59
- `User with email address "${(data.input as any).email}" already exists`
60
- );
58
+ throw new BadRequestException('Email address already in use');
61
59
  } else {
62
60
  throw new UnprocessableEntityException();
63
61
  }
@@ -105,7 +103,7 @@ export abstract class CoreUserService<
105
103
  }
106
104
 
107
105
  if (!dbObject.verificationToken) {
108
- throw new Error('User has no token');
106
+ throw new BadRequestException('User has no verification token');
109
107
  }
110
108
 
111
109
  if (dbObject.verified) {
@@ -185,7 +183,7 @@ export abstract class CoreUserService<
185
183
 
186
184
  // Check roles values
187
185
  if (roles.some((role) => typeof role !== 'string')) {
188
- throw new BadRequestException('roles contains invalid values');
186
+ throw new BadRequestException('Roles contains invalid values');
189
187
  }
190
188
 
191
189
  // Update and return user
@@ -78,7 +78,7 @@ export class CoreModule implements NestModule {
78
78
  return { user: user, headers: connectionParams };
79
79
  }
80
80
 
81
- throw new UnauthorizedException();
81
+ throw new UnauthorizedException('Missing authentication token');
82
82
  }
83
83
  },
84
84
  },
@@ -98,7 +98,7 @@ export class CoreModule implements NestModule {
98
98
  return extra;
99
99
  }
100
100
 
101
- throw new UnauthorizedException();
101
+ throw new UnauthorizedException('Missing authentication token');
102
102
  }
103
103
  },
104
104
  context: ({ extra }) => extra,
package/src/index.ts CHANGED
@@ -76,6 +76,9 @@ export * from './core/common/types/string-or-object-id.type';
76
76
  // Core - Modules - Auth
77
77
  // =====================================================================================================================
78
78
 
79
+ export * from './core/modules/auth/exceptions/expired-refresh-token.exception';
80
+ export * from './core/modules/auth/exceptions/expired-token.exception';
81
+ export * from './core/modules/auth/exceptions/invalid-token.exception';
79
82
  export * from './core/modules/auth/guards/auth.guard';
80
83
  export * from './core/modules/auth/guards/roles.guard';
81
84
  export * from './core/modules/auth/inputs/core-auth-sign-in.input';
@@ -87,6 +90,8 @@ export * from './core/modules/auth/services/core-auth.service';
87
90
  export * from './core/modules/auth/services/core-auth-user.service';
88
91
  export * from './core/modules/auth/strategies/jwt.strategy';
89
92
  export * from './core/modules/auth/strategies/jwt-refresh.strategy';
93
+ export * from './core/modules/auth/auth-guard-strategy.enum';
94
+ export * from './core/modules/auth/core-auth.controller';
90
95
  export * from './core/modules/auth/core-auth.model';
91
96
  export * from './core/modules/auth/core-auth.module';
92
97
  export * from './core/modules/auth/core-auth.resolver';
@@ -0,0 +1,17 @@
1
+ import { Controller } from '@nestjs/common';
2
+ import { ConfigService } from '../../../core/common/services/config.service';
3
+ import { CoreAuthController } from '../../../core/modules/auth/core-auth.controller';
4
+ import { AuthService } from './auth.service';
5
+
6
+ @Controller('auth')
7
+ export class AuthController extends CoreAuthController {
8
+ /**
9
+ * Import project services
10
+ */
11
+ constructor(
12
+ protected override readonly authService: AuthService,
13
+ protected override readonly configService: ConfigService
14
+ ) {
15
+ super(authService, configService);
16
+ }
17
+ }
@@ -1,4 +1,5 @@
1
1
  import {
2
+ BadRequestException,
2
3
  Controller,
3
4
  Delete,
4
5
  Get,
@@ -41,7 +42,7 @@ export class FileController {
41
42
  @Get(':id')
42
43
  async getFile(@Param('id') id: string, @Res() res) {
43
44
  if (!id) {
44
- throw new UnprocessableEntityException();
45
+ throw new BadRequestException('Missing ID');
45
46
  }
46
47
 
47
48
  let file;
@@ -52,7 +53,7 @@ export class FileController {
52
53
  }
53
54
 
54
55
  if (!file) {
55
- throw new NotFoundException();
56
+ throw new NotFoundException('File not found');
56
57
  }
57
58
  const filestream = await this.fileService.getFileStream(id);
58
59
  res.header('Content-Type', file.contentType);
@@ -75,7 +76,7 @@ export class FileController {
75
76
  @Delete(':id')
76
77
  async deleteFile(@Param('id') id: string) {
77
78
  if (!id) {
78
- throw new UnprocessableEntityException();
79
+ throw new BadRequestException('Missing ID');
79
80
  }
80
81
 
81
82
  return await this.fileService.deleteFile(id);
@@ -88,7 +88,7 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
88
88
  const dbUser = await this.mainDbModel.findOne({ id: user.id }).exec();
89
89
  // Check user
90
90
  if (!dbUser) {
91
- throw new UnauthorizedException();
91
+ throw new UnauthorizedException('User is not allowed to set the avatar');
92
92
  }
93
93
 
94
94
  // Check file