xiongzhu před 2 roky
rodič
revize
4f3f734101
65 změnil soubory, kde provedl 1999 přidání a 2158 odebrání
  1. 5 2
      .prettierrc
  2. 1 1
      package.json
  3. 63 63
      src/app.controller.spec.ts
  4. 16 16
      src/app.controller.ts
  5. 54 54
      src/app.module.ts
  6. 30 30
      src/app.service.spec.ts
  7. 12 12
      src/app.service.ts
  8. 27 31
      src/helpers/configure-swagger-docs.helper.ts
  9. 51 57
      src/iam/change-password/change-password.controller.spec.ts
  10. 18 26
      src/iam/change-password/change-password.controller.ts
  11. 31 35
      src/iam/change-password/change-password.module.ts
  12. 62 62
      src/iam/change-password/change-password.service.spec.ts
  13. 27 37
      src/iam/change-password/change-password.service.ts
  14. 3 6
      src/iam/change-password/dto/change-password.dto.ts
  15. 2 2
      src/iam/forgot-password/dto/forgot-password.dto.ts
  16. 49 55
      src/iam/forgot-password/forgot-password.controller.spec.ts
  17. 18 26
      src/iam/forgot-password/forgot-password.controller.ts
  18. 20 20
      src/iam/forgot-password/forgot-password.module.ts
  19. 73 73
      src/iam/forgot-password/forgot-password.service.spec.ts
  20. 41 45
      src/iam/forgot-password/forgot-password.service.ts
  21. 2 2
      src/iam/iam.constants.ts
  22. 10 17
      src/iam/iam.module.ts
  23. 9 12
      src/iam/login/config/jwt.config.ts
  24. 4 5
      src/iam/login/decorators/auth-guard.decorator.ts
  25. 3 6
      src/iam/login/dto/login.dto.ts
  26. 2 2
      src/iam/login/enums/auth-type.enum.ts
  27. 28 38
      src/iam/login/guards/access-token/access-token.guard.ts
  28. 27 40
      src/iam/login/guards/authentication/authentication.guard.ts
  29. 3 3
      src/iam/login/interfaces/jwt-payload.interface.ts
  30. 42 42
      src/iam/login/login.controller.spec.ts
  31. 11 11
      src/iam/login/login.controller.ts
  32. 33 33
      src/iam/login/login.module.ts
  33. 112 112
      src/iam/login/login.service.spec.ts
  34. 51 61
      src/iam/login/login.service.ts
  35. 1 1
      src/iam/register/dto/register-user.dto.ts
  36. 71 71
      src/iam/register/register.controller.spec.ts
  37. 18 26
      src/iam/register/register.controller.ts
  38. 19 19
      src/iam/register/register.module.ts
  39. 72 72
      src/iam/register/register.service.spec.ts
  40. 34 37
      src/iam/register/register.service.ts
  41. 28 28
      src/main.ts
  42. 6 4
      src/migrations/1589834500772-Api.ts
  43. 4 4
      src/repl.ts
  44. 21 21
      src/shared/hashing/bcrypt.service.spec.ts
  45. 10 10
      src/shared/hashing/bcrypt.service.ts
  46. 19 19
      src/shared/hashing/hashing.service.spec.ts
  47. 3 3
      src/shared/hashing/hashing.service.ts
  48. 6 6
      src/shared/mailer/mailer.module.ts
  49. 14 14
      src/shared/mailer/mailer.service.spec.ts
  50. 32 39
      src/shared/mailer/mailer.service.ts
  51. 4 4
      src/shared/utils/utils.module.ts
  52. 13 13
      src/shared/utils/utils.service.spec.ts
  53. 5 5
      src/shared/utils/utils.service.ts
  54. 2 2
      src/users/dto/user-profile.dto.ts
  55. 2 2
      src/users/dto/user-update.dto.ts
  56. 15 15
      src/users/dto/user.dto.ts
  57. 13 13
      src/users/entities/users.entity.ts
  58. 5 5
      src/users/interfaces/users.interface.ts
  59. 132 134
      src/users/users.controller.spec.ts
  60. 66 69
      src/users/users.controller.ts
  61. 17 17
      src/users/users.module.ts
  62. 218 232
      src/users/users.service.spec.ts
  63. 92 109
      src/users/users.service.ts
  64. 116 126
      test/change-password/change-password.e2e-spec.ts
  65. 1 1
      yarn.lock

+ 5 - 2
.prettierrc

@@ -1,4 +1,7 @@
 {
-  "singleQuote": true,
-  "trailingComma": "all"
+    "singleQuote": true,
+    "trailingComma": "none",
+    "semi": false,
+    "printWidth": 120,
+    "tabWidth": 4
 }

+ 1 - 1
package.json

@@ -61,7 +61,7 @@
     "eslint-plugin-prettier": "^4.2.1",
     "jest": "^29.4.1",
     "nodemailer-express-handlebars": "^6.0.0",
-    "prettier": "^2.8.4",
+    "prettier": "^2.8.7",
     "supertest": "^6.3.3",
     "ts-jest": "^29.0.5",
     "ts-loader": "^9.4.2",

+ 63 - 63
src/app.controller.spec.ts

@@ -1,75 +1,75 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { AppController } from './app.controller';
-import { AppService } from './app.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { AppController } from './app.controller'
+import { AppService } from './app.service'
 
 class MockResponse {
-  res: any;
-  constructor() {
-    this.res = {};
-  }
-  status = jest
-    .fn()
-    .mockReturnThis()
-    .mockImplementationOnce((code) => {
-      this.res.code = code;
-      return this;
-    });
-  send = jest
-    .fn()
-    .mockReturnThis()
-    .mockImplementationOnce((message) => {
-      this.res.message = message;
-      return this;
-    });
-  json = jest
-    .fn()
-    .mockReturnThis()
-    .mockImplementationOnce((json) => {
-      this.res.json = json;
-      return this;
-    });
+    res: any
+    constructor() {
+        this.res = {}
+    }
+    status = jest
+        .fn()
+        .mockReturnThis()
+        .mockImplementationOnce((code) => {
+            this.res.code = code
+            return this
+        })
+    send = jest
+        .fn()
+        .mockReturnThis()
+        .mockImplementationOnce((message) => {
+            this.res.message = message
+            return this
+        })
+    json = jest
+        .fn()
+        .mockReturnThis()
+        .mockImplementationOnce((json) => {
+            this.res.json = json
+            return this
+        })
 }
 
 describe('AppController', () => {
-  let appController: AppController;
-  let appService: AppService;
-  const response = new MockResponse();
+    let appController: AppController
+    let appService: AppService
+    const response = new MockResponse()
 
-  beforeEach(async () => {
-    const app: TestingModule = await Test.createTestingModule({
-      controllers: [AppController],
-      providers: [
-        {
-          provide: AppService,
-          useValue: {
-            getHello: jest.fn(() => {}),
-            getSecureResource: jest.fn(() => {}),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const app: TestingModule = await Test.createTestingModule({
+            controllers: [AppController],
+            providers: [
+                {
+                    provide: AppService,
+                    useValue: {
+                        getHello: jest.fn(() => {}),
+                        getSecureResource: jest.fn(() => {})
+                    }
+                }
+            ]
+        }).compile()
 
-    appController = app.get<AppController>(AppController);
-    appService = app.get<AppService>(AppService);
-  });
+        appController = app.get<AppController>(AppController)
+        appService = app.get<AppService>(AppService)
+    })
 
-  describe('root', () => {
-    it('should be defined', () => {
-      expect(appController).toBeDefined();
-    });
+    describe('root', () => {
+        it('should be defined', () => {
+            expect(appController).toBeDefined()
+        })
 
-    it('should call method getHello() in AppService', () => {
-      const createSpy = jest.spyOn(appService, 'getHello');
+        it('should call method getHello() in AppService', () => {
+            const createSpy = jest.spyOn(appService, 'getHello')
 
-      appController.getHello(response as any);
-      expect(createSpy).toHaveBeenCalled();
-    });
+            appController.getHello(response as any)
+            expect(createSpy).toHaveBeenCalled()
+        })
 
-    it('should call method getProtectedResource() in AppService', () => {
-      const createSpy = jest.spyOn(appService, 'getSecureResource');
+        it('should call method getProtectedResource() in AppService', () => {
+            const createSpy = jest.spyOn(appService, 'getSecureResource')
 
-      appController.getProtectedResource(response as any);
-      expect(createSpy).toHaveBeenCalled();
-    });
-  });
-});
+            appController.getProtectedResource(response as any)
+            expect(createSpy).toHaveBeenCalled()
+        })
+    })
+})

+ 16 - 16
src/app.controller.ts

@@ -1,22 +1,22 @@
-import { Controller, Get, Res, HttpStatus, UseGuards } from '@nestjs/common';
-import { AppService } from './app.service';
-import { Response } from 'express';
-import { AuthGuard } from './iam/login/decorators/auth-guard.decorator';
-import { AuthType } from './iam/login/enums/auth-type.enum';
+import { Controller, Get, Res, HttpStatus, UseGuards } from '@nestjs/common'
+import { AppService } from './app.service'
+import { Response } from 'express'
+import { AuthGuard } from './iam/login/decorators/auth-guard.decorator'
+import { AuthType } from './iam/login/enums/auth-type.enum'
 
 @Controller()
 export class AppController {
-  constructor(private readonly appService: AppService) {}
+    constructor(private readonly appService: AppService) {}
 
-  @AuthGuard(AuthType.None)
-  @Get()
-  getHello(@Res() res: Response) {
-    return res.status(HttpStatus.OK).json(this.appService.getHello());
-  }
+    @AuthGuard(AuthType.None)
+    @Get()
+    getHello(@Res() res: Response) {
+        return res.status(HttpStatus.OK).json(this.appService.getHello())
+    }
 
-  @AuthGuard(AuthType.Bearer)
-  @Get('secure')
-  getProtectedResource(@Res() res: Response) {
-    return res.status(HttpStatus.OK).json(this.appService.getSecureResource());
-  }
+    @AuthGuard(AuthType.Bearer)
+    @Get('secure')
+    getProtectedResource(@Res() res: Response) {
+        return res.status(HttpStatus.OK).json(this.appService.getSecureResource())
+    }
 }

+ 54 - 54
src/app.module.ts

@@ -1,58 +1,58 @@
-import { Module } from '@nestjs/common';
-import { ConfigModule, ConfigService } from '@nestjs/config';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { AppController } from './app.controller';
-import { AppService } from './app.service';
-import { UsersModule } from './users/users.module';
-import { ThrottlerModule } from '@nestjs/throttler';
-import { IamModule } from './iam/iam.module';
-import * as Yup from 'yup';
+import { Module } from '@nestjs/common'
+import { ConfigModule, ConfigService } from '@nestjs/config'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { AppController } from './app.controller'
+import { AppService } from './app.service'
+import { UsersModule } from './users/users.module'
+import { ThrottlerModule } from '@nestjs/throttler'
+import { IamModule } from './iam/iam.module'
+import * as Yup from 'yup'
 
 @Module({
-  imports: [
-    ConfigModule.forRoot({
-      isGlobal: true,
-      envFilePath: ['.env', '.env.dev', '.env.stage', '.env.prod'],
-      validationSchema: Yup.object({
-        TYPEORM_HOST: Yup.string().required(),
-        TYPEORM_PORT: Yup.number().default(3306),
-        TYPEORM_USERNAME: Yup.string().required(),
-        TYPEORM_PASSWORD: Yup.string().required(),
-        TYPEORM_DATABASE: Yup.string().required(),
-      }),
-    }),
-    ThrottlerModule.forRootAsync({
-      imports: [ConfigModule],
-      inject: [ConfigService],
-      useFactory: (config: ConfigService) => ({
-        ttl: config.get<number>('THROTTLE_TTL'),
-        limit: config.get<number>('THROTTLE_LIMIT'),
-      }),
-    }),
-    TypeOrmModule.forRootAsync({
-      imports: [ConfigModule],
-      inject: [ConfigService],
-      useFactory: (config: ConfigService) => ({
-        type: 'mysql',
-        host: config.get<string>('TYPEORM_HOST'),
-        port: config.get<number>('TYPEORM_PORT'),
-        username: config.get<string>('TYPEORM_USERNAME'),
-        password: config.get<string>('TYPEORM_PASSWORD'),
-        database: config.get<string>('TYPEORM_DATABASE'),
-        synchronize: true,
-        entities: [__dirname + '/**/*.entity.{ts,js}'],
-        migrations: ['dist/migrations/**/*.js'],
-        subscribers: ['dist/subscriber/**/*.js'],
-        cli: {
-          migrationsDir: config.get<string>('TYPEORM_MIGRATIONS_DIR'),
-          subscribersDir: config.get<string>('TYPEORM_SUBSCRIBERS_DIR'),
-        },
-      }),
-    }),
-    IamModule,
-    UsersModule,
-  ],
-  controllers: [AppController],
-  providers: [AppService],
+    imports: [
+        ConfigModule.forRoot({
+            isGlobal: true,
+            envFilePath: ['.env', '.env.dev', '.env.stage', '.env.prod'],
+            validationSchema: Yup.object({
+                TYPEORM_HOST: Yup.string().required(),
+                TYPEORM_PORT: Yup.number().default(3306),
+                TYPEORM_USERNAME: Yup.string().required(),
+                TYPEORM_PASSWORD: Yup.string().required(),
+                TYPEORM_DATABASE: Yup.string().required()
+            })
+        }),
+        ThrottlerModule.forRootAsync({
+            imports: [ConfigModule],
+            inject: [ConfigService],
+            useFactory: (config: ConfigService) => ({
+                ttl: config.get<number>('THROTTLE_TTL'),
+                limit: config.get<number>('THROTTLE_LIMIT')
+            })
+        }),
+        TypeOrmModule.forRootAsync({
+            imports: [ConfigModule],
+            inject: [ConfigService],
+            useFactory: (config: ConfigService) => ({
+                type: 'mysql',
+                host: config.get<string>('TYPEORM_HOST'),
+                port: config.get<number>('TYPEORM_PORT'),
+                username: config.get<string>('TYPEORM_USERNAME'),
+                password: config.get<string>('TYPEORM_PASSWORD'),
+                database: config.get<string>('TYPEORM_DATABASE'),
+                synchronize: true,
+                entities: [__dirname + '/**/*.entity.{ts,js}'],
+                migrations: ['dist/migrations/**/*.js'],
+                subscribers: ['dist/subscriber/**/*.js'],
+                cli: {
+                    migrationsDir: config.get<string>('TYPEORM_MIGRATIONS_DIR'),
+                    subscribersDir: config.get<string>('TYPEORM_SUBSCRIBERS_DIR')
+                }
+            })
+        }),
+        IamModule,
+        UsersModule
+    ],
+    controllers: [AppController],
+    providers: [AppService]
 })
 export class AppModule {}

+ 30 - 30
src/app.service.spec.ts

@@ -1,37 +1,37 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { AppService } from './app.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { AppService } from './app.service'
 
 describe('AppService', () => {
-  let service: AppService;
+    let service: AppService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [AppService],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [AppService]
+        }).compile()
 
-    service = module.get<AppService>(AppService);
-  });
+        service = module.get<AppService>(AppService)
+    })
 
-  describe('App service', () => {
-    it('should be defined', () => {
-      expect(service).toBeDefined();
-    });
+    describe('App service', () => {
+        it('should be defined', () => {
+            expect(service).toBeDefined()
+        })
 
-    describe('getHello() method', () => {
-      it('should return message "This is a simple example of item returned by your APIs"', () => {
-        expect(service.getHello()).toEqual({
-          message: 'This is a simple example of item returned by your APIs.',
-        });
-      });
-    });
+        describe('getHello() method', () => {
+            it('should return message "This is a simple example of item returned by your APIs"', () => {
+                expect(service.getHello()).toEqual({
+                    message: 'This is a simple example of item returned by your APIs.'
+                })
+            })
+        })
 
-    describe('getSecureResource() method', () => {
-      it('should return message "Access to protected resources granted! This protected resource is displayed when the token is successfully provided"', () => {
-        expect(service.getSecureResource()).toEqual({
-          message:
-            'Access to protected resources granted! This protected resource is displayed when the token is successfully provided.',
-        });
-      });
-    });
-  });
-});
+        describe('getSecureResource() method', () => {
+            it('should return message "Access to protected resources granted! This protected resource is displayed when the token is successfully provided"', () => {
+                expect(service.getSecureResource()).toEqual({
+                    message:
+                        'Access to protected resources granted! This protected resource is displayed when the token is successfully provided.'
+                })
+            })
+        })
+    })
+})

+ 12 - 12
src/app.service.ts

@@ -1,17 +1,17 @@
-import { Injectable } from '@nestjs/common';
+import { Injectable } from '@nestjs/common'
 
 @Injectable()
 export class AppService {
-  getHello() {
-    return {
-      message: 'This is a simple example of item returned by your APIs.',
-    };
-  }
+    getHello() {
+        return {
+            message: 'This is a simple example of item returned by your APIs.'
+        }
+    }
 
-  getSecureResource() {
-    return {
-      message:
-        'Access to protected resources granted! This protected resource is displayed when the token is successfully provided.',
-    };
-  }
+    getSecureResource() {
+        return {
+            message:
+                'Access to protected resources granted! This protected resource is displayed when the token is successfully provided.'
+        }
+    }
 }

+ 27 - 31
src/helpers/configure-swagger-docs.helper.ts

@@ -1,35 +1,31 @@
-import { INestApplication } from '@nestjs/common';
-import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
-import { ConfigService } from '@nestjs/config';
-import * as basicAuth from 'express-basic-auth';
+import { INestApplication } from '@nestjs/common'
+import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
+import { ConfigService } from '@nestjs/config'
+import * as basicAuth from 'express-basic-auth'
 
-const SWAGGER_ENVS = ['local', 'dev', 'staging'];
+const SWAGGER_ENVS = ['local', 'dev', 'staging']
 
-export function configureSwaggerDocs(
-  app: INestApplication,
-  configService: ConfigService,
-) {
-  if (SWAGGER_ENVS.includes(configService.get<string>('NODE_ENV'))) {
-    app.use(
-      ['/docs', '/docs-json', '/docs-yaml'],
-      basicAuth({
-        challenge: true,
-        users: {
-          [configService.get<string>('SWAGGER_USER')]:
-            configService.get<string>('SWAGGER_PASSWORD'),
-        },
-      }),
-    );
+export function configureSwaggerDocs(app: INestApplication, configService: ConfigService) {
+    if (SWAGGER_ENVS.includes(configService.get<string>('NODE_ENV'))) {
+        app.use(
+            ['/docs', '/docs-json', '/docs-yaml'],
+            basicAuth({
+                challenge: true,
+                users: {
+                    [configService.get<string>('SWAGGER_USER')]: configService.get<string>('SWAGGER_PASSWORD')
+                }
+            })
+        )
 
-    const config = new DocumentBuilder()
-      .setTitle('API')
-      .setDescription('The API description')
-      .setVersion('1.0')
-      .addBearerAuth()
-      .addTag('auth')
-      .addTag('users')
-      .build();
-    const document = SwaggerModule.createDocument(app, config);
-    SwaggerModule.setup('/docs', app, document);
-  }
+        const config = new DocumentBuilder()
+            .setTitle('API')
+            .setDescription('The API description')
+            .setVersion('1.0')
+            .addBearerAuth()
+            .addTag('auth')
+            .addTag('users')
+            .build()
+        const document = SwaggerModule.createDocument(app, config)
+        SwaggerModule.setup('/docs', app, document)
+    }
 }

+ 51 - 57
src/iam/change-password/change-password.controller.spec.ts

@@ -1,61 +1,55 @@
-import { BadRequestException } from '@nestjs/common';
-import { Test, TestingModule } from '@nestjs/testing';
-import { ChangePasswordController } from './change-password.controller';
-import { ChangePasswordService } from './change-password.service';
-import { ChangePasswordDto } from './dto/change-password.dto';
+import { BadRequestException } from '@nestjs/common'
+import { Test, TestingModule } from '@nestjs/testing'
+import { ChangePasswordController } from './change-password.controller'
+import { ChangePasswordService } from './change-password.service'
+import { ChangePasswordDto } from './dto/change-password.dto'
 
 const changePasswordDto: ChangePasswordDto = {
-  email: 'text@example.com',
-  password: 'password123',
-};
+    email: 'text@example.com',
+    password: 'password123'
+}
 
 describe('ChangePassword Controller', () => {
-  let changePasswordController: ChangePasswordController;
-  let changePasswordService: ChangePasswordService;
-
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      controllers: [ChangePasswordController],
-      providers: [
-        {
-          provide: ChangePasswordService,
-          useValue: {
-            changePassword: jest.fn(() => {}),
-          },
-        },
-      ],
-    }).compile();
-
-    changePasswordController = module.get<ChangePasswordController>(
-      ChangePasswordController,
-    );
-    changePasswordService = module.get<ChangePasswordService>(
-      ChangePasswordService,
-    );
-  });
-
-  describe('Change Password', () => {
-    it('should be defined', () => {
-      expect(changePasswordController).toBeDefined();
-    });
-
-    it('should call method changePassword in changePasswordService', async () => {
-      const createSpy = jest.spyOn(changePasswordService, 'changePassword');
-
-      await changePasswordController.changePassword(changePasswordDto);
-      expect(createSpy).toHaveBeenCalledWith(changePasswordDto);
-    });
-
-    it('should throw an exception if it not find an user email', async () => {
-      changePasswordService.changePassword = jest
-        .fn()
-        .mockRejectedValueOnce(null);
-      await expect(
-        changePasswordController.changePassword({
-          email: 'not a correct email',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(BadRequestException);
-    });
-  });
-});
+    let changePasswordController: ChangePasswordController
+    let changePasswordService: ChangePasswordService
+
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            controllers: [ChangePasswordController],
+            providers: [
+                {
+                    provide: ChangePasswordService,
+                    useValue: {
+                        changePassword: jest.fn(() => {})
+                    }
+                }
+            ]
+        }).compile()
+
+        changePasswordController = module.get<ChangePasswordController>(ChangePasswordController)
+        changePasswordService = module.get<ChangePasswordService>(ChangePasswordService)
+    })
+
+    describe('Change Password', () => {
+        it('should be defined', () => {
+            expect(changePasswordController).toBeDefined()
+        })
+
+        it('should call method changePassword in changePasswordService', async () => {
+            const createSpy = jest.spyOn(changePasswordService, 'changePassword')
+
+            await changePasswordController.changePassword(changePasswordDto)
+            expect(createSpy).toHaveBeenCalledWith(changePasswordDto)
+        })
+
+        it('should throw an exception if it not find an user email', async () => {
+            changePasswordService.changePassword = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                changePasswordController.changePassword({
+                    email: 'not a correct email',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(BadRequestException)
+        })
+    })
+})

+ 18 - 26
src/iam/change-password/change-password.controller.ts

@@ -1,35 +1,27 @@
-import {
-  Controller,
-  Post,
-  Body,
-  HttpStatus,
-  BadRequestException,
-} from '@nestjs/common';
-import { ChangePasswordService } from './change-password.service';
-import { ChangePasswordDto } from './dto/change-password.dto';
-import { ApiTags } from '@nestjs/swagger';
-import { AuthGuard } from '../login/decorators/auth-guard.decorator';
-import { AuthType } from '../login/enums/auth-type.enum';
+import { Controller, Post, Body, HttpStatus, BadRequestException } from '@nestjs/common'
+import { ChangePasswordService } from './change-password.service'
+import { ChangePasswordDto } from './dto/change-password.dto'
+import { ApiTags } from '@nestjs/swagger'
+import { AuthGuard } from '../login/decorators/auth-guard.decorator'
+import { AuthType } from '../login/enums/auth-type.enum'
 
 @ApiTags('auth')
 @AuthGuard(AuthType.Bearer)
 @Controller('auth/change-password')
 export class ChangePasswordController {
-  constructor(private readonly changePasswordService: ChangePasswordService) {}
+    constructor(private readonly changePasswordService: ChangePasswordService) {}
 
-  @Post()
-  public async changePassword(
-    @Body() changePasswordDto: ChangePasswordDto,
-  ): Promise<any> {
-    try {
-      await this.changePasswordService.changePassword(changePasswordDto);
+    @Post()
+    public async changePassword(@Body() changePasswordDto: ChangePasswordDto): Promise<any> {
+        try {
+            await this.changePasswordService.changePassword(changePasswordDto)
 
-      return {
-        message: 'Request Change Password Successfully!',
-        status: HttpStatus.OK,
-      };
-    } catch (err) {
-      throw new BadRequestException(err, 'Error: Change password failed!');
+            return {
+                message: 'Request Change Password Successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: Change password failed!')
+        }
     }
-  }
 }

+ 31 - 35
src/iam/change-password/change-password.module.ts

@@ -1,39 +1,35 @@
-import { Module } from '@nestjs/common';
-import { ChangePasswordController } from './change-password.controller';
-import { ChangePasswordService } from './change-password.service';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { UsersService } from '../../users/users.service';
-import { MailerModule } from '../../shared/mailer/mailer.module';
-import { BcryptService } from '../../shared/hashing/bcrypt.service';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { APP_GUARD } from '@nestjs/core';
-import { AuthenticationGuard } from '../login/guards/authentication/authentication.guard';
-import { AccessTokenGuard } from '../login/guards/access-token/access-token.guard';
-import { JwtService } from '@nestjs/jwt';
-import { ConfigModule } from '@nestjs/config';
-import jwtConfig from '../login/config/jwt.config';
+import { Module } from '@nestjs/common'
+import { ChangePasswordController } from './change-password.controller'
+import { ChangePasswordService } from './change-password.service'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { UsersService } from '../../users/users.service'
+import { MailerModule } from '../../shared/mailer/mailer.module'
+import { BcryptService } from '../../shared/hashing/bcrypt.service'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { APP_GUARD } from '@nestjs/core'
+import { AuthenticationGuard } from '../login/guards/authentication/authentication.guard'
+import { AccessTokenGuard } from '../login/guards/access-token/access-token.guard'
+import { JwtService } from '@nestjs/jwt'
+import { ConfigModule } from '@nestjs/config'
+import jwtConfig from '../login/config/jwt.config'
 
 @Module({
-  imports: [
-    ConfigModule.forFeature(jwtConfig),
-    TypeOrmModule.forFeature([Users]),
-    MailerModule,
-  ],
-  controllers: [ChangePasswordController],
-  providers: [
-    {
-      provide: HashingService,
-      useClass: BcryptService,
-    },
-    {
-      provide: APP_GUARD,
-      useClass: AuthenticationGuard,
-    },
-    AccessTokenGuard,
-    ChangePasswordService,
-    UsersService,
-    JwtService,
-  ],
+    imports: [ConfigModule.forFeature(jwtConfig), TypeOrmModule.forFeature([Users]), MailerModule],
+    controllers: [ChangePasswordController],
+    providers: [
+        {
+            provide: HashingService,
+            useClass: BcryptService
+        },
+        {
+            provide: APP_GUARD,
+            useClass: AuthenticationGuard
+        },
+        AccessTokenGuard,
+        ChangePasswordService,
+        UsersService,
+        JwtService
+    ]
 })
 export class ChangePasswordModule {}

+ 62 - 62
src/iam/change-password/change-password.service.spec.ts

@@ -1,70 +1,70 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { ChangePasswordService } from './change-password.service';
-import { getRepositoryToken } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { Repository } from 'typeorm';
-import { UsersService } from '../../users/users.service';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { ConfigService } from '@nestjs/config';
+import { Test, TestingModule } from '@nestjs/testing'
+import { ChangePasswordService } from './change-password.service'
+import { getRepositoryToken } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { Repository } from 'typeorm'
+import { UsersService } from '../../users/users.service'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { ConfigService } from '@nestjs/config'
 
 const changePasswordUser = {
-  email: 'test@example.it',
-  password: '1234567',
-};
+    email: 'test@example.it',
+    password: '1234567'
+}
 
 describe('ChangePasswordService', () => {
-  let service: ChangePasswordService;
-  let repository: Repository<Users>;
+    let service: ChangePasswordService
+    let repository: Repository<Users>
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        ChangePasswordService,
-        {
-          provide: UsersService,
-          useValue: {
-            updateByPassword: jest.fn().mockResolvedValue(changePasswordUser),
-          },
-        },
-        {
-          provide: MailerService,
-          useValue: {
-            sendMail: jest.fn(),
-          },
-        },
-        {
-          provide: ConfigService,
-          useValue: {
-            get: jest.fn().mockReturnValue('some string'),
-          },
-        },
-        {
-          provide: getRepositoryToken(Users),
-          useValue: {
-            findOneBy: jest.fn(),
-            updateByPassword: jest.fn(),
-            save: jest.fn(),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                ChangePasswordService,
+                {
+                    provide: UsersService,
+                    useValue: {
+                        updateByPassword: jest.fn().mockResolvedValue(changePasswordUser)
+                    }
+                },
+                {
+                    provide: MailerService,
+                    useValue: {
+                        sendMail: jest.fn()
+                    }
+                },
+                {
+                    provide: ConfigService,
+                    useValue: {
+                        get: jest.fn().mockReturnValue('some string')
+                    }
+                },
+                {
+                    provide: getRepositoryToken(Users),
+                    useValue: {
+                        findOneBy: jest.fn(),
+                        updateByPassword: jest.fn(),
+                        save: jest.fn()
+                    }
+                }
+            ]
+        }).compile()
 
-    service = module.get<ChangePasswordService>(ChangePasswordService);
-    repository = module.get<Repository<Users>>(getRepositoryToken(Users));
-  });
+        service = module.get<ChangePasswordService>(ChangePasswordService)
+        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
+    })
 
-  describe('change password user', () => {
-    it('should be defined', () => {
-      expect(service).toBeDefined();
-    });
+    describe('change password user', () => {
+        it('should be defined', () => {
+            expect(service).toBeDefined()
+        })
 
-    it('should change password a user', () => {
-      expect(
-        service.changePassword({
-          email: 'test@example.it',
-          password: '1234567',
-        }),
-      ).resolves.toEqual(changePasswordUser);
-    });
-  });
-});
+        it('should change password a user', () => {
+            expect(
+                service.changePassword({
+                    email: 'test@example.it',
+                    password: '1234567'
+                })
+            ).resolves.toEqual(changePasswordUser)
+        })
+    })
+})

+ 27 - 37
src/iam/change-password/change-password.service.ts

@@ -1,45 +1,35 @@
-import { Injectable, Logger } from '@nestjs/common';
-import { UsersService } from '../../users/users.service';
-import { ChangePasswordDto } from './dto/change-password.dto';
-import { MailerService } from '../../shared/mailer/mailer.service';
+import { Injectable, Logger } from '@nestjs/common'
+import { UsersService } from '../../users/users.service'
+import { ChangePasswordDto } from './dto/change-password.dto'
+import { MailerService } from '../../shared/mailer/mailer.service'
 
 @Injectable()
 export class ChangePasswordService {
-  constructor(
-    private readonly usersService: UsersService,
-    private readonly mailerService: MailerService,
-  ) {}
+    constructor(private readonly usersService: UsersService, private readonly mailerService: MailerService) {}
 
-  public async changePassword(
-    changePasswordDto: ChangePasswordDto,
-  ): Promise<any> {
-    this.sendMailChangePassword(changePasswordDto);
+    public async changePassword(changePasswordDto: ChangePasswordDto): Promise<any> {
+        this.sendMailChangePassword(changePasswordDto)
 
-    return await this.usersService.updateByPassword(
-      changePasswordDto.email,
-      changePasswordDto.password,
-    );
-  }
+        return await this.usersService.updateByPassword(changePasswordDto.email, changePasswordDto.password)
+    }
 
-  private sendMailChangePassword(user): void {
-    try {
-      this.mailerService.sendMail({
-        to: user.email,
-        from: 'from@example.com',
-        subject: 'Change Password successful ✔',
-        text: 'Change Password successful!',
-        template: 'index',
-        context: {
-          title: 'Change Password successful!',
-          description:
-            'Change Password Successfully! ✔, This is your new password: ' +
-            user.password,
-          nameUser: user.name,
-        },
-      });
-      Logger.log('[MailService] Change Password: Send Mail successfully!');
-    } catch (err) {
-      Logger.error('[MailService] Change Password: Send Mail Failed!', err);
+    private sendMailChangePassword(user): void {
+        try {
+            this.mailerService.sendMail({
+                to: user.email,
+                from: 'from@example.com',
+                subject: 'Change Password successful ✔',
+                text: 'Change Password successful!',
+                template: 'index',
+                context: {
+                    title: 'Change Password successful!',
+                    description: 'Change Password Successfully! ✔, This is your new password: ' + user.password,
+                    nameUser: user.name
+                }
+            })
+            Logger.log('[MailService] Change Password: Send Mail successfully!')
+        } catch (err) {
+            Logger.error('[MailService] Change Password: Send Mail Failed!', err)
+        }
     }
-  }
 }

+ 3 - 6
src/iam/change-password/dto/change-password.dto.ts

@@ -1,7 +1,4 @@
-import { PickType } from '@nestjs/swagger';
-import { UserDto } from '../../../users/dto/user.dto';
+import { PickType } from '@nestjs/swagger'
+import { UserDto } from '../../../users/dto/user.dto'
 
-export class ChangePasswordDto extends PickType(UserDto, [
-  'email',
-  'password',
-] as const) {}
+export class ChangePasswordDto extends PickType(UserDto, ['email', 'password'] as const) {}

+ 2 - 2
src/iam/forgot-password/dto/forgot-password.dto.ts

@@ -1,4 +1,4 @@
-import { PickType } from '@nestjs/swagger';
-import { UserDto } from '../../../users/dto/user.dto';
+import { PickType } from '@nestjs/swagger'
+import { UserDto } from '../../../users/dto/user.dto'
 
 export class ForgotPasswordDto extends PickType(UserDto, ['email'] as const) {}

+ 49 - 55
src/iam/forgot-password/forgot-password.controller.spec.ts

@@ -1,59 +1,53 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { ForgotPasswordController } from './forgot-password.controller';
-import { ForgotPasswordService } from './forgot-password.service';
-import { ForgotPasswordDto } from './dto/forgot-password.dto';
-import { BadRequestException } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing'
+import { ForgotPasswordController } from './forgot-password.controller'
+import { ForgotPasswordService } from './forgot-password.service'
+import { ForgotPasswordDto } from './dto/forgot-password.dto'
+import { BadRequestException } from '@nestjs/common'
 
 const forgotPasswordDto: ForgotPasswordDto = {
-  email: 'test@example.com',
-};
+    email: 'test@example.com'
+}
 
 describe('ForgotPassword Controller', () => {
-  let forgotPasswordController: ForgotPasswordController;
-  let forgotPasswordService: ForgotPasswordService;
-
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      controllers: [ForgotPasswordController],
-      providers: [
-        {
-          provide: ForgotPasswordService,
-          useValue: {
-            forgotPassword: jest.fn(() => {}),
-          },
-        },
-      ],
-    }).compile();
-
-    forgotPasswordController = module.get<ForgotPasswordController>(
-      ForgotPasswordController,
-    );
-    forgotPasswordService = module.get<ForgotPasswordService>(
-      ForgotPasswordService,
-    );
-  });
-
-  describe('Forgot Password', () => {
-    it('should be defined', () => {
-      expect(forgotPasswordController).toBeDefined();
-    });
-
-    it('should call method forgotPassword in forgotPasswordService', async () => {
-      const createSpy = jest.spyOn(forgotPasswordService, 'forgotPassword');
-
-      await forgotPasswordController.forgotPassword(forgotPasswordDto);
-      expect(createSpy).toHaveBeenCalledWith(forgotPasswordDto);
-    });
-
-    it('should throw an exception if it not find an user email', async () => {
-      forgotPasswordService.forgotPassword = jest
-        .fn()
-        .mockRejectedValueOnce(null);
-      await expect(
-        forgotPasswordController.forgotPassword({
-          email: 'not a correct email',
-        }),
-      ).rejects.toThrow(BadRequestException);
-    });
-  });
-});
+    let forgotPasswordController: ForgotPasswordController
+    let forgotPasswordService: ForgotPasswordService
+
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            controllers: [ForgotPasswordController],
+            providers: [
+                {
+                    provide: ForgotPasswordService,
+                    useValue: {
+                        forgotPassword: jest.fn(() => {})
+                    }
+                }
+            ]
+        }).compile()
+
+        forgotPasswordController = module.get<ForgotPasswordController>(ForgotPasswordController)
+        forgotPasswordService = module.get<ForgotPasswordService>(ForgotPasswordService)
+    })
+
+    describe('Forgot Password', () => {
+        it('should be defined', () => {
+            expect(forgotPasswordController).toBeDefined()
+        })
+
+        it('should call method forgotPassword in forgotPasswordService', async () => {
+            const createSpy = jest.spyOn(forgotPasswordService, 'forgotPassword')
+
+            await forgotPasswordController.forgotPassword(forgotPasswordDto)
+            expect(createSpy).toHaveBeenCalledWith(forgotPasswordDto)
+        })
+
+        it('should throw an exception if it not find an user email', async () => {
+            forgotPasswordService.forgotPassword = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                forgotPasswordController.forgotPassword({
+                    email: 'not a correct email'
+                })
+            ).rejects.toThrow(BadRequestException)
+        })
+    })
+})

+ 18 - 26
src/iam/forgot-password/forgot-password.controller.ts

@@ -1,35 +1,27 @@
-import {
-  Controller,
-  Post,
-  Body,
-  HttpStatus,
-  BadRequestException,
-} from '@nestjs/common';
-import { ApiTags } from '@nestjs/swagger';
-import { ForgotPasswordService } from '../forgot-password/forgot-password.service';
-import { AuthGuard } from '../login/decorators/auth-guard.decorator';
-import { AuthType } from '../login/enums/auth-type.enum';
-import { ForgotPasswordDto } from './dto/forgot-password.dto';
+import { Controller, Post, Body, HttpStatus, BadRequestException } from '@nestjs/common'
+import { ApiTags } from '@nestjs/swagger'
+import { ForgotPasswordService } from '../forgot-password/forgot-password.service'
+import { AuthGuard } from '../login/decorators/auth-guard.decorator'
+import { AuthType } from '../login/enums/auth-type.enum'
+import { ForgotPasswordDto } from './dto/forgot-password.dto'
 
 @ApiTags('auth')
 @AuthGuard(AuthType.None)
 @Controller('auth/forgot-password')
 export class ForgotPasswordController {
-  constructor(private readonly forgotPasswordService: ForgotPasswordService) {}
+    constructor(private readonly forgotPasswordService: ForgotPasswordService) {}
 
-  @Post()
-  public async forgotPassword(
-    @Body() forgotPasswordDto: ForgotPasswordDto,
-  ): Promise<any> {
-    try {
-      await this.forgotPasswordService.forgotPassword(forgotPasswordDto);
+    @Post()
+    public async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto): Promise<any> {
+        try {
+            await this.forgotPasswordService.forgotPassword(forgotPasswordDto)
 
-      return {
-        message: 'Request Reset Password Successfully!',
-        status: HttpStatus.OK,
-      };
-    } catch (err) {
-      throw new BadRequestException(err, 'Error: Forgot password failed!');
+            return {
+                message: 'Request Reset Password Successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: Forgot password failed!')
+        }
     }
-  }
 }

+ 20 - 20
src/iam/forgot-password/forgot-password.module.ts

@@ -1,24 +1,24 @@
-import { Module } from '@nestjs/common';
-import { ForgotPasswordService } from './forgot-password.service';
-import { ForgotPasswordController } from './forgot-password.controller';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { UsersService } from '../../users/users.service';
-import { MailerModule } from '../../shared/mailer/mailer.module';
-import { UtilsModule } from '../../shared/utils/utils.module';
-import { BcryptService } from '../../shared/hashing/bcrypt.service';
-import { HashingService } from '../../shared/hashing/hashing.service';
+import { Module } from '@nestjs/common'
+import { ForgotPasswordService } from './forgot-password.service'
+import { ForgotPasswordController } from './forgot-password.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { UsersService } from '../../users/users.service'
+import { MailerModule } from '../../shared/mailer/mailer.module'
+import { UtilsModule } from '../../shared/utils/utils.module'
+import { BcryptService } from '../../shared/hashing/bcrypt.service'
+import { HashingService } from '../../shared/hashing/hashing.service'
 
 @Module({
-  imports: [TypeOrmModule.forFeature([Users]), MailerModule, UtilsModule],
-  providers: [
-    {
-      provide: HashingService,
-      useClass: BcryptService,
-    },
-    ForgotPasswordService,
-    UsersService,
-  ],
-  controllers: [ForgotPasswordController],
+    imports: [TypeOrmModule.forFeature([Users]), MailerModule, UtilsModule],
+    providers: [
+        {
+            provide: HashingService,
+            useClass: BcryptService
+        },
+        ForgotPasswordService,
+        UsersService
+    ],
+    controllers: [ForgotPasswordController]
 })
 export class ForgotPasswordModule {}

+ 73 - 73
src/iam/forgot-password/forgot-password.service.spec.ts

@@ -1,83 +1,83 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { getRepositoryToken } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { ForgotPasswordService } from './forgot-password.service';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { UtilsService } from '../../shared/utils/utils.service';
-import { ConfigService } from '@nestjs/config';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { Repository } from 'typeorm';
-import { UsersService } from '../../users/users.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { getRepositoryToken } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { ForgotPasswordService } from './forgot-password.service'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { UtilsService } from '../../shared/utils/utils.service'
+import { ConfigService } from '@nestjs/config'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { Repository } from 'typeorm'
+import { UsersService } from '../../users/users.service'
 
 const oneUser = {
-  email: 'test@example.com',
-};
+    email: 'test@example.com'
+}
 
 const user = {
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 describe('ForgotPasswordService', () => {
-  let service: ForgotPasswordService;
-  let repository: Repository<Users>;
-  let mailerService: MailerService;
+    let service: ForgotPasswordService
+    let repository: Repository<Users>
+    let mailerService: MailerService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        ForgotPasswordService,
-        {
-          provide: UsersService,
-          useValue: {
-            forgotPassword: jest.fn(),
-          },
-        },
-        {
-          provide: getRepositoryToken(Users),
-          useValue: {
-            findOneBy: jest.fn(() => oneUser),
-            save: jest.fn(() => user),
-          },
-        },
-        {
-          provide: HashingService,
-          useValue: {
-            hash: jest.fn(() => 'pass123'),
-          },
-        },
-        {
-          provide: ConfigService,
-          useValue: {
-            get: jest.fn().mockReturnValue('some string'),
-          },
-        },
-        {
-          provide: MailerService,
-          useValue: {
-            sendMail: jest.fn(),
-          },
-        },
-        UtilsService,
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                ForgotPasswordService,
+                {
+                    provide: UsersService,
+                    useValue: {
+                        forgotPassword: jest.fn()
+                    }
+                },
+                {
+                    provide: getRepositoryToken(Users),
+                    useValue: {
+                        findOneBy: jest.fn(() => oneUser),
+                        save: jest.fn(() => user)
+                    }
+                },
+                {
+                    provide: HashingService,
+                    useValue: {
+                        hash: jest.fn(() => 'pass123')
+                    }
+                },
+                {
+                    provide: ConfigService,
+                    useValue: {
+                        get: jest.fn().mockReturnValue('some string')
+                    }
+                },
+                {
+                    provide: MailerService,
+                    useValue: {
+                        sendMail: jest.fn()
+                    }
+                },
+                UtilsService
+            ]
+        }).compile()
 
-    service = module.get<ForgotPasswordService>(ForgotPasswordService);
-    mailerService = module.get<MailerService>(MailerService);
-    repository = module.get<Repository<Users>>(getRepositoryToken(Users));
-  });
+        service = module.get<ForgotPasswordService>(ForgotPasswordService)
+        mailerService = module.get<MailerService>(MailerService)
+        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
+    })
 
-  describe('forgot password user', () => {
-    it('should be defined', () => {
-      expect(service).toBeDefined();
-    });
+    describe('forgot password user', () => {
+        it('should be defined', () => {
+            expect(service).toBeDefined()
+        })
 
-    it('should generate a new password for user by email', async () => {
-      expect(
-        await service.forgotPassword({
-          email: 'test@example.com',
-        }),
-      ).toEqual(oneUser);
-    });
-  });
-});
+        it('should generate a new password for user by email', async () => {
+            expect(
+                await service.forgotPassword({
+                    email: 'test@example.com'
+                })
+            ).toEqual(oneUser)
+        })
+    })
+})

+ 41 - 45
src/iam/forgot-password/forgot-password.service.ts

@@ -1,54 +1,50 @@
-import { Injectable, Logger } from '@nestjs/common';
-import { Repository } from 'typeorm';
-import { InjectRepository } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { ForgotPasswordDto } from './dto/forgot-password.dto';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { UtilsService } from '../../shared/utils/utils.service';
-import { HashingService } from '../../shared/hashing/hashing.service';
+import { Injectable, Logger } from '@nestjs/common'
+import { Repository } from 'typeorm'
+import { InjectRepository } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { ForgotPasswordDto } from './dto/forgot-password.dto'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { UtilsService } from '../../shared/utils/utils.service'
+import { HashingService } from '../../shared/hashing/hashing.service'
 
 @Injectable()
 export class ForgotPasswordService {
-  constructor(
-    @InjectRepository(Users)
-    private readonly userRepository: Repository<Users>,
-    private readonly mailerService: MailerService,
-    private readonly utilsService: UtilsService,
-    private readonly hashingService: HashingService,
-  ) {}
+    constructor(
+        @InjectRepository(Users)
+        private readonly userRepository: Repository<Users>,
+        private readonly mailerService: MailerService,
+        private readonly utilsService: UtilsService,
+        private readonly hashingService: HashingService
+    ) {}
 
-  public async forgotPassword(
-    forgotPasswordDto: ForgotPasswordDto,
-  ): Promise<any> {
-    const userUpdate = await this.userRepository.findOneBy({
-      email: forgotPasswordDto.email,
-    });
-    const passwordRand = this.utilsService.generatePassword();
-    userUpdate.password = await this.hashingService.hash(passwordRand);
+    public async forgotPassword(forgotPasswordDto: ForgotPasswordDto): Promise<any> {
+        const userUpdate = await this.userRepository.findOneBy({
+            email: forgotPasswordDto.email
+        })
+        const passwordRand = this.utilsService.generatePassword()
+        userUpdate.password = await this.hashingService.hash(passwordRand)
 
-    this.sendMailForgotPassword(userUpdate.email, passwordRand);
+        this.sendMailForgotPassword(userUpdate.email, passwordRand)
 
-    return await this.userRepository.save(userUpdate);
-  }
+        return await this.userRepository.save(userUpdate)
+    }
 
-  private sendMailForgotPassword(email, password): void {
-    try {
-      this.mailerService.sendMail({
-        to: email,
-        from: 'from@example.com',
-        subject: 'Forgot Password successful ✔',
-        text: 'Forgot Password successful!',
-        template: 'index',
-        context: {
-          title: 'Forgot Password successful!',
-          description:
-            'Request Reset Password Successfully!  ✔, This is your new password: ' +
-            password,
-        },
-      });
-      Logger.log('[MailService] Forgot Password: Send Mail successfully!');
-    } catch (err) {
-      Logger.error('[MailService] Forgot Password: Send Mail Failed!', err);
+    private sendMailForgotPassword(email, password): void {
+        try {
+            this.mailerService.sendMail({
+                to: email,
+                from: 'from@example.com',
+                subject: 'Forgot Password successful ✔',
+                text: 'Forgot Password successful!',
+                template: 'index',
+                context: {
+                    title: 'Forgot Password successful!',
+                    description: 'Request Reset Password Successfully!  ✔, This is your new password: ' + password
+                }
+            })
+            Logger.log('[MailService] Forgot Password: Send Mail successfully!')
+        } catch (err) {
+            Logger.error('[MailService] Forgot Password: Send Mail Failed!', err)
+        }
     }
-  }
 }

+ 2 - 2
src/iam/iam.constants.ts

@@ -1,2 +1,2 @@
-export const REQUEST_USER_KEY = 'user';
-export const TYPE_TOKEN_BEARER = 'Bearer';
+export const REQUEST_USER_KEY = 'user'
+export const TYPE_TOKEN_BEARER = 'Bearer'

+ 10 - 17
src/iam/iam.module.ts

@@ -1,21 +1,14 @@
-import { Module } from '@nestjs/common';
-import { JwtService } from '@nestjs/jwt';
-import { UtilsModule } from '../shared/utils/utils.module';
-import { UsersModule } from '../users/users.module';
-import { ChangePasswordModule } from './change-password/change-password.module';
-import { ForgotPasswordModule } from './forgot-password/forgot-password.module';
-import { LoginModule } from './login/login.module';
-import { RegisterModule } from './register/register.module';
+import { Module } from '@nestjs/common'
+import { JwtService } from '@nestjs/jwt'
+import { UtilsModule } from '../shared/utils/utils.module'
+import { UsersModule } from '../users/users.module'
+import { ChangePasswordModule } from './change-password/change-password.module'
+import { ForgotPasswordModule } from './forgot-password/forgot-password.module'
+import { LoginModule } from './login/login.module'
+import { RegisterModule } from './register/register.module'
 
 @Module({
-  imports: [
-    LoginModule,
-    RegisterModule,
-    UsersModule,
-    ForgotPasswordModule,
-    ChangePasswordModule,
-    UtilsModule,
-  ],
-  providers: [JwtService],
+    imports: [LoginModule, RegisterModule, UsersModule, ForgotPasswordModule, ChangePasswordModule, UtilsModule],
+    providers: [JwtService]
 })
 export class IamModule {}

+ 9 - 12
src/iam/login/config/jwt.config.ts

@@ -1,16 +1,13 @@
-import { ConfigService, registerAs } from '@nestjs/config';
-import { config } from 'dotenv';
+import { ConfigService, registerAs } from '@nestjs/config'
+import { config } from 'dotenv'
 
-config();
+config()
 
-const configService = new ConfigService();
+const configService = new ConfigService()
 
 export default registerAs('jwt', () => {
-  return {
-    secret: configService.get<string>('JWT_SECRET_KEY'),
-    accessTokenTtl: parseInt(
-      configService.get<string>('JWT_ACCESS_TOKEN_TTL') ?? '3600',
-      10,
-    ),
-  };
-});
+    return {
+        secret: configService.get<string>('JWT_SECRET_KEY'),
+        accessTokenTtl: parseInt(configService.get<string>('JWT_ACCESS_TOKEN_TTL') ?? '3600', 10)
+    }
+})

+ 4 - 5
src/iam/login/decorators/auth-guard.decorator.ts

@@ -1,7 +1,6 @@
-import { SetMetadata } from '@nestjs/common';
-import { AuthType } from '../enums/auth-type.enum';
+import { SetMetadata } from '@nestjs/common'
+import { AuthType } from '../enums/auth-type.enum'
 
-export const AUTH_TYPE_KEY = 'authType';
+export const AUTH_TYPE_KEY = 'authType'
 
-export const AuthGuard = (...authTypes: AuthType[]) =>
-  SetMetadata(AUTH_TYPE_KEY, authTypes);
+export const AuthGuard = (...authTypes: AuthType[]) => SetMetadata(AUTH_TYPE_KEY, authTypes)

+ 3 - 6
src/iam/login/dto/login.dto.ts

@@ -1,7 +1,4 @@
-import { PickType } from '@nestjs/swagger';
-import { UserDto } from '../../../users/dto/user.dto';
+import { PickType } from '@nestjs/swagger'
+import { UserDto } from '../../../users/dto/user.dto'
 
-export class LoginDto extends PickType(UserDto, [
-  'email',
-  'password',
-] as const) {}
+export class LoginDto extends PickType(UserDto, ['email', 'password'] as const) {}

+ 2 - 2
src/iam/login/enums/auth-type.enum.ts

@@ -1,4 +1,4 @@
 export enum AuthType {
-  Bearer,
-  None,
+    Bearer,
+    None
 }

+ 28 - 38
src/iam/login/guards/access-token/access-token.guard.ts

@@ -1,46 +1,36 @@
-import {
-  CanActivate,
-  ExecutionContext,
-  HttpStatus,
-  Inject,
-  Injectable,
-  UnauthorizedException,
-} from '@nestjs/common';
-import { ConfigType } from '@nestjs/config';
-import { JwtService } from '@nestjs/jwt';
-import { Request } from 'express';
-import { REQUEST_USER_KEY, TYPE_TOKEN_BEARER } from '../../../iam.constants';
-import jwtConfig from '../../config/jwt.config';
+import { CanActivate, ExecutionContext, HttpStatus, Inject, Injectable, UnauthorizedException } from '@nestjs/common'
+import { ConfigType } from '@nestjs/config'
+import { JwtService } from '@nestjs/jwt'
+import { Request } from 'express'
+import { REQUEST_USER_KEY, TYPE_TOKEN_BEARER } from '../../../iam.constants'
+import jwtConfig from '../../config/jwt.config'
 
 @Injectable()
 export class AccessTokenGuard implements CanActivate {
-  constructor(
-    private readonly jwtService: JwtService,
-    @Inject(jwtConfig.KEY)
-    private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,
-  ) {}
+    constructor(
+        private readonly jwtService: JwtService,
+        @Inject(jwtConfig.KEY)
+        private readonly jwtConfiguration: ConfigType<typeof jwtConfig>
+    ) {}
 
-  async canActivate(context: ExecutionContext): Promise<boolean> {
-    const request = context.switchToHttp().getRequest();
-    const token = this.extractTokenFromHeader(request);
-    if (!token) {
-      throw new UnauthorizedException();
-    }
+    async canActivate(context: ExecutionContext): Promise<boolean> {
+        const request = context.switchToHttp().getRequest()
+        const token = this.extractTokenFromHeader(request)
+        if (!token) {
+            throw new UnauthorizedException()
+        }
 
-    try {
-      const payload = await this.jwtService.verifyAsync(
-        token,
-        this.jwtConfiguration,
-      );
-      request[REQUEST_USER_KEY] = payload;
-    } catch (err) {
-      throw new UnauthorizedException(HttpStatus.UNAUTHORIZED, err);
+        try {
+            const payload = await this.jwtService.verifyAsync(token, this.jwtConfiguration)
+            request[REQUEST_USER_KEY] = payload
+        } catch (err) {
+            throw new UnauthorizedException(HttpStatus.UNAUTHORIZED, err)
+        }
+        return true
     }
-    return true;
-  }
 
-  private extractTokenFromHeader(request: Request): string | undefined {
-    const [type, token] = request.headers.authorization?.split(' ') ?? [];
-    return type === TYPE_TOKEN_BEARER ? token : undefined;
-  }
+    private extractTokenFromHeader(request: Request): string | undefined {
+        const [type, token] = request.headers.authorization?.split(' ') ?? []
+        return type === TYPE_TOKEN_BEARER ? token : undefined
+    }
 }

+ 27 - 40
src/iam/login/guards/authentication/authentication.guard.ts

@@ -1,49 +1,36 @@
-import {
-  CanActivate,
-  ExecutionContext,
-  Injectable,
-  UnauthorizedException,
-} from '@nestjs/common';
-import { Reflector } from '@nestjs/core';
-import { AuthType } from '../../enums/auth-type.enum';
-import { AccessTokenGuard } from '../access-token/access-token.guard';
-import { AUTH_TYPE_KEY } from '../../decorators/auth-guard.decorator';
+import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common'
+import { Reflector } from '@nestjs/core'
+import { AuthType } from '../../enums/auth-type.enum'
+import { AccessTokenGuard } from '../access-token/access-token.guard'
+import { AUTH_TYPE_KEY } from '../../decorators/auth-guard.decorator'
 
 @Injectable()
 export class AuthenticationGuard implements CanActivate {
-  private static readonly defaultAuthType = AuthType.Bearer;
-  private readonly authTypeGuardMap: Record<
-    AuthType,
-    CanActivate | CanActivate[]
-  > = {
-    [AuthType.Bearer]: this.accessTokenGuard,
-    [AuthType.None]: { canActivate: () => true },
-  };
+    private static readonly defaultAuthType = AuthType.Bearer
+    private readonly authTypeGuardMap: Record<AuthType, CanActivate | CanActivate[]> = {
+        [AuthType.Bearer]: this.accessTokenGuard,
+        [AuthType.None]: { canActivate: () => true }
+    }
 
-  constructor(
-    private readonly reflector: Reflector,
-    private readonly accessTokenGuard: AccessTokenGuard,
-  ) {}
+    constructor(private readonly reflector: Reflector, private readonly accessTokenGuard: AccessTokenGuard) {}
 
-  async canActivate(context: ExecutionContext): Promise<boolean> {
-    const authTypes = this.reflector.getAllAndOverride<AuthType[]>(
-      AUTH_TYPE_KEY,
-      [context.getHandler(), context.getClass()],
-    ) ?? [AuthenticationGuard.defaultAuthType];
-    const guards = authTypes.map((type) => this.authTypeGuardMap[type]).flat();
-    let error = new UnauthorizedException();
+    async canActivate(context: ExecutionContext): Promise<boolean> {
+        const authTypes = this.reflector.getAllAndOverride<AuthType[]>(AUTH_TYPE_KEY, [
+            context.getHandler(),
+            context.getClass()
+        ]) ?? [AuthenticationGuard.defaultAuthType]
+        const guards = authTypes.map((type) => this.authTypeGuardMap[type]).flat()
+        let error = new UnauthorizedException()
 
-    for (const instance of guards) {
-      const canActivate = await Promise.resolve(
-        instance.canActivate(context),
-      ).catch((err) => {
-        error = err;
-      });
+        for (const instance of guards) {
+            const canActivate = await Promise.resolve(instance.canActivate(context)).catch((err) => {
+                error = err
+            })
 
-      if (canActivate) {
-        return true;
-      }
+            if (canActivate) {
+                return true
+            }
+        }
+        throw error
     }
-    throw error;
-  }
 }

+ 3 - 3
src/iam/login/interfaces/jwt-payload.interface.ts

@@ -1,5 +1,5 @@
 export interface JWTPayload {
-  id: number;
-  email: string;
-  name: string;
+    id: number
+    email: string
+    name: string
 }

+ 42 - 42
src/iam/login/login.controller.spec.ts

@@ -1,51 +1,51 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { UsersService } from '../../users/users.service';
-import { LoginController } from './login.controller';
-import { LoginService } from './login.service';
-import { LoginDto } from './dto/login.dto';
+import { Test, TestingModule } from '@nestjs/testing'
+import { UsersService } from '../../users/users.service'
+import { LoginController } from './login.controller'
+import { LoginService } from './login.service'
+import { LoginDto } from './dto/login.dto'
 
 const loginDto: LoginDto = {
-  email: 'test@example.com',
-  password: 'password123',
-};
+    email: 'test@example.com',
+    password: 'password123'
+}
 
 describe('Login Controller', () => {
-  let loginController: LoginController;
-  let loginService: LoginService;
+    let loginController: LoginController
+    let loginService: LoginService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      controllers: [LoginController],
-      providers: [
-        {
-          provide: LoginService,
-          useValue: {
-            login: jest.fn(() => {}),
-          },
-        },
-        {
-          provide: UsersService,
-          useValue: {
-            findByEmail: jest.fn(() => {}),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            controllers: [LoginController],
+            providers: [
+                {
+                    provide: LoginService,
+                    useValue: {
+                        login: jest.fn(() => {})
+                    }
+                },
+                {
+                    provide: UsersService,
+                    useValue: {
+                        findByEmail: jest.fn(() => {})
+                    }
+                }
+            ]
+        }).compile()
 
-    loginController = module.get<LoginController>(LoginController);
-    loginService = module.get<LoginService>(LoginService);
-  });
+        loginController = module.get<LoginController>(LoginController)
+        loginService = module.get<LoginService>(LoginService)
+    })
 
-  describe('Login user', () => {
-    it('should be defined', () => {
-      expect(loginController).toBeDefined();
-    });
+    describe('Login user', () => {
+        it('should be defined', () => {
+            expect(loginController).toBeDefined()
+        })
 
-    it('should call method login in loginService', async () => {
-      const createSpy = jest.spyOn(loginService, 'login');
+        it('should call method login in loginService', async () => {
+            const createSpy = jest.spyOn(loginService, 'login')
 
-      await loginController.login(loginDto);
-      expect(createSpy).toHaveBeenCalledWith(loginDto);
-    });
-  });
-});
+            await loginController.login(loginDto)
+            expect(createSpy).toHaveBeenCalledWith(loginDto)
+        })
+    })
+})

+ 11 - 11
src/iam/login/login.controller.ts

@@ -1,18 +1,18 @@
-import { Controller, Post, Body } from '@nestjs/common';
-import { LoginService } from './login.service';
-import { LoginDto } from '../login/dto/login.dto';
-import { ApiTags } from '@nestjs/swagger';
-import { AuthType } from './enums/auth-type.enum';
-import { AuthGuard } from './decorators/auth-guard.decorator';
+import { Controller, Post, Body } from '@nestjs/common'
+import { LoginService } from './login.service'
+import { LoginDto } from '../login/dto/login.dto'
+import { ApiTags } from '@nestjs/swagger'
+import { AuthType } from './enums/auth-type.enum'
+import { AuthGuard } from './decorators/auth-guard.decorator'
 
 @ApiTags('auth')
 @AuthGuard(AuthType.None)
 @Controller('auth/login')
 export class LoginController {
-  constructor(private readonly loginService: LoginService) {}
+    constructor(private readonly loginService: LoginService) {}
 
-  @Post()
-  public async login(@Body() loginDto: LoginDto): Promise<any> {
-    return await this.loginService.login(loginDto);
-  }
+    @Post()
+    public async login(@Body() loginDto: LoginDto): Promise<any> {
+        return await this.loginService.login(loginDto)
+    }
 }

+ 33 - 33
src/iam/login/login.module.ts

@@ -1,37 +1,37 @@
-import { Module } from '@nestjs/common';
-import { LoginService } from './login.service';
-import { LoginController } from './login.controller';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { Users } from '../../users/entities/users.entity';
-import { JwtModule } from '@nestjs/jwt';
-import { UsersService } from '../../users/users.service';
-import { ConfigModule } from '@nestjs/config';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { BcryptService } from '../../shared/hashing/bcrypt.service';
-import { APP_GUARD } from '@nestjs/core';
-import { AuthenticationGuard } from './guards/authentication/authentication.guard';
-import { AccessTokenGuard } from './guards/access-token/access-token.guard';
-import jwtConfig from './config/jwt.config';
+import { Module } from '@nestjs/common'
+import { LoginService } from './login.service'
+import { LoginController } from './login.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Users } from '../../users/entities/users.entity'
+import { JwtModule } from '@nestjs/jwt'
+import { UsersService } from '../../users/users.service'
+import { ConfigModule } from '@nestjs/config'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { BcryptService } from '../../shared/hashing/bcrypt.service'
+import { APP_GUARD } from '@nestjs/core'
+import { AuthenticationGuard } from './guards/authentication/authentication.guard'
+import { AccessTokenGuard } from './guards/access-token/access-token.guard'
+import jwtConfig from './config/jwt.config'
 
 @Module({
-  imports: [
-    TypeOrmModule.forFeature([Users]),
-    ConfigModule.forFeature(jwtConfig),
-    JwtModule.registerAsync(jwtConfig.asProvider()),
-  ],
-  providers: [
-    {
-      provide: HashingService,
-      useClass: BcryptService,
-    },
-    {
-      provide: APP_GUARD,
-      useClass: AuthenticationGuard,
-    },
-    AccessTokenGuard,
-    LoginService,
-    UsersService,
-  ],
-  controllers: [LoginController],
+    imports: [
+        TypeOrmModule.forFeature([Users]),
+        ConfigModule.forFeature(jwtConfig),
+        JwtModule.registerAsync(jwtConfig.asProvider())
+    ],
+    providers: [
+        {
+            provide: HashingService,
+            useClass: BcryptService
+        },
+        {
+            provide: APP_GUARD,
+            useClass: AuthenticationGuard
+        },
+        AccessTokenGuard,
+        LoginService,
+        UsersService
+    ],
+    controllers: [LoginController]
 })
 export class LoginModule {}

+ 112 - 112
src/iam/login/login.service.spec.ts

@@ -1,129 +1,129 @@
-import { ConfigService } from '@nestjs/config';
-import { JwtService } from '@nestjs/jwt';
-import { Test, TestingModule } from '@nestjs/testing';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { LoginService } from './login.service';
-import { UsersService } from '../../users/users.service';
-import { Users } from '../../users/entities/users.entity';
-import { getRepositoryToken } from '@nestjs/typeorm';
-import { LoginDto } from './dto/login.dto';
-import { UnauthorizedException, HttpException } from '@nestjs/common';
+import { ConfigService } from '@nestjs/config'
+import { JwtService } from '@nestjs/jwt'
+import { Test, TestingModule } from '@nestjs/testing'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { LoginService } from './login.service'
+import { UsersService } from '../../users/users.service'
+import { Users } from '../../users/entities/users.entity'
+import { getRepositoryToken } from '@nestjs/typeorm'
+import { LoginDto } from './dto/login.dto'
+import { UnauthorizedException, HttpException } from '@nestjs/common'
 
 const oneUser = {
-  id: 1,
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    id: 1,
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const loginDto: LoginDto = {
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const userLogin = {
-  sub: 1,
-  accessToken: undefined,
-  audience: 'some string',
-  expiresIn: 'some string',
-  issuer: 'some string',
-  user: {
-    id: 1,
-    name: 'name #1',
-    email: 'test@example.com',
-  },
-};
+    sub: 1,
+    accessToken: undefined,
+    audience: 'some string',
+    expiresIn: 'some string',
+    issuer: 'some string',
+    user: {
+        id: 1,
+        name: 'name #1',
+        email: 'test@example.com'
+    }
+}
 
 const payload = {
-  id: 1,
-  name: 'name #1',
-  email: 'test@example.com',
-};
+    id: 1,
+    name: 'name #1',
+    email: 'test@example.com'
+}
 
 describe('LoginService', () => {
-  let loginService: LoginService;
-  let usersService: UsersService;
-  let hashingService: HashingService;
+    let loginService: LoginService
+    let usersService: UsersService
+    let hashingService: HashingService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        LoginService,
-        {
-          provide: JwtService,
-          useValue: {
-            signAsync: jest.fn(),
-            signToken: jest.fn(() => payload),
-          },
-        },
-        {
-          provide: ConfigService,
-          useValue: {
-            get: jest.fn().mockReturnValue('some string'),
-          },
-        },
-        {
-          provide: HashingService,
-          useValue: {
-            hash: jest.fn(() => Promise.resolve('pass123')),
-            compare: jest.fn(() => Promise.resolve(true)),
-          },
-        },
-        {
-          provide: UsersService,
-          useValue: {
-            findByEmail: jest.fn().mockResolvedValue(oneUser),
-          },
-        },
-        {
-          provide: getRepositoryToken(Users),
-          useValue: {
-            findByEmail: jest.fn(),
-            findOneBy: jest.fn().mockReturnValue(oneUser),
-            findOne: jest.fn().mockReturnValue(oneUser),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                LoginService,
+                {
+                    provide: JwtService,
+                    useValue: {
+                        signAsync: jest.fn(),
+                        signToken: jest.fn(() => payload)
+                    }
+                },
+                {
+                    provide: ConfigService,
+                    useValue: {
+                        get: jest.fn().mockReturnValue('some string')
+                    }
+                },
+                {
+                    provide: HashingService,
+                    useValue: {
+                        hash: jest.fn(() => Promise.resolve('pass123')),
+                        compare: jest.fn(() => Promise.resolve(true))
+                    }
+                },
+                {
+                    provide: UsersService,
+                    useValue: {
+                        findByEmail: jest.fn().mockResolvedValue(oneUser)
+                    }
+                },
+                {
+                    provide: getRepositoryToken(Users),
+                    useValue: {
+                        findByEmail: jest.fn(),
+                        findOneBy: jest.fn().mockReturnValue(oneUser),
+                        findOne: jest.fn().mockReturnValue(oneUser)
+                    }
+                }
+            ]
+        }).compile()
 
-    loginService = module.get<LoginService>(LoginService);
-    usersService = module.get<UsersService>(UsersService);
-    hashingService = module.get<HashingService>(HashingService);
-  });
+        loginService = module.get<LoginService>(LoginService)
+        usersService = module.get<UsersService>(UsersService)
+        hashingService = module.get<HashingService>(HashingService)
+    })
 
-  it('should be defined', () => {
-    expect(loginService).toBeDefined();
-  });
+    it('should be defined', () => {
+        expect(loginService).toBeDefined()
+    })
 
-  describe('findUserByEmail() method', () => {
-    it('should find a user by email', async () => {
-      expect(await loginService.findUserByEmail(loginDto)).toEqual(oneUser);
-    });
+    describe('findUserByEmail() method', () => {
+        it('should find a user by email', async () => {
+            expect(await loginService.findUserByEmail(loginDto)).toEqual(oneUser)
+        })
 
-    it('should generate token jwt', async () => {
-      expect(await loginService.login(loginDto)).toEqual(userLogin);
-    });
+        it('should generate token jwt', async () => {
+            expect(await loginService.login(loginDto)).toEqual(userLogin)
+        })
 
-    it('should return an exception if wrong password', async () => {
-      usersService.findByEmail = jest.fn().mockResolvedValueOnce(oneUser);
-      hashingService.compare = jest.fn().mockResolvedValueOnce(false);
-      await expect(
-        loginService.login({
-          email: 'someemail@test.com',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(HttpException);
-    });
+        it('should return an exception if wrong password', async () => {
+            usersService.findByEmail = jest.fn().mockResolvedValueOnce(oneUser)
+            hashingService.compare = jest.fn().mockResolvedValueOnce(false)
+            await expect(
+                loginService.login({
+                    email: 'someemail@test.com',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(HttpException)
+        })
 
-    it('should return an exception if login fails', async () => {
-      usersService.findByEmail = jest.fn().mockResolvedValueOnce(null);
-      await expect(
-        loginService.login({
-          email: 'not a correct email',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-});
+        it('should return an exception if login fails', async () => {
+            usersService.findByEmail = jest.fn().mockResolvedValueOnce(null)
+            await expect(
+                loginService.login({
+                    email: 'not a correct email',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(HttpException)
+        })
+    })
+})

+ 51 - 61
src/iam/login/login.service.ts

@@ -1,68 +1,58 @@
-import {
-  HttpException,
-  HttpStatus,
-  Injectable,
-  UnauthorizedException,
-} from '@nestjs/common';
-import { JwtService } from '@nestjs/jwt';
-import { UsersService } from '../../users/users.service';
-import { IUsers } from '../../users/interfaces/users.interface';
-import { LoginDto } from './dto/login.dto';
-import { ConfigService } from '@nestjs/config';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { JWTPayload } from './interfaces/jwt-payload.interface';
+import { HttpException, HttpStatus, Injectable, UnauthorizedException } from '@nestjs/common'
+import { JwtService } from '@nestjs/jwt'
+import { UsersService } from '../../users/users.service'
+import { IUsers } from '../../users/interfaces/users.interface'
+import { LoginDto } from './dto/login.dto'
+import { ConfigService } from '@nestjs/config'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { JWTPayload } from './interfaces/jwt-payload.interface'
 
 @Injectable()
 export class LoginService {
-  constructor(
-    private readonly usersService: UsersService,
-    private readonly jwtService: JwtService,
-    private readonly configService: ConfigService,
-    private readonly hashingService: HashingService,
-  ) {}
-
-  public async findUserByEmail(loginDto: LoginDto): Promise<IUsers> {
-    return await this.usersService.findByEmail(loginDto.email);
-  }
-
-  public async login(loginDto: LoginDto): Promise<any> {
-    try {
-      const user = await this.findUserByEmail(loginDto);
-      if (!user) {
-        throw new UnauthorizedException('User does not exists');
-      }
-
-      const passwordIsValid = await this.hashingService.compare(
-        loginDto.password,
-        user.password,
-      );
-
-      if (!passwordIsValid) {
-        throw new UnauthorizedException(
-          'Authentication failed. Wrong password',
-        );
-      }
-
-      return await this.signToken({
-        name: user.name,
-        email: user.email,
-        id: user.id,
-      });
-    } catch (err) {
-      throw new HttpException(err, HttpStatus.BAD_REQUEST);
+    constructor(
+        private readonly usersService: UsersService,
+        private readonly jwtService: JwtService,
+        private readonly configService: ConfigService,
+        private readonly hashingService: HashingService
+    ) {}
+
+    public async findUserByEmail(loginDto: LoginDto): Promise<IUsers> {
+        return await this.usersService.findByEmail(loginDto.email)
     }
-  }
 
-  private async signToken(payload: JWTPayload): Promise<any> {
-    const accessToken = await this.jwtService.signAsync(payload);
+    public async login(loginDto: LoginDto): Promise<any> {
+        try {
+            const user = await this.findUserByEmail(loginDto)
+            if (!user) {
+                throw new UnauthorizedException('User does not exists')
+            }
+
+            const passwordIsValid = await this.hashingService.compare(loginDto.password, user.password)
+
+            if (!passwordIsValid) {
+                throw new UnauthorizedException('Authentication failed. Wrong password')
+            }
+
+            return await this.signToken({
+                name: user.name,
+                email: user.email,
+                id: user.id
+            })
+        } catch (err) {
+            throw new HttpException(err, HttpStatus.BAD_REQUEST)
+        }
+    }
 
-    return {
-      sub: payload.id,
-      expiresIn: this.configService.get<string>('JWT_ACCESS_TOKEN_TTL'),
-      audience: this.configService.get<string>('JWT_TOKEN_AUDIENCE'),
-      issuer: this.configService.get<string>('JWT_TOKEN_ISSUER'),
-      accessToken: accessToken,
-      user: payload,
-    };
-  }
+    private async signToken(payload: JWTPayload): Promise<any> {
+        const accessToken = await this.jwtService.signAsync(payload)
+
+        return {
+            sub: payload.id,
+            expiresIn: this.configService.get<string>('JWT_ACCESS_TOKEN_TTL'),
+            audience: this.configService.get<string>('JWT_TOKEN_AUDIENCE'),
+            issuer: this.configService.get<string>('JWT_TOKEN_ISSUER'),
+            accessToken: accessToken,
+            user: payload
+        }
+    }
 }

+ 1 - 1
src/iam/register/dto/register-user.dto.ts

@@ -1,3 +1,3 @@
-import { UserDto } from '../../../users/dto/user.dto';
+import { UserDto } from '../../../users/dto/user.dto'
 
 export class RegisterUserDto extends UserDto {}

+ 71 - 71
src/iam/register/register.controller.spec.ts

@@ -1,81 +1,81 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { RegisterController } from './register.controller';
-import { RegisterService } from './register.service';
-import { UsersService } from '../../users/users.service';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { ConfigService } from '@nestjs/config';
-import { RegisterUserDto } from './dto/register-user.dto';
-import { BadRequestException } from '@nestjs/common';
+import { Test, TestingModule } from '@nestjs/testing'
+import { RegisterController } from './register.controller'
+import { RegisterService } from './register.service'
+import { UsersService } from '../../users/users.service'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { ConfigService } from '@nestjs/config'
+import { RegisterUserDto } from './dto/register-user.dto'
+import { BadRequestException } from '@nestjs/common'
 
 const registerUserDto: RegisterUserDto = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'password123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'password123'
+}
 
 describe('Register Controller', () => {
-  let registerController: RegisterController;
-  let registerService: RegisterService;
+    let registerController: RegisterController
+    let registerService: RegisterService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      controllers: [RegisterController],
-      providers: [
-        RegisterService,
-        {
-          provide: MailerService,
-          useValue: {
-            sendMail: jest.fn(),
-          },
-        },
-        {
-          provide: ConfigService,
-          useValue: {
-            get: jest.fn().mockReturnValue('some string'),
-          },
-        },
-        {
-          provide: UsersService,
-          useValue: {
-            register: jest.fn(() => {}),
-          },
-        },
-        {
-          provide: RegisterService,
-          useValue: {
-            register: jest.fn(() => {}),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            controllers: [RegisterController],
+            providers: [
+                RegisterService,
+                {
+                    provide: MailerService,
+                    useValue: {
+                        sendMail: jest.fn()
+                    }
+                },
+                {
+                    provide: ConfigService,
+                    useValue: {
+                        get: jest.fn().mockReturnValue('some string')
+                    }
+                },
+                {
+                    provide: UsersService,
+                    useValue: {
+                        register: jest.fn(() => {})
+                    }
+                },
+                {
+                    provide: RegisterService,
+                    useValue: {
+                        register: jest.fn(() => {})
+                    }
+                }
+            ]
+        }).compile()
 
-    registerController = module.get<RegisterController>(RegisterController);
-    registerService = module.get<RegisterService>(RegisterService);
-  });
+        registerController = module.get<RegisterController>(RegisterController)
+        registerService = module.get<RegisterService>(RegisterService)
+    })
 
-  describe('Registration user', () => {
-    it('should be defined', () => {
-      expect(registerController).toBeDefined();
-    });
+    describe('Registration user', () => {
+        it('should be defined', () => {
+            expect(registerController).toBeDefined()
+        })
 
-    it('should call method register in registerService', async () => {
-      const createSpy = jest.spyOn(registerService, 'register');
+        it('should call method register in registerService', async () => {
+            const createSpy = jest.spyOn(registerService, 'register')
 
-      await registerController.register(registerUserDto);
-      expect(createSpy).toHaveBeenCalledWith(registerUserDto);
-    });
+            await registerController.register(registerUserDto)
+            expect(createSpy).toHaveBeenCalledWith(registerUserDto)
+        })
 
-    it('should throw an exception if it not register fails', async () => {
-      registerService.register = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        registerController.register({
-          name: 'not a correct name',
-          email: 'not a correct email',
-          username: 'not a correct username',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(BadRequestException);
-    });
-  });
-});
+        it('should throw an exception if it not register fails', async () => {
+            registerService.register = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                registerController.register({
+                    name: 'not a correct name',
+                    email: 'not a correct email',
+                    username: 'not a correct username',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(BadRequestException)
+        })
+    })
+})

+ 18 - 26
src/iam/register/register.controller.ts

@@ -1,35 +1,27 @@
-import {
-  Controller,
-  Post,
-  Body,
-  HttpStatus,
-  BadRequestException,
-} from '@nestjs/common';
-import { RegisterService } from './register.service';
-import { RegisterUserDto } from './dto/register-user.dto';
-import { ApiTags } from '@nestjs/swagger';
-import { AuthType } from '../login/enums/auth-type.enum';
-import { AuthGuard } from '../login/decorators/auth-guard.decorator';
+import { Controller, Post, Body, HttpStatus, BadRequestException } from '@nestjs/common'
+import { RegisterService } from './register.service'
+import { RegisterUserDto } from './dto/register-user.dto'
+import { ApiTags } from '@nestjs/swagger'
+import { AuthType } from '../login/enums/auth-type.enum'
+import { AuthGuard } from '../login/decorators/auth-guard.decorator'
 
 @ApiTags('auth')
 @AuthGuard(AuthType.None)
 @Controller('auth/register')
 export class RegisterController {
-  constructor(private readonly registerService: RegisterService) {}
+    constructor(private readonly registerService: RegisterService) {}
 
-  @Post()
-  public async register(
-    @Body() registerUserDto: RegisterUserDto,
-  ): Promise<any> {
-    try {
-      await this.registerService.register(registerUserDto);
+    @Post()
+    public async register(@Body() registerUserDto: RegisterUserDto): Promise<any> {
+        try {
+            await this.registerService.register(registerUserDto)
 
-      return {
-        message: 'User registration successfully!',
-        status: HttpStatus.CREATED,
-      };
-    } catch (err) {
-      throw new BadRequestException(err, 'Error: User not registration!');
+            return {
+                message: 'User registration successfully!',
+                status: HttpStatus.CREATED
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: User not registration!')
+        }
     }
-  }
 }

+ 19 - 19
src/iam/register/register.module.ts

@@ -1,23 +1,23 @@
-import { Module } from '@nestjs/common';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { BcryptService } from '../../shared/hashing/bcrypt.service';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { MailerModule } from '../../shared/mailer/mailer.module';
-import { Users } from '../../users/entities/users.entity';
-import { UsersService } from '../../users/users.service';
-import { RegisterController } from './register.controller';
-import { RegisterService } from './register.service';
+import { Module } from '@nestjs/common'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { BcryptService } from '../../shared/hashing/bcrypt.service'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { MailerModule } from '../../shared/mailer/mailer.module'
+import { Users } from '../../users/entities/users.entity'
+import { UsersService } from '../../users/users.service'
+import { RegisterController } from './register.controller'
+import { RegisterService } from './register.service'
 
 @Module({
-  imports: [TypeOrmModule.forFeature([Users]), MailerModule],
-  controllers: [RegisterController],
-  providers: [
-    {
-      provide: HashingService,
-      useClass: BcryptService,
-    },
-    RegisterService,
-    UsersService,
-  ],
+    imports: [TypeOrmModule.forFeature([Users]), MailerModule],
+    controllers: [RegisterController],
+    providers: [
+        {
+            provide: HashingService,
+            useClass: BcryptService
+        },
+        RegisterService,
+        UsersService
+    ]
 })
 export class RegisterModule {}

+ 72 - 72
src/iam/register/register.service.spec.ts

@@ -1,80 +1,80 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { UsersService } from '../../users/users.service';
-import { RegisterService } from './register.service';
-import { Users } from '../../users/entities/users.entity';
-import { getRepositoryToken } from '@nestjs/typeorm';
-import { RegisterUserDto } from './dto/register-user.dto';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { ConfigService } from '@nestjs/config';
-import { Repository } from 'typeorm';
+import { Test, TestingModule } from '@nestjs/testing'
+import { UsersService } from '../../users/users.service'
+import { RegisterService } from './register.service'
+import { Users } from '../../users/entities/users.entity'
+import { getRepositoryToken } from '@nestjs/typeorm'
+import { RegisterUserDto } from './dto/register-user.dto'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { ConfigService } from '@nestjs/config'
+import { Repository } from 'typeorm'
 
 const registerUserDto: RegisterUserDto = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'password123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'password123'
+}
 
 describe('RegisterService', () => {
-  let service: RegisterService;
-  let repository: Repository<Users>;
+    let service: RegisterService
+    let repository: Repository<Users>
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        RegisterService,
-        {
-          provide: UsersService,
-          useValue: {
-            create: jest.fn().mockResolvedValue(registerUserDto),
-          },
-        },
-        {
-          provide: MailerService,
-          useValue: {
-            sendMail: jest.fn(),
-          },
-        },
-        {
-          provide: ConfigService,
-          useValue: {
-            get: jest.fn().mockReturnValue('some string'),
-          },
-        },
-        {
-          provide: HashingService,
-          useValue: {
-            hash: jest.fn(),
-          },
-        },
-        {
-          provide: getRepositoryToken(Users),
-          useValue: {
-            save: jest.fn(),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                RegisterService,
+                {
+                    provide: UsersService,
+                    useValue: {
+                        create: jest.fn().mockResolvedValue(registerUserDto)
+                    }
+                },
+                {
+                    provide: MailerService,
+                    useValue: {
+                        sendMail: jest.fn()
+                    }
+                },
+                {
+                    provide: ConfigService,
+                    useValue: {
+                        get: jest.fn().mockReturnValue('some string')
+                    }
+                },
+                {
+                    provide: HashingService,
+                    useValue: {
+                        hash: jest.fn()
+                    }
+                },
+                {
+                    provide: getRepositoryToken(Users),
+                    useValue: {
+                        save: jest.fn()
+                    }
+                }
+            ]
+        }).compile()
 
-    service = module.get<RegisterService>(RegisterService);
-    repository = module.get<Repository<Users>>(getRepositoryToken(Users));
-  });
+        service = module.get<RegisterService>(RegisterService)
+        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
+    })
 
-  describe('Create user', () => {
-    it('should be defined', () => {
-      expect(service).toBeDefined();
-    });
+    describe('Create user', () => {
+        it('should be defined', () => {
+            expect(service).toBeDefined()
+        })
 
-    it('should create a user during registration', async () => {
-      expect(
-        await service.register({
-          name: 'name #1',
-          username: 'username #1',
-          email: 'test@example.com',
-          password: 'password123',
-        }),
-      ).toEqual(registerUserDto);
-    });
-  });
-});
+        it('should create a user during registration', async () => {
+            expect(
+                await service.register({
+                    name: 'name #1',
+                    username: 'username #1',
+                    email: 'test@example.com',
+                    password: 'password123'
+                })
+            ).toEqual(registerUserDto)
+        })
+    })
+})

+ 34 - 37
src/iam/register/register.service.ts

@@ -1,46 +1,43 @@
-import { Injectable, Logger } from '@nestjs/common';
-import { HashingService } from '../../shared/hashing/hashing.service';
-import { MailerService } from '../../shared/mailer/mailer.service';
-import { IUsers } from '../../users/interfaces/users.interface';
-import { UsersService } from '../../users/users.service';
-import { RegisterUserDto } from './dto/register-user.dto';
+import { Injectable, Logger } from '@nestjs/common'
+import { HashingService } from '../../shared/hashing/hashing.service'
+import { MailerService } from '../../shared/mailer/mailer.service'
+import { IUsers } from '../../users/interfaces/users.interface'
+import { UsersService } from '../../users/users.service'
+import { RegisterUserDto } from './dto/register-user.dto'
 
 @Injectable()
 export class RegisterService {
-  constructor(
-    private readonly usersService: UsersService,
-    private readonly mailerService: MailerService,
-    private readonly hashingService: HashingService,
-  ) {}
+    constructor(
+        private readonly usersService: UsersService,
+        private readonly mailerService: MailerService,
+        private readonly hashingService: HashingService
+    ) {}
 
-  public async register(registerUserDto: RegisterUserDto): Promise<IUsers> {
-    registerUserDto.password = await this.hashingService.hash(
-      registerUserDto.password,
-    );
+    public async register(registerUserDto: RegisterUserDto): Promise<IUsers> {
+        registerUserDto.password = await this.hashingService.hash(registerUserDto.password)
 
-    this.sendMailRegisterUser(registerUserDto);
+        this.sendMailRegisterUser(registerUserDto)
 
-    return this.usersService.create(registerUserDto);
-  }
+        return this.usersService.create(registerUserDto)
+    }
 
-  private sendMailRegisterUser(user): void {
-    try {
-      this.mailerService.sendMail({
-        to: user.email,
-        from: 'from@example.com',
-        subject: 'Registration successful ✔',
-        text: 'Registration successful!',
-        template: 'index',
-        context: {
-          title: 'Registration successfully',
-          description:
-            "You did it! You registered!, You're successfully registered.✔",
-          nameUser: user.name,
-        },
-      });
-      Logger.log('[MailService] User Registration: Send Mail successfully!');
-    } catch (err) {
-      Logger.error('[MailService] User Registration: Send Mail failed!', err);
+    private sendMailRegisterUser(user): void {
+        try {
+            this.mailerService.sendMail({
+                to: user.email,
+                from: 'from@example.com',
+                subject: 'Registration successful ✔',
+                text: 'Registration successful!',
+                template: 'index',
+                context: {
+                    title: 'Registration successfully',
+                    description: "You did it! You registered!, You're successfully registered.✔",
+                    nameUser: user.name
+                }
+            })
+            Logger.log('[MailService] User Registration: Send Mail successfully!')
+        } catch (err) {
+            Logger.error('[MailService] User Registration: Send Mail failed!', err)
+        }
     }
-  }
 }

+ 28 - 28
src/main.ts

@@ -1,34 +1,34 @@
-import { NestFactory } from '@nestjs/core';
-import { AppModule } from './app.module';
-import { Logger, ValidationPipe } from '@nestjs/common';
-import { ConfigService } from '@nestjs/config';
-import { configureSwaggerDocs } from './helpers/configure-swagger-docs.helper';
+import { NestFactory } from '@nestjs/core'
+import { AppModule } from './app.module'
+import { Logger, ValidationPipe } from '@nestjs/common'
+import { ConfigService } from '@nestjs/config'
+import { configureSwaggerDocs } from './helpers/configure-swagger-docs.helper'
 
 async function bootstrap() {
-  const app = await NestFactory.create(AppModule);
-  const configService = app.get<ConfigService>(ConfigService);
+    const app = await NestFactory.create(AppModule)
+    const configService = app.get<ConfigService>(ConfigService)
 
-  app.setGlobalPrefix('api');
-  app.useGlobalPipes(
-    new ValidationPipe({
-      whitelist: true,
-      transform: true,
-      forbidNonWhitelisted: true,
-      transformOptions: {
-        enableImplicitConversion: true,
-      },
-    }),
-  );
+    app.setGlobalPrefix('api')
+    app.useGlobalPipes(
+        new ValidationPipe({
+            whitelist: true,
+            transform: true,
+            forbidNonWhitelisted: true,
+            transformOptions: {
+                enableImplicitConversion: true
+            }
+        })
+    )
 
-  configureSwaggerDocs(app, configService);
+    configureSwaggerDocs(app, configService)
 
-  app.enableCors({
-    origin: configService.get<string>('ENDPOINT_CORS'),
-    methods: 'GET,POST,PUT,PATCH,DELETE',
-    credentials: true,
-  });
-  const port = configService.get<number>('NODE_API_PORT') || 3000;
-  await app.listen(port);
-  Logger.log(`Url for OpenApi: ${await app.getUrl()}/docs`, 'Swagger');
+    app.enableCors({
+        origin: configService.get<string>('ENDPOINT_CORS'),
+        methods: 'GET,POST,PUT,PATCH,DELETE',
+        credentials: true
+    })
+    const port = configService.get<number>('NODE_API_PORT') || 3000
+    await app.listen(port)
+    Logger.log(`Url for OpenApi: ${await app.getUrl()}/docs`, 'Swagger')
 }
-bootstrap();
+bootstrap()

+ 6 - 4
src/migrations/1589834500772-Api.ts

@@ -1,14 +1,16 @@
-import {MigrationInterface, QueryRunner} from "typeorm";
+import { MigrationInterface, QueryRunner } from 'typeorm'
 
 export class Api1589834500772 implements MigrationInterface {
     name = 'Api1589834500772'
 
     public async up(queryRunner: QueryRunner): Promise<void> {
-        await queryRunner.query("CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(60) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB", undefined);
+        await queryRunner.query(
+            'CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(60) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB',
+            undefined
+        )
     }
 
     public async down(queryRunner: QueryRunner): Promise<void> {
-        await queryRunner.query("DROP TABLE `user`", undefined);
+        await queryRunner.query('DROP TABLE `user`', undefined)
     }
-
 }

+ 4 - 4
src/repl.ts

@@ -1,7 +1,7 @@
-import { repl } from '@nestjs/core';
-import { AppModule } from './app.module';
+import { repl } from '@nestjs/core'
+import { AppModule } from './app.module'
 
 async function bootstrap() {
-  await repl(AppModule);
+    await repl(AppModule)
 }
-bootstrap();
+bootstrap()

+ 21 - 21
src/shared/hashing/bcrypt.service.spec.ts

@@ -1,26 +1,26 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { BcryptService } from './bcrypt.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { BcryptService } from './bcrypt.service'
 
 describe('BcryptService', () => {
-  let service: BcryptService;
+    let service: BcryptService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        {
-          provide: BcryptService,
-          useValue: {
-            hash: jest.fn(() => 'pass123'),
-            compare: jest.fn(() => true),
-          },
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                {
+                    provide: BcryptService,
+                    useValue: {
+                        hash: jest.fn(() => 'pass123'),
+                        compare: jest.fn(() => true)
+                    }
+                }
+            ]
+        }).compile()
 
-    service = module.get<BcryptService>(BcryptService);
-  });
+        service = module.get<BcryptService>(BcryptService)
+    })
 
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});
+    it('should be defined', () => {
+        expect(service).toBeDefined()
+    })
+})

+ 10 - 10
src/shared/hashing/bcrypt.service.ts

@@ -1,15 +1,15 @@
-import { Injectable } from '@nestjs/common';
-import { compare, genSalt, hash } from 'bcrypt';
-import { HashingService } from './hashing.service';
+import { Injectable } from '@nestjs/common'
+import { compare, genSalt, hash } from 'bcrypt'
+import { HashingService } from './hashing.service'
 
 @Injectable()
 export class BcryptService implements HashingService {
-  async hash(data: string | Buffer): Promise<string> {
-    const salt = await genSalt();
-    return hash(data, salt);
-  }
+    async hash(data: string | Buffer): Promise<string> {
+        const salt = await genSalt()
+        return hash(data, salt)
+    }
 
-  compare(data: string | Buffer, encrypted: string): Promise<boolean> {
-    return compare(data, encrypted);
-  }
+    compare(data: string | Buffer, encrypted: string): Promise<boolean> {
+        return compare(data, encrypted)
+    }
 }

+ 19 - 19
src/shared/hashing/hashing.service.spec.ts

@@ -1,24 +1,24 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { BcryptService } from './bcrypt.service';
-import { HashingService } from './hashing.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { BcryptService } from './bcrypt.service'
+import { HashingService } from './hashing.service'
 
 describe('HashingService', () => {
-  let service: HashingService;
+    let service: HashingService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        {
-          provide: HashingService,
-          useClass: BcryptService,
-        },
-      ],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                {
+                    provide: HashingService,
+                    useClass: BcryptService
+                }
+            ]
+        }).compile()
 
-    service = module.get<HashingService>(HashingService);
-  });
+        service = module.get<HashingService>(HashingService)
+    })
 
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});
+    it('should be defined', () => {
+        expect(service).toBeDefined()
+    })
+})

+ 3 - 3
src/shared/hashing/hashing.service.ts

@@ -1,7 +1,7 @@
-import { Injectable } from '@nestjs/common';
+import { Injectable } from '@nestjs/common'
 
 @Injectable()
 export abstract class HashingService {
-  abstract hash(data: string | Buffer): Promise<string>;
-  abstract compare(data: string | Buffer, encrypted: string): Promise<boolean>;
+    abstract hash(data: string | Buffer): Promise<string>
+    abstract compare(data: string | Buffer, encrypted: string): Promise<boolean>
 }

+ 6 - 6
src/shared/mailer/mailer.module.ts

@@ -1,10 +1,10 @@
-import { Module } from '@nestjs/common';
-import { MailerService } from './mailer.service';
-import { ConfigModule } from '@nestjs/config';
+import { Module } from '@nestjs/common'
+import { MailerService } from './mailer.service'
+import { ConfigModule } from '@nestjs/config'
 
 @Module({
-  imports: [ConfigModule.forRoot({ isGlobal: true })],
-  providers: [MailerService],
-  exports: [MailerService],
+    imports: [ConfigModule.forRoot({ isGlobal: true })],
+    providers: [MailerService],
+    exports: [MailerService]
 })
 export class MailerModule {}

+ 14 - 14
src/shared/mailer/mailer.service.spec.ts

@@ -1,19 +1,19 @@
-import { ConfigService } from '@nestjs/config';
-import { Test, TestingModule } from '@nestjs/testing';
-import { MailerService } from './mailer.service';
+import { ConfigService } from '@nestjs/config'
+import { Test, TestingModule } from '@nestjs/testing'
+import { MailerService } from './mailer.service'
 
 describe('MailerService', () => {
-  let service: MailerService;
+    let service: MailerService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [ConfigService, MailerService],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [ConfigService, MailerService]
+        }).compile()
 
-    service = module.get<MailerService>(MailerService);
-  });
+        service = module.get<MailerService>(MailerService)
+    })
 
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});
+    it('should be defined', () => {
+        expect(service).toBeDefined()
+    })
+})

+ 32 - 39
src/shared/mailer/mailer.service.ts

@@ -1,46 +1,39 @@
-import { Injectable } from '@nestjs/common';
-import { createTransport } from 'nodemailer';
-import * as Mail from 'nodemailer/lib/mailer';
-import { ConfigService } from '@nestjs/config';
-import * as hbs from 'nodemailer-express-handlebars';
+import { Injectable } from '@nestjs/common'
+import { createTransport } from 'nodemailer'
+import * as Mail from 'nodemailer/lib/mailer'
+import { ConfigService } from '@nestjs/config'
+import * as hbs from 'nodemailer-express-handlebars'
 
 @Injectable()
 export class MailerService {
-  private nodemailerTransport: Mail;
+    private nodemailerTransport: Mail
 
-  constructor(private readonly configService: ConfigService) {
-    this.nodemailerTransport = createTransport({
-      host: this.configService.get<string>('EMAIL_HOST'),
-      port: this.configService.get<number>('EMAIL_PORT'),
-      auth: {
-        user: this.configService.get<string>('EMAIL_AUTH_USER'),
-        pass: this.configService.get<string>('EMAIL_AUTH_PASSWORD'),
-      },
-      debug: this.configService.get<boolean>('EMAIL_DEBUG'),
-      logger: false,
-    });
+    constructor(private readonly configService: ConfigService) {
+        this.nodemailerTransport = createTransport({
+            host: this.configService.get<string>('EMAIL_HOST'),
+            port: this.configService.get<number>('EMAIL_PORT'),
+            auth: {
+                user: this.configService.get<string>('EMAIL_AUTH_USER'),
+                pass: this.configService.get<string>('EMAIL_AUTH_PASSWORD')
+            },
+            debug: this.configService.get<boolean>('EMAIL_DEBUG'),
+            logger: false
+        })
 
-    const options = {
-      viewEngine: {
-        extname: '.hbs', // handlebars extension
-        layoutsDir:
-          process.cwd() +
-          `${this.configService.get<string>('EMAIL_LAYOUT_DIR')}`, // location of handlebars templates
-        defaultLayout: `${this.configService.get<string>(
-          'EMAIL_DEFAULT_LAYOUT',
-        )}`, // name of main template
-        partialsDir:
-          process.cwd() +
-          `${this.configService.get<string>('EMAIL_PARTIAL_DIR')}`, // location of your subtemplates aka. header, footer etc
-      },
-      viewPath:
-        process.cwd() + `${this.configService.get<string>('EMAIL_VIEW_PATH')}`,
-      extName: '.hbs',
-    };
-    this.nodemailerTransport.use('compile', hbs(options));
-  }
+        const options = {
+            viewEngine: {
+                extname: '.hbs', // handlebars extension
+                layoutsDir: process.cwd() + `${this.configService.get<string>('EMAIL_LAYOUT_DIR')}`, // location of handlebars templates
+                defaultLayout: `${this.configService.get<string>('EMAIL_DEFAULT_LAYOUT')}`, // name of main template
+                partialsDir: process.cwd() + `${this.configService.get<string>('EMAIL_PARTIAL_DIR')}` // location of your subtemplates aka. header, footer etc
+            },
+            viewPath: process.cwd() + `${this.configService.get<string>('EMAIL_VIEW_PATH')}`,
+            extName: '.hbs'
+        }
+        this.nodemailerTransport.use('compile', hbs(options))
+    }
 
-  sendMail(options: any) {
-    return this.nodemailerTransport.sendMail(options);
-  }
+    sendMail(options: any) {
+        return this.nodemailerTransport.sendMail(options)
+    }
 }

+ 4 - 4
src/shared/utils/utils.module.ts

@@ -1,8 +1,8 @@
-import { Module } from '@nestjs/common';
-import { UtilsService } from './utils.service';
+import { Module } from '@nestjs/common'
+import { UtilsService } from './utils.service'
 
 @Module({
-  providers: [UtilsService],
-  exports: [UtilsService],
+    providers: [UtilsService],
+    exports: [UtilsService]
 })
 export class UtilsModule {}

+ 13 - 13
src/shared/utils/utils.service.spec.ts

@@ -1,18 +1,18 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { UtilsService } from './utils.service';
+import { Test, TestingModule } from '@nestjs/testing'
+import { UtilsService } from './utils.service'
 
 describe('UtilsService', () => {
-  let service: UtilsService;
+    let service: UtilsService
 
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [UtilsService],
-    }).compile();
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [UtilsService]
+        }).compile()
 
-    service = module.get<UtilsService>(UtilsService);
-  });
+        service = module.get<UtilsService>(UtilsService)
+    })
 
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});
+    it('should be defined', () => {
+        expect(service).toBeDefined()
+    })
+})

+ 5 - 5
src/shared/utils/utils.service.ts

@@ -1,9 +1,9 @@
-import { Injectable } from '@nestjs/common';
-import * as crypto from 'crypto';
+import { Injectable } from '@nestjs/common'
+import * as crypto from 'crypto'
 
 @Injectable()
 export class UtilsService {
-  public generatePassword(): string {
-    return crypto.randomUUID();
-  }
+    public generatePassword(): string {
+        return crypto.randomUUID()
+    }
 }

+ 2 - 2
src/users/dto/user-profile.dto.ts

@@ -1,4 +1,4 @@
-import { OmitType } from '@nestjs/swagger';
-import { UserDto } from './user.dto';
+import { OmitType } from '@nestjs/swagger'
+import { UserDto } from './user.dto'
 
 export class UserProfileDto extends OmitType(UserDto, ['password'] as const) {}

+ 2 - 2
src/users/dto/user-update.dto.ts

@@ -1,4 +1,4 @@
-import { PartialType } from '@nestjs/swagger';
-import { UserDto } from './user.dto';
+import { PartialType } from '@nestjs/swagger'
+import { UserDto } from './user.dto'
 
 export class UserUpdateDto extends PartialType(UserDto) {}

+ 15 - 15
src/users/dto/user.dto.ts

@@ -1,21 +1,21 @@
-import { MaxLength, IsNotEmpty, IsEmail, IsString } from 'class-validator';
+import { MaxLength, IsNotEmpty, IsEmail, IsString } from 'class-validator'
 
 export class UserDto {
-  @IsString()
-  @MaxLength(30)
-  readonly name: string;
+    @IsString()
+    @MaxLength(30)
+    readonly name: string
 
-  @IsString()
-  @MaxLength(40)
-  readonly username: string;
+    @IsString()
+    @MaxLength(40)
+    readonly username: string
 
-  @IsEmail()
-  @IsString()
-  @IsNotEmpty()
-  readonly email: string;
+    @IsEmail()
+    @IsString()
+    @IsNotEmpty()
+    readonly email: string
 
-  @IsNotEmpty()
-  @IsString()
-  @MaxLength(60)
-  password: string;
+    @IsNotEmpty()
+    @IsString()
+    @MaxLength(60)
+    password: string
 }

+ 13 - 13
src/users/entities/users.entity.ts

@@ -1,21 +1,21 @@
-import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
 
 @Entity()
 export class Users {
-  @PrimaryGeneratedColumn()
-  id: number;
+    @PrimaryGeneratedColumn()
+    id: number
 
-  @Column()
-  name: string;
+    @Column()
+    name: string
 
-  @Column()
-  username: string;
+    @Column()
+    username: string
 
-  @Column({
-    unique: true,
-  })
-  email: string;
+    @Column({
+        unique: true
+    })
+    email: string
 
-  @Column({ length: 60 })
-  password: string;
+    @Column({ length: 60 })
+    password: string
 }

+ 5 - 5
src/users/interfaces/users.interface.ts

@@ -1,7 +1,7 @@
 export interface IUsers {
-  readonly id: number;
-  readonly name: string;
-  readonly username: string;
-  readonly email: string;
-  readonly password: string;
+    readonly id: number
+    readonly name: string
+    readonly username: string
+    readonly email: string
+    readonly password: string
 }

+ 132 - 134
src/users/users.controller.spec.ts

@@ -1,142 +1,140 @@
-import { BadRequestException, NotFoundException } from '@nestjs/common';
-import { Test, TestingModule } from '@nestjs/testing';
-import { UserProfileDto } from './dto/user-profile.dto';
-import { UserDto } from './dto/user.dto';
-import { UsersController } from './users.controller';
-import { UsersService } from './users.service';
+import { BadRequestException, NotFoundException } from '@nestjs/common'
+import { Test, TestingModule } from '@nestjs/testing'
+import { UserProfileDto } from './dto/user-profile.dto'
+import { UserDto } from './dto/user.dto'
+import { UsersController } from './users.controller'
+import { UsersService } from './users.service'
 
 const userDto: UserDto = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'password123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'password123'
+}
 
 const userUpdateDto: UserDto = {
-  name: 'name #1 update',
-  username: 'username #1 update',
-  email: 'test@example.com',
-  password: 'password123',
-};
+    name: 'name #1 update',
+    username: 'username #1 update',
+    email: 'test@example.com',
+    password: 'password123'
+}
 
 const userProfileDto: UserProfileDto = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com'
+}
 
 describe('Users Controller', () => {
-  let usersController: UsersController;
-  let usersService: UsersService;
-
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      controllers: [UsersController],
-      providers: [
-        {
-          provide: UsersService,
-          useValue: {
-            findAll: jest.fn(() => {}),
-            findById: jest.fn(() => userDto),
-            updateProfileUser: jest.fn(() => {}),
-            updateUser: jest.fn(() => {}),
-            deleteUser: jest.fn(() => userDto),
-          },
-        },
-      ],
-    }).compile();
-
-    usersController = module.get<UsersController>(UsersController);
-    usersService = module.get<UsersService>(UsersService);
-  });
-
-  describe('Users Controller', () => {
-    it('should be defined', () => {
-      expect(usersController).toBeDefined();
-    });
-
-    describe('findAllUser() method', () => {
-      it('should call method findAllUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'findAll');
-
-        await usersController.findAllUser();
-        expect(createSpy).toHaveBeenCalled();
-      });
-    });
-
-    describe('findOneUser() method', () => {
-      it('should call method findOneUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'findById');
-
-        await usersController.findOneUser('anyid');
-        expect(createSpy).toHaveBeenCalledWith('anyid');
-      });
-    });
-
-    describe('findById() method', () => {
-      it('should call method getUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'findById');
-
-        await usersController.getUser('1');
-        expect(createSpy).toHaveBeenCalledWith('1');
-      });
-
-      it('should return an exception if update user fails', async () => {
-        usersService.findById = jest.fn().mockResolvedValueOnce(null);
-        await expect(usersController.getUser('not correct id')).rejects.toThrow(
-          NotFoundException,
-        );
-      });
-    });
-
-    describe('updateProfileUser() method', () => {
-      it('should call method updateProfileUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'updateProfileUser');
-
-        await usersController.updateProfileUser('1', userProfileDto);
-        expect(createSpy).toHaveBeenCalledWith('1', userProfileDto);
-      });
-
-      it('should return an exception if update profile user fails', async () => {
-        usersService.updateProfileUser = jest.fn().mockRejectedValueOnce(null);
-        await expect(
-          usersController.updateProfileUser('not a correct id', {
-            name: 'not a correct name',
-            username: 'not a correct username',
-            email: 'not a correct email',
-          }),
-        ).rejects.toThrow(BadRequestException);
-      });
-    });
-
-    describe('updateUser() method', () => {
-      it('should call method updateUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'updateUser');
-
-        await usersController.updateUser('1', userUpdateDto);
-        expect(createSpy).toHaveBeenCalledWith('1', userUpdateDto);
-      });
-
-      it('should return an exception if update user fails', async () => {
-        usersService.updateUser = jest.fn().mockRejectedValueOnce(null);
-        await expect(
-          usersController.updateUser('not a correct id', {
-            name: 'not a correct name',
-            username: 'not a correct username',
-            email: 'not a correct email',
-            password: 'not a correct password',
-          }),
-        ).rejects.toThrow(BadRequestException);
-      });
-    });
-
-    describe('deleteUser() method', () => {
-      it('should call method deleteUser in userService', async () => {
-        const createSpy = jest.spyOn(usersService, 'deleteUser');
-
-        await usersController.deleteUser('anyid');
-        expect(createSpy).toHaveBeenCalledWith('anyid');
-      });
-    });
-  });
-});
+    let usersController: UsersController
+    let usersService: UsersService
+
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            controllers: [UsersController],
+            providers: [
+                {
+                    provide: UsersService,
+                    useValue: {
+                        findAll: jest.fn(() => {}),
+                        findById: jest.fn(() => userDto),
+                        updateProfileUser: jest.fn(() => {}),
+                        updateUser: jest.fn(() => {}),
+                        deleteUser: jest.fn(() => userDto)
+                    }
+                }
+            ]
+        }).compile()
+
+        usersController = module.get<UsersController>(UsersController)
+        usersService = module.get<UsersService>(UsersService)
+    })
+
+    describe('Users Controller', () => {
+        it('should be defined', () => {
+            expect(usersController).toBeDefined()
+        })
+
+        describe('findAllUser() method', () => {
+            it('should call method findAllUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'findAll')
+
+                await usersController.findAllUser()
+                expect(createSpy).toHaveBeenCalled()
+            })
+        })
+
+        describe('findOneUser() method', () => {
+            it('should call method findOneUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'findById')
+
+                await usersController.findOneUser('anyid')
+                expect(createSpy).toHaveBeenCalledWith('anyid')
+            })
+        })
+
+        describe('findById() method', () => {
+            it('should call method getUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'findById')
+
+                await usersController.getUser('1')
+                expect(createSpy).toHaveBeenCalledWith('1')
+            })
+
+            it('should return an exception if update user fails', async () => {
+                usersService.findById = jest.fn().mockResolvedValueOnce(null)
+                await expect(usersController.getUser('not correct id')).rejects.toThrow(NotFoundException)
+            })
+        })
+
+        describe('updateProfileUser() method', () => {
+            it('should call method updateProfileUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'updateProfileUser')
+
+                await usersController.updateProfileUser('1', userProfileDto)
+                expect(createSpy).toHaveBeenCalledWith('1', userProfileDto)
+            })
+
+            it('should return an exception if update profile user fails', async () => {
+                usersService.updateProfileUser = jest.fn().mockRejectedValueOnce(null)
+                await expect(
+                    usersController.updateProfileUser('not a correct id', {
+                        name: 'not a correct name',
+                        username: 'not a correct username',
+                        email: 'not a correct email'
+                    })
+                ).rejects.toThrow(BadRequestException)
+            })
+        })
+
+        describe('updateUser() method', () => {
+            it('should call method updateUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'updateUser')
+
+                await usersController.updateUser('1', userUpdateDto)
+                expect(createSpy).toHaveBeenCalledWith('1', userUpdateDto)
+            })
+
+            it('should return an exception if update user fails', async () => {
+                usersService.updateUser = jest.fn().mockRejectedValueOnce(null)
+                await expect(
+                    usersController.updateUser('not a correct id', {
+                        name: 'not a correct name',
+                        username: 'not a correct username',
+                        email: 'not a correct email',
+                        password: 'not a correct password'
+                    })
+                ).rejects.toThrow(BadRequestException)
+            })
+        })
+
+        describe('deleteUser() method', () => {
+            it('should call method deleteUser in userService', async () => {
+                const createSpy = jest.spyOn(usersService, 'deleteUser')
+
+                await usersController.deleteUser('anyid')
+                expect(createSpy).toHaveBeenCalledWith('anyid')
+            })
+        })
+    })
+})

+ 66 - 69
src/users/users.controller.ts

@@ -1,88 +1,85 @@
 import {
-  Controller,
-  Put,
-  Get,
-  Body,
-  Param,
-  HttpStatus,
-  NotFoundException,
-  Delete,
-  BadRequestException,
-} from '@nestjs/common';
-import { UsersService } from './users.service';
-import { UserProfileDto } from './dto/user-profile.dto';
-import { UserUpdateDto } from './dto/user-update.dto';
-import { IUsers } from './interfaces/users.interface';
-import { ApiTags } from '@nestjs/swagger';
-import { AuthGuard } from '../iam/login/decorators/auth-guard.decorator';
-import { AuthType } from '../iam/login/enums/auth-type.enum';
+    Controller,
+    Put,
+    Get,
+    Body,
+    Param,
+    HttpStatus,
+    NotFoundException,
+    Delete,
+    BadRequestException
+} from '@nestjs/common'
+import { UsersService } from './users.service'
+import { UserProfileDto } from './dto/user-profile.dto'
+import { UserUpdateDto } from './dto/user-update.dto'
+import { IUsers } from './interfaces/users.interface'
+import { ApiTags } from '@nestjs/swagger'
+import { AuthGuard } from '../iam/login/decorators/auth-guard.decorator'
+import { AuthType } from '../iam/login/enums/auth-type.enum'
 
 @ApiTags('users')
 @AuthGuard(AuthType.Bearer)
 @Controller('users')
 export class UsersController {
-  constructor(private readonly usersService: UsersService) {}
+    constructor(private readonly usersService: UsersService) {}
 
-  @Get()
-  public async findAllUser(): Promise<IUsers[]> {
-    return this.usersService.findAll();
-  }
+    @Get()
+    public async findAllUser(): Promise<IUsers[]> {
+        return this.usersService.findAll()
+    }
 
-  @Get('/:userId')
-  public async findOneUser(@Param('userId') userId: string): Promise<IUsers> {
-    return this.usersService.findById(userId);
-  }
+    @Get('/:userId')
+    public async findOneUser(@Param('userId') userId: string): Promise<IUsers> {
+        return this.usersService.findById(userId)
+    }
 
-  @Get('/:userId/profile')
-  public async getUser(@Param('userId') userId: string): Promise<any> {
-    const user = await this.findOneUser(userId);
+    @Get('/:userId/profile')
+    public async getUser(@Param('userId') userId: string): Promise<any> {
+        const user = await this.findOneUser(userId)
 
-    if (!user) {
-      throw new NotFoundException('User does not exist!');
-    }
+        if (!user) {
+            throw new NotFoundException('User does not exist!')
+        }
 
-    return {
-      user: user,
-      status: HttpStatus.OK,
-    };
-  }
+        return {
+            user: user,
+            status: HttpStatus.OK
+        }
+    }
 
-  @Put('/:userId/profile')
-  public async updateProfileUser(
-    @Param('userId') userId: string,
-    @Body() userProfileDto: UserProfileDto,
-  ): Promise<any> {
-    try {
-      await this.usersService.updateProfileUser(userId, userProfileDto);
+    @Put('/:userId/profile')
+    public async updateProfileUser(
+        @Param('userId') userId: string,
+        @Body() userProfileDto: UserProfileDto
+    ): Promise<any> {
+        try {
+            await this.usersService.updateProfileUser(userId, userProfileDto)
 
-      return {
-        message: 'User Updated successfully!',
-        status: HttpStatus.OK,
-      };
-    } catch (err) {
-      throw new BadRequestException(err, 'Error: User not updated!');
+            return {
+                message: 'User Updated successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: User not updated!')
+        }
     }
-  }
 
-  @Put('/:userId')
-  public async updateUser(
-    @Param('userId') userId: string,
-    @Body() userUpdateDto: UserUpdateDto,
-  ) {
-    try {
-      await this.usersService.updateUser(userId, userUpdateDto);
+    @Put('/:userId')
+    public async updateUser(@Param('userId') userId: string, @Body() userUpdateDto: UserUpdateDto) {
+        try {
+            await this.usersService.updateUser(userId, userUpdateDto)
 
-      return {
-        message: 'User Updated successfully!',
-        status: HttpStatus.OK,
-      };
-    } catch (err) {
-      throw new BadRequestException(err, 'Error: User not updated!');
+            return {
+                message: 'User Updated successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: User not updated!')
+        }
     }
-  }
 
-  @Delete('/:userId')
-  public async deleteUser(@Param('userId') userId: string): Promise<void> {
-    await this.usersService.deleteUser(userId);
-  }
+    @Delete('/:userId')
+    public async deleteUser(@Param('userId') userId: string): Promise<void> {
+        await this.usersService.deleteUser(userId)
+    }
 }

+ 17 - 17
src/users/users.module.ts

@@ -1,21 +1,21 @@
-import { Module } from '@nestjs/common';
-import { TypeOrmModule } from '@nestjs/typeorm';
-import { Users } from './entities/users.entity';
-import { UsersService } from './users.service';
-import { UsersController } from './users.controller';
-import { MailerModule } from '../shared/mailer/mailer.module';
-import { BcryptService } from '../shared/hashing/bcrypt.service';
-import { HashingService } from '../shared/hashing/hashing.service';
+import { Module } from '@nestjs/common'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Users } from './entities/users.entity'
+import { UsersService } from './users.service'
+import { UsersController } from './users.controller'
+import { MailerModule } from '../shared/mailer/mailer.module'
+import { BcryptService } from '../shared/hashing/bcrypt.service'
+import { HashingService } from '../shared/hashing/hashing.service'
 
 @Module({
-  imports: [TypeOrmModule.forFeature([Users]), MailerModule],
-  controllers: [UsersController],
-  providers: [
-    {
-      provide: HashingService,
-      useClass: BcryptService,
-    },
-    UsersService,
-  ],
+    imports: [TypeOrmModule.forFeature([Users]), MailerModule],
+    controllers: [UsersController],
+    providers: [
+        {
+            provide: HashingService,
+            useClass: BcryptService
+        },
+        UsersService
+    ]
 })
 export class UsersModule {}

+ 218 - 232
src/users/users.service.spec.ts

@@ -1,249 +1,235 @@
-import { HttpException, HttpStatus, NotFoundException } from '@nestjs/common';
-import { Test, TestingModule } from '@nestjs/testing';
-import { getRepositoryToken } from '@nestjs/typeorm';
-import { Repository } from 'typeorm';
-import { BcryptService } from '../shared/hashing/bcrypt.service';
-import { HashingService } from '../shared/hashing/hashing.service';
-import { UserDto } from './dto/user.dto';
-import { Users } from './entities/users.entity';
-import { UsersService } from './users.service';
+import { HttpException, HttpStatus, NotFoundException } from '@nestjs/common'
+import { Test, TestingModule } from '@nestjs/testing'
+import { getRepositoryToken } from '@nestjs/typeorm'
+import { Repository } from 'typeorm'
+import { BcryptService } from '../shared/hashing/bcrypt.service'
+import { HashingService } from '../shared/hashing/hashing.service'
+import { UserDto } from './dto/user.dto'
+import { Users } from './entities/users.entity'
+import { UsersService } from './users.service'
 
 const userArray = [
-  {
+    {
+        id: 1,
+        name: 'name #1',
+        username: 'username #1',
+        email: 'test1@example.com',
+        password: 'pass123'
+    },
+    {
+        id: 2,
+        name: 'name #2',
+        username: 'username #2',
+        email: 'test2@example.com',
+        password: 'pass123'
+    }
+]
+
+const oneUser = {
     id: 1,
     name: 'name #1',
     username: 'username #1',
-    email: 'test1@example.com',
-    password: 'pass123',
-  },
-  {
-    id: 2,
-    name: 'name #2',
-    username: 'username #2',
-    email: 'test2@example.com',
-    password: 'pass123',
-  },
-];
-
-const oneUser = {
-  id: 1,
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const createUser: UserDto = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const updateUserByEmail = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const updateUserByPassword = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const updateProfileUser = {
-  name: 'name #1',
-  username: 'username #1',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    name: 'name #1',
+    username: 'username #1',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 const updateUser = {
-  id: 1,
-  name: 'name #1 update',
-  username: 'username #1 update',
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    id: 1,
+    name: 'name #1 update',
+    username: 'username #1 update',
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 describe('UsersService', () => {
-  let service: UsersService;
-  let repository: Repository<Users>;
-
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [
-        UsersService,
-        {
-          provide: HashingService,
-          useClass: BcryptService,
-        },
-        {
-          provide: getRepositoryToken(Users),
-          useValue: {
-            find: jest.fn().mockResolvedValue(userArray),
-            findOne: jest.fn().mockResolvedValue(oneUser),
-            findOneBy: jest.fn().mockResolvedValueOnce(oneUser),
-            save: jest.fn().mockReturnValue(createUser),
-            updateByEmail: jest.fn().mockResolvedValue(updateUserByEmail),
-            updateByPassword: jest.fn().mockResolvedValue(updateUserByPassword),
-            updateProfileUser: jest.fn().mockResolvedValue(updateProfileUser),
-            update: jest.fn().mockReturnValue(updateUser),
-            remove: jest.fn(),
-          },
-        },
-      ],
-    }).compile();
-
-    service = module.get<UsersService>(UsersService);
-    repository = module.get<Repository<Users>>(getRepositoryToken(Users));
-  });
-
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-
-  describe('findAll() method', () => {
-    it('should return an array of all users', async () => {
-      const users = await service.findAll();
-      expect(users).toEqual(userArray);
-    });
-  });
-
-  describe('findByEmail() method', () => {
-    it('should find a user by email', async () => {
-      expect(await service.findByEmail('test@example.com')).toEqual(oneUser);
-    });
-
-    it('should throw an exception if it not found a user by email', async () => {
-      repository.findOneBy = jest.fn().mockResolvedValueOnce(null);
-      await expect(service.findByEmail('not a correct email')).rejects.toThrow(
-        NotFoundException,
-      );
-    });
-  });
-  describe('findById() method', () => {
-    it('should find a user by id', async () => {
-      expect(await service.findById('anyid')).toEqual(oneUser);
-    });
-
-    it('should throw an exception if it not found a user by id', async () => {
-      repository.findOneBy = jest.fn().mockResolvedValueOnce(null);
-      await expect(service.findById('not a correct id')).rejects.toThrow(
-        NotFoundException,
-      );
-    });
-  });
-
-  describe('create() method', () => {
-    it('should create a new user', async () => {
-      expect(
-        await service.create({
-          name: 'name #1',
-          username: 'username #1',
-          email: 'test@example.com',
-          password: 'pass123',
-        }),
-      ).toEqual(createUser);
-    });
-
-    it('should return an exception if login fails', async () => {
-      repository.save = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        service.create({
-          name: 'not a correct name',
-          username: 'not a correct username',
-          email: 'not a correct email',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-
-  describe('updateByEmail() method', () => {
-    it('should update a user by email', async () => {
-      expect(await service.updateByEmail('test@example.com')).toEqual(
-        updateUserByEmail,
-      );
-    });
-
-    it('should return an exception if update by email fails', async () => {
-      repository.save = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        service.updateByEmail('not a correct email'),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-
-  describe('updateByPassword() method', () => {
-    it('should update a user by password', async () => {
-      expect(
-        await service.updateByPassword('test@example.com', 'pass123'),
-      ).toEqual(updateUserByPassword);
-    });
-
-    it('should return an exception if update by password fails', async () => {
-      repository.save = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        service.updateByPassword('not a correct email', 'not correct password'),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-
-  describe('updateProfileUser() method', () => {
-    it('should update profile of a user by id', async () => {
-      expect(
-        await service.updateProfileUser('anyid', updateProfileUser),
-      ).toEqual(updateProfileUser);
-    });
-
-    it('should return an exception if update profile user fails', async () => {
-      repository.save = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        service.updateProfileUser('not a correct id', {
-          name: 'not a correct name',
-          username: 'not a correct username',
-          email: 'not a correct email',
-        }),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-
-  describe('updateUser() method', () => {
-    it('should update a user by id', async () => {
-      expect(await service.updateUser('anyid', updateUser)).toEqual(updateUser);
-    });
-
-    it('should return an exception if update profile user fails', async () => {
-      repository.update = jest.fn().mockRejectedValueOnce(null);
-      await expect(
-        service.updateUser('not a correct id', {
-          name: 'not a correct name',
-          username: 'not a correct username',
-          email: 'not a correct email',
-          password: 'not a correct password',
-        }),
-      ).rejects.toThrow(HttpException);
-    });
-  });
-
-  describe('deleteUser() method', () => {
-    it('should remove a user by id', async () => {
-      const removeSpy = jest.spyOn(repository, 'remove');
-      const user = await service.deleteUser('any id');
-      expect(removeSpy).toBeCalledWith(oneUser);
-      expect(user).toBeUndefined();
-    });
-
-    it('should throw an error if no user is found with an id', async () => {
-      repository.findOneBy = jest.fn().mockResolvedValueOnce(undefined);
-      await expect(service.deleteUser('bad id')).rejects.toThrow(
-        NotFoundException,
-      );
-      expect(repository.findOneBy).toBeCalledTimes(1);
-    });
-  });
-});
+    let service: UsersService
+    let repository: Repository<Users>
+
+    beforeEach(async () => {
+        const module: TestingModule = await Test.createTestingModule({
+            providers: [
+                UsersService,
+                {
+                    provide: HashingService,
+                    useClass: BcryptService
+                },
+                {
+                    provide: getRepositoryToken(Users),
+                    useValue: {
+                        find: jest.fn().mockResolvedValue(userArray),
+                        findOne: jest.fn().mockResolvedValue(oneUser),
+                        findOneBy: jest.fn().mockResolvedValueOnce(oneUser),
+                        save: jest.fn().mockReturnValue(createUser),
+                        updateByEmail: jest.fn().mockResolvedValue(updateUserByEmail),
+                        updateByPassword: jest.fn().mockResolvedValue(updateUserByPassword),
+                        updateProfileUser: jest.fn().mockResolvedValue(updateProfileUser),
+                        update: jest.fn().mockReturnValue(updateUser),
+                        remove: jest.fn()
+                    }
+                }
+            ]
+        }).compile()
+
+        service = module.get<UsersService>(UsersService)
+        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
+    })
+
+    it('should be defined', () => {
+        expect(service).toBeDefined()
+    })
+
+    describe('findAll() method', () => {
+        it('should return an array of all users', async () => {
+            const users = await service.findAll()
+            expect(users).toEqual(userArray)
+        })
+    })
+
+    describe('findByEmail() method', () => {
+        it('should find a user by email', async () => {
+            expect(await service.findByEmail('test@example.com')).toEqual(oneUser)
+        })
+
+        it('should throw an exception if it not found a user by email', async () => {
+            repository.findOneBy = jest.fn().mockResolvedValueOnce(null)
+            await expect(service.findByEmail('not a correct email')).rejects.toThrow(NotFoundException)
+        })
+    })
+    describe('findById() method', () => {
+        it('should find a user by id', async () => {
+            expect(await service.findById('anyid')).toEqual(oneUser)
+        })
+
+        it('should throw an exception if it not found a user by id', async () => {
+            repository.findOneBy = jest.fn().mockResolvedValueOnce(null)
+            await expect(service.findById('not a correct id')).rejects.toThrow(NotFoundException)
+        })
+    })
+
+    describe('create() method', () => {
+        it('should create a new user', async () => {
+            expect(
+                await service.create({
+                    name: 'name #1',
+                    username: 'username #1',
+                    email: 'test@example.com',
+                    password: 'pass123'
+                })
+            ).toEqual(createUser)
+        })
+
+        it('should return an exception if login fails', async () => {
+            repository.save = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                service.create({
+                    name: 'not a correct name',
+                    username: 'not a correct username',
+                    email: 'not a correct email',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(HttpException)
+        })
+    })
+
+    describe('updateByEmail() method', () => {
+        it('should update a user by email', async () => {
+            expect(await service.updateByEmail('test@example.com')).toEqual(updateUserByEmail)
+        })
+
+        it('should return an exception if update by email fails', async () => {
+            repository.save = jest.fn().mockRejectedValueOnce(null)
+            await expect(service.updateByEmail('not a correct email')).rejects.toThrow(HttpException)
+        })
+    })
+
+    describe('updateByPassword() method', () => {
+        it('should update a user by password', async () => {
+            expect(await service.updateByPassword('test@example.com', 'pass123')).toEqual(updateUserByPassword)
+        })
+
+        it('should return an exception if update by password fails', async () => {
+            repository.save = jest.fn().mockRejectedValueOnce(null)
+            await expect(service.updateByPassword('not a correct email', 'not correct password')).rejects.toThrow(
+                HttpException
+            )
+        })
+    })
+
+    describe('updateProfileUser() method', () => {
+        it('should update profile of a user by id', async () => {
+            expect(await service.updateProfileUser('anyid', updateProfileUser)).toEqual(updateProfileUser)
+        })
+
+        it('should return an exception if update profile user fails', async () => {
+            repository.save = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                service.updateProfileUser('not a correct id', {
+                    name: 'not a correct name',
+                    username: 'not a correct username',
+                    email: 'not a correct email'
+                })
+            ).rejects.toThrow(HttpException)
+        })
+    })
+
+    describe('updateUser() method', () => {
+        it('should update a user by id', async () => {
+            expect(await service.updateUser('anyid', updateUser)).toEqual(updateUser)
+        })
+
+        it('should return an exception if update profile user fails', async () => {
+            repository.update = jest.fn().mockRejectedValueOnce(null)
+            await expect(
+                service.updateUser('not a correct id', {
+                    name: 'not a correct name',
+                    username: 'not a correct username',
+                    email: 'not a correct email',
+                    password: 'not a correct password'
+                })
+            ).rejects.toThrow(HttpException)
+        })
+    })
+
+    describe('deleteUser() method', () => {
+        it('should remove a user by id', async () => {
+            const removeSpy = jest.spyOn(repository, 'remove')
+            const user = await service.deleteUser('any id')
+            expect(removeSpy).toBeCalledWith(oneUser)
+            expect(user).toBeUndefined()
+        })
+
+        it('should throw an error if no user is found with an id', async () => {
+            repository.findOneBy = jest.fn().mockResolvedValueOnce(undefined)
+            await expect(service.deleteUser('bad id')).rejects.toThrow(NotFoundException)
+            expect(repository.findOneBy).toBeCalledTimes(1)
+        })
+    })
+})

+ 92 - 109
src/users/users.service.ts

@@ -1,126 +1,109 @@
-import {
-  Injectable,
-  NotFoundException,
-  HttpException,
-  HttpStatus,
-  BadRequestException,
-} from '@nestjs/common';
-import { Repository, UpdateResult } from 'typeorm';
-import { InjectRepository } from '@nestjs/typeorm';
-import { Users } from './entities/users.entity';
-import { IUsers } from './interfaces/users.interface';
-import { UserDto } from './dto/user.dto';
-import { UserProfileDto } from './dto/user-profile.dto';
-import { UserUpdateDto } from './dto/user-update.dto';
-import { HashingService } from '../shared/hashing/hashing.service';
+import { Injectable, NotFoundException, HttpException, HttpStatus, BadRequestException } from '@nestjs/common'
+import { Repository, UpdateResult } from 'typeorm'
+import { InjectRepository } from '@nestjs/typeorm'
+import { Users } from './entities/users.entity'
+import { IUsers } from './interfaces/users.interface'
+import { UserDto } from './dto/user.dto'
+import { UserProfileDto } from './dto/user-profile.dto'
+import { UserUpdateDto } from './dto/user-update.dto'
+import { HashingService } from '../shared/hashing/hashing.service'
 
 @Injectable()
 export class UsersService {
-  constructor(
-    @InjectRepository(Users)
-    private readonly userRepository: Repository<Users>,
-    private readonly hashingService: HashingService,
-  ) {}
-
-  public async findAll(): Promise<Users[]> {
-    return await this.userRepository.find();
-  }
-
-  public async findByEmail(email: string): Promise<Users> {
-    const user = await this.userRepository.findOneBy({
-      email: email,
-    });
-
-    if (!user) {
-      throw new NotFoundException(`User not found`);
+    constructor(
+        @InjectRepository(Users)
+        private readonly userRepository: Repository<Users>,
+        private readonly hashingService: HashingService
+    ) {}
+
+    public async findAll(): Promise<Users[]> {
+        return await this.userRepository.find()
     }
 
-    return user;
-  }
+    public async findByEmail(email: string): Promise<Users> {
+        const user = await this.userRepository.findOneBy({
+            email: email
+        })
 
-  public async findById(userId: string): Promise<Users> {
-    const user = await this.userRepository.findOneBy({
-      id: +userId,
-    });
+        if (!user) {
+            throw new NotFoundException(`User not found`)
+        }
 
-    if (!user) {
-      throw new NotFoundException(`User #${userId} not found`);
+        return user
     }
 
-    return user;
-  }
+    public async findById(userId: string): Promise<Users> {
+        const user = await this.userRepository.findOneBy({
+            id: +userId
+        })
 
-  public async create(userDto: UserDto): Promise<IUsers> {
-    try {
-      return await this.userRepository.save(userDto);
-    } catch (err) {
-      throw new HttpException(err, HttpStatus.BAD_REQUEST);
+        if (!user) {
+            throw new NotFoundException(`User #${userId} not found`)
+        }
+
+        return user
+    }
+
+    public async create(userDto: UserDto): Promise<IUsers> {
+        try {
+            return await this.userRepository.save(userDto)
+        } catch (err) {
+            throw new HttpException(err, HttpStatus.BAD_REQUEST)
+        }
     }
-  }
-
-  public async updateByEmail(email: string): Promise<Users> {
-    try {
-      const user = await this.userRepository.findOneBy({ email: email });
-      user.password = await this.hashingService.hash(
-        Math.random().toString(36).slice(-8),
-      );
-
-      return await this.userRepository.save(user);
-    } catch (err) {
-      throw new HttpException(err, HttpStatus.BAD_REQUEST);
+
+    public async updateByEmail(email: string): Promise<Users> {
+        try {
+            const user = await this.userRepository.findOneBy({ email: email })
+            user.password = await this.hashingService.hash(Math.random().toString(36).slice(-8))
+
+            return await this.userRepository.save(user)
+        } catch (err) {
+            throw new HttpException(err, HttpStatus.BAD_REQUEST)
+        }
     }
-  }
-
-  public async updateByPassword(
-    email: string,
-    password: string,
-  ): Promise<Users> {
-    try {
-      const user = await this.userRepository.findOneBy({ email: email });
-      user.password = await this.hashingService.hash(password);
-
-      return await this.userRepository.save(user);
-    } catch (err) {
-      throw new HttpException(err, HttpStatus.BAD_REQUEST);
+
+    public async updateByPassword(email: string, password: string): Promise<Users> {
+        try {
+            const user = await this.userRepository.findOneBy({ email: email })
+            user.password = await this.hashingService.hash(password)
+
+            return await this.userRepository.save(user)
+        } catch (err) {
+            throw new HttpException(err, HttpStatus.BAD_REQUEST)
+        }
     }
-  }
-
-  public async updateProfileUser(
-    id: string,
-    userProfileDto: UserProfileDto,
-  ): Promise<Users> {
-    try {
-      const user = await this.userRepository.findOneBy({ id: +id });
-      user.name = userProfileDto.name;
-      user.email = userProfileDto.email;
-      user.username = userProfileDto.username;
-
-      return await this.userRepository.save(user);
-    } catch (err) {
-      throw new HttpException(err, HttpStatus.BAD_REQUEST);
+
+    public async updateProfileUser(id: string, userProfileDto: UserProfileDto): Promise<Users> {
+        try {
+            const user = await this.userRepository.findOneBy({ id: +id })
+            user.name = userProfileDto.name
+            user.email = userProfileDto.email
+            user.username = userProfileDto.username
+
+            return await this.userRepository.save(user)
+        } catch (err) {
+            throw new HttpException(err, HttpStatus.BAD_REQUEST)
+        }
     }
-  }
-
-  public async updateUser(
-    id: string,
-    userUpdateDto: UserUpdateDto,
-  ): Promise<UpdateResult> {
-    try {
-      const user = await this.userRepository.update(
-        {
-          id: +id,
-        },
-        { ...userUpdateDto },
-      );
-
-      return user;
-    } catch (err) {
-      throw new BadRequestException('User not updated');
+
+    public async updateUser(id: string, userUpdateDto: UserUpdateDto): Promise<UpdateResult> {
+        try {
+            const user = await this.userRepository.update(
+                {
+                    id: +id
+                },
+                { ...userUpdateDto }
+            )
+
+            return user
+        } catch (err) {
+            throw new BadRequestException('User not updated')
+        }
     }
-  }
 
-  public async deleteUser(id: string): Promise<void> {
-    const user = await this.findById(id);
-    await this.userRepository.remove(user);
-  }
+    public async deleteUser(id: string): Promise<void> {
+        const user = await this.findById(id)
+        await this.userRepository.remove(user)
+    }
 }

+ 116 - 126
test/change-password/change-password.e2e-spec.ts

@@ -1,140 +1,130 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import * as request from 'supertest';
-import { AppModule } from './../../src/app.module';
-import { MailerService } from '../../src/shared/mailer/mailer.service';
-import {
-  BadRequestException,
-  HttpStatus,
-  ValidationPipe,
-} from '@nestjs/common';
-import { AccessTokenGuard } from '../../src/iam/login/guards/access-token/access-token.guard';
+import { Test, TestingModule } from '@nestjs/testing'
+import * as request from 'supertest'
+import { AppModule } from './../../src/app.module'
+import { MailerService } from '../../src/shared/mailer/mailer.service'
+import { BadRequestException, HttpStatus, ValidationPipe } from '@nestjs/common'
+import { AccessTokenGuard } from '../../src/iam/login/guards/access-token/access-token.guard'
 
 const user = {
-  email: 'test@example.com',
-  password: 'pass123',
-};
+    email: 'test@example.com',
+    password: 'pass123'
+}
 
 describe('App (e2e)', () => {
-  let app;
-  let accessTokenJwt: string;
+    let app
+    let accessTokenJwt: string
 
-  beforeAll(async () => {
-    const moduleFixture: TestingModule = await Test.createTestingModule({
-      imports: [AppModule],
-    })
-      .overrideProvider(MailerService)
-      .useValue({
-        sendMail: jest.fn(() => true),
-      })
-      .overrideGuard(AccessTokenGuard)
-      .useValue({ canActivate: () => true })
-      .compile();
+    beforeAll(async () => {
+        const moduleFixture: TestingModule = await Test.createTestingModule({
+            imports: [AppModule]
+        })
+            .overrideProvider(MailerService)
+            .useValue({
+                sendMail: jest.fn(() => true)
+            })
+            .overrideGuard(AccessTokenGuard)
+            .useValue({ canActivate: () => true })
+            .compile()
 
-    app = moduleFixture.createNestApplication();
-    app.setGlobalPrefix('api');
-    app.useGlobalPipes(
-      new ValidationPipe({
-        whitelist: true,
-        transform: true,
-        forbidNonWhitelisted: true,
-        transformOptions: {
-          enableImplicitConversion: true,
-        },
-      }),
-    );
+        app = moduleFixture.createNestApplication()
+        app.setGlobalPrefix('api')
+        app.useGlobalPipes(
+            new ValidationPipe({
+                whitelist: true,
+                transform: true,
+                forbidNonWhitelisted: true,
+                transformOptions: {
+                    enableImplicitConversion: true
+                }
+            })
+        )
 
-    await app.init();
-  });
+        await app.init()
+    })
 
-  describe('should sign in and get a "live" JWT', () => {
-    it('should authenticates user with valid credentials and provides a jwt token', () => {
-      return request(app.getHttpServer())
-        .post('/api/auth/login')
-        .send({
-          email: 'test@example.com',
-          password: 'pass123',
-        })
-        .then(({ body }) => {
-          accessTokenJwt = body.accessToken;
-          expect(accessTokenJwt).toMatch(
-            /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/,
-          );
+    describe('should sign in and get a "live" JWT', () => {
+        it('should authenticates user with valid credentials and provides a jwt token', () => {
+            return request(app.getHttpServer())
+                .post('/api/auth/login')
+                .send({
+                    email: 'test@example.com',
+                    password: 'pass123'
+                })
+                .then(({ body }) => {
+                    accessTokenJwt = body.accessToken
+                    expect(accessTokenJwt).toMatch(/^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/)
 
-          expect(body).toEqual({
-            sub: 1,
-            expiresIn: '3600',
-            audience: '127.0.0.1:3001',
-            issuer: '127.0.0.1:3001',
-            accessToken: accessTokenJwt,
-            user: { name: 'name #1', email: 'test@example.com', id: 1 },
-          });
+                    expect(body).toEqual({
+                        sub: 1,
+                        expiresIn: '3600',
+                        audience: '127.0.0.1:3001',
+                        issuer: '127.0.0.1:3001',
+                        accessToken: accessTokenJwt,
+                        user: { name: 'name #1', email: 'test@example.com', id: 1 }
+                    })
 
-          expect(HttpStatus.OK);
-        });
-    });
-  });
+                    expect(HttpStatus.OK)
+                })
+        })
+    })
 
-  describe('ChangePasswordController (e2e) - [POST /api/auth/change-password]', () => {
-    it('should change password an user', async () => {
-      return await request(app.getHttpServer())
-        .post('/api/auth/change-password')
-        .set('Authorization', `Bearer ${accessTokenJwt}`)
-        .send(user)
-        .then(({ body }) => {
-          expect(body).toEqual({
-            message: 'Request Change Password Successfully!',
-            status: 200,
-          });
-          expect(HttpStatus.OK);
-        });
-    });
-  });
+    describe('ChangePasswordController (e2e) - [POST /api/auth/change-password]', () => {
+        it('should change password an user', async () => {
+            return await request(app.getHttpServer())
+                .post('/api/auth/change-password')
+                .set('Authorization', `Bearer ${accessTokenJwt}`)
+                .send(user)
+                .then(({ body }) => {
+                    expect(body).toEqual({
+                        message: 'Request Change Password Successfully!',
+                        status: 200
+                    })
+                    expect(HttpStatus.OK)
+                })
+        })
+    })
 
-  it('should throw an error for a bad email', async () => {
-    return await request(app.getHttpServer())
-      .post('/api/auth/change-password')
-      .set('Authorization', `Bearer ${accessTokenJwt}`)
-      .send({
-        password: 'new123456',
-      })
-      .then(({ body }) => {
-        expect(body).toEqual({
-          error: 'Bad Request',
-          message: [
-            'email should not be empty',
-            'email must be a string',
-            'email must be an email',
-          ],
-          statusCode: 400,
-        });
-        expect(HttpStatus.BAD_REQUEST);
-        expect(new BadRequestException());
-      });
-  });
+    it('should throw an error for a bad email', async () => {
+        return await request(app.getHttpServer())
+            .post('/api/auth/change-password')
+            .set('Authorization', `Bearer ${accessTokenJwt}`)
+            .send({
+                password: 'new123456'
+            })
+            .then(({ body }) => {
+                expect(body).toEqual({
+                    error: 'Bad Request',
+                    message: ['email should not be empty', 'email must be a string', 'email must be an email'],
+                    statusCode: 400
+                })
+                expect(HttpStatus.BAD_REQUEST)
+                expect(new BadRequestException())
+            })
+    })
 
-  it('should throw an error for a bad password', async () => {
-    return await request(app.getHttpServer())
-      .post('/api/auth/change-password')
-      .set('Authorization', `Bearer ${accessTokenJwt}`)
-      .send({
-        email: 'test@example.it',
-      })
-      .then(({ body }) => {
-        expect(body).toEqual({
-          error: 'Bad Request',
-          message: [
-            'password must be shorter than or equal to 60 characters',
-            'password must be a string',
-            'password should not be empty',
-          ],
-          statusCode: 400,
-        });
-        expect(HttpStatus.BAD_REQUEST);
-        expect(new BadRequestException());
-      });
-  });
+    it('should throw an error for a bad password', async () => {
+        return await request(app.getHttpServer())
+            .post('/api/auth/change-password')
+            .set('Authorization', `Bearer ${accessTokenJwt}`)
+            .send({
+                email: 'test@example.it'
+            })
+            .then(({ body }) => {
+                expect(body).toEqual({
+                    error: 'Bad Request',
+                    message: [
+                        'password must be shorter than or equal to 60 characters',
+                        'password must be a string',
+                        'password should not be empty'
+                    ],
+                    statusCode: 400
+                })
+                expect(HttpStatus.BAD_REQUEST)
+                expect(new BadRequestException())
+            })
+    })
 
-  afterAll(async () => {
-    await app.close();
-  });
-});
+    afterAll(async () => {
+        await app.close()
+    })
+})

+ 1 - 1
yarn.lock

@@ -4311,7 +4311,7 @@ prettier-linter-helpers@^1.0.0:
   dependencies:
     fast-diff "^1.1.2"
 
-prettier@^2.8.4:
+prettier@^2.8.7:
   version "2.8.7"
   resolved "https://registry.npmmirror.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450"
   integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==