xiongzhu 2 ani în urmă
părinte
comite
ddbb30bca8
39 a modificat fișierele cu 243 adăugiri și 1026 ștergeri
  1. 63 0
      src/iam/auth.controller.ts
  2. 0 55
      src/iam/change-password/change-password.controller.spec.ts
  3. 0 27
      src/iam/change-password/change-password.controller.ts
  4. 0 35
      src/iam/change-password/change-password.module.ts
  5. 0 70
      src/iam/change-password/change-password.service.spec.ts
  6. 0 35
      src/iam/change-password/change-password.service.ts
  7. 0 0
      src/iam/config/jwt.config.ts
  8. 0 0
      src/iam/decorators/auth-guard.decorator.ts
  9. 1 1
      src/iam/dto/change-password.dto.ts
  10. 1 1
      src/iam/dto/forgot-password.dto.ts
  11. 1 1
      src/iam/dto/login.dto.ts
  12. 3 0
      src/iam/dto/register-user.dto.ts
  13. 0 0
      src/iam/enums/auth-type.enum.ts
  14. 0 53
      src/iam/forgot-password/forgot-password.controller.spec.ts
  15. 0 27
      src/iam/forgot-password/forgot-password.controller.ts
  16. 0 24
      src/iam/forgot-password/forgot-password.module.ts
  17. 0 83
      src/iam/forgot-password/forgot-password.service.spec.ts
  18. 0 50
      src/iam/forgot-password/forgot-password.service.ts
  19. 1 1
      src/iam/guards/access-token/access-token.guard.ts
  20. 0 0
      src/iam/guards/authentication/authentication.guard.ts
  21. 4 6
      src/iam/iam.module.ts
  22. 0 0
      src/iam/interfaces/jwt-payload.interface.ts
  23. 0 51
      src/iam/login/login.controller.spec.ts
  24. 0 18
      src/iam/login/login.controller.ts
  25. 0 37
      src/iam/login/login.module.ts
  26. 0 129
      src/iam/login/login.service.spec.ts
  27. 0 58
      src/iam/login/login.service.ts
  28. 0 3
      src/iam/register/dto/register-user.dto.ts
  29. 0 81
      src/iam/register/register.controller.spec.ts
  30. 0 27
      src/iam/register/register.controller.ts
  31. 0 23
      src/iam/register/register.module.ts
  32. 0 80
      src/iam/register/register.service.spec.ts
  33. 0 43
      src/iam/register/register.service.ts
  34. 17 1
      src/users/users.module.ts
  35. 148 2
      src/users/users.service.ts
  36. 1 1
      test/app.e2e-spec.ts
  37. 1 1
      test/change-password/change-password.e2e-spec.ts
  38. 1 1
      test/forgot-password/forgot-password.e2e-spec.ts
  39. 1 1
      test/users/users.e2e-spec.ts

+ 63 - 0
src/iam/auth.controller.ts

@@ -0,0 +1,63 @@
+import { Controller, Post, Body, HttpStatus, BadRequestException } from '@nestjs/common'
+import { ApiTags } from '@nestjs/swagger'
+import { UsersService } from 'src/users/users.service'
+import { RegisterUserDto } from './dto/register-user.dto'
+import { LoginDto } from './dto/login.dto'
+import { AuthType } from './enums/auth-type.enum'
+import { AuthGuard } from './decorators/auth-guard.decorator'
+import { ForgotPasswordDto } from './dto/forgot-password.dto'
+import { ChangePasswordDto } from './dto/change-password.dto'
+
+@ApiTags('auth')
+@AuthGuard(AuthType.None)
+@Controller('/auth')
+export class AuthController {
+    constructor(private readonly userService: UsersService) {}
+
+    @Post('/register')
+    public async register(@Body() registerUserDto: RegisterUserDto): Promise<any> {
+        try {
+            await this.userService.register(registerUserDto)
+
+            return {
+                message: 'User registration successfully!',
+                status: HttpStatus.CREATED
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: User not registration!')
+        }
+    }
+
+    @Post('/login')
+    public async login(@Body() loginDto: LoginDto): Promise<any> {
+        return await this.userService.login(loginDto)
+    }
+
+    @Post('/change-password')
+    public async changePassword(@Body() changePasswordDto: ChangePasswordDto): Promise<any> {
+        try {
+            await this.userService.changePassword(changePasswordDto)
+
+            return {
+                message: 'Request Change Password Successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: Change password failed!')
+        }
+    }
+
+    @Post('/forgot-password')
+    public async forgotPassword(@Body() forgotPasswordDto: ForgotPasswordDto): Promise<any> {
+        try {
+            await this.userService.forgotPassword(forgotPasswordDto)
+
+            return {
+                message: 'Request Reset Password Successfully!',
+                status: HttpStatus.OK
+            }
+        } catch (err) {
+            throw new BadRequestException(err, 'Error: Forgot password failed!')
+        }
+    }
+}

+ 0 - 55
src/iam/change-password/change-password.controller.spec.ts

@@ -1,55 +0,0 @@
-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'
-}
-
-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)
-        })
-    })
-})

+ 0 - 27
src/iam/change-password/change-password.controller.ts

@@ -1,27 +0,0 @@
-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) {}
-
-    @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!')
-        }
-    }
-}

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

@@ -1,35 +0,0 @@
-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
-    ]
-})
-export class ChangePasswordModule {}

+ 0 - 70
src/iam/change-password/change-password.service.spec.ts

@@ -1,70 +0,0 @@
-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'
-}
-
-describe('ChangePasswordService', () => {
-    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()
-
-        service = module.get<ChangePasswordService>(ChangePasswordService)
-        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
-    })
-
-    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)
-        })
-    })
-})

+ 0 - 35
src/iam/change-password/change-password.service.ts

@@ -1,35 +0,0 @@
-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) {}
-
-    public async changePassword(changePasswordDto: ChangePasswordDto): Promise<any> {
-        this.sendMailChangePassword(changePasswordDto)
-
-        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)
-        }
-    }
-}

+ 0 - 0
src/iam/login/config/jwt.config.ts → src/iam/config/jwt.config.ts


+ 0 - 0
src/iam/login/decorators/auth-guard.decorator.ts → src/iam/decorators/auth-guard.decorator.ts


+ 1 - 1
src/iam/change-password/dto/change-password.dto.ts → src/iam/dto/change-password.dto.ts

@@ -1,4 +1,4 @@
 import { PickType } from '@nestjs/swagger'
 import { PickType } from '@nestjs/swagger'
-import { UserDto } from '../../../users/dto/user.dto'
+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) {}

+ 1 - 1
src/iam/forgot-password/dto/forgot-password.dto.ts → src/iam/dto/forgot-password.dto.ts

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

+ 1 - 1
src/iam/login/dto/login.dto.ts → src/iam/dto/login.dto.ts

@@ -1,4 +1,4 @@
 import { PickType } from '@nestjs/swagger'
 import { PickType } from '@nestjs/swagger'
-import { UserDto } from '../../../users/dto/user.dto'
+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) {}

+ 3 - 0
src/iam/dto/register-user.dto.ts

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

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


+ 0 - 53
src/iam/forgot-password/forgot-password.controller.spec.ts

@@ -1,53 +0,0 @@
-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'
-}
-
-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)
-        })
-    })
-})

+ 0 - 27
src/iam/forgot-password/forgot-password.controller.ts

@@ -1,27 +0,0 @@
-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) {}
-
-    @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!')
-        }
-    }
-}

+ 0 - 24
src/iam/forgot-password/forgot-password.module.ts

@@ -1,24 +0,0 @@
-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]
-})
-export class ForgotPasswordModule {}

+ 0 - 83
src/iam/forgot-password/forgot-password.service.spec.ts

@@ -1,83 +0,0 @@
-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'
-}
-
-const user = {
-    email: 'test@example.com',
-    password: 'pass123'
-}
-
-describe('ForgotPasswordService', () => {
-    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()
-
-        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()
-        })
-
-        it('should generate a new password for user by email', async () => {
-            expect(
-                await service.forgotPassword({
-                    email: 'test@example.com'
-                })
-            ).toEqual(oneUser)
-        })
-    })
-})

+ 0 - 50
src/iam/forgot-password/forgot-password.service.ts

@@ -1,50 +0,0 @@
-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
-    ) {}
-
-    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)
-
-        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)
-        }
-    }
-}

+ 1 - 1
src/iam/login/guards/access-token/access-token.guard.ts → src/iam/guards/access-token/access-token.guard.ts

@@ -2,7 +2,7 @@ import { CanActivate, ExecutionContext, HttpStatus, Inject, Injectable, Unauthor
 import { ConfigType } from '@nestjs/config'
 import { ConfigType } from '@nestjs/config'
 import { JwtService } from '@nestjs/jwt'
 import { JwtService } from '@nestjs/jwt'
 import { Request } from 'express'
 import { Request } from 'express'
-import { REQUEST_USER_KEY, TYPE_TOKEN_BEARER } from '../../../iam.constants'
+import { REQUEST_USER_KEY, TYPE_TOKEN_BEARER } from '../../iam.constants'
 import jwtConfig from '../../config/jwt.config'
 import jwtConfig from '../../config/jwt.config'
 
 
 @Injectable()
 @Injectable()

+ 0 - 0
src/iam/login/guards/authentication/authentication.guard.ts → src/iam/guards/authentication/authentication.guard.ts


+ 4 - 6
src/iam/iam.module.ts

@@ -2,13 +2,11 @@ import { Module } from '@nestjs/common'
 import { JwtService } from '@nestjs/jwt'
 import { JwtService } from '@nestjs/jwt'
 import { UtilsModule } from '../shared/utils/utils.module'
 import { UtilsModule } from '../shared/utils/utils.module'
 import { UsersModule } from '../users/users.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 { AuthController } from './auth.controller'
 
 
 @Module({
 @Module({
-    imports: [LoginModule, RegisterModule, UsersModule, ForgotPasswordModule, ChangePasswordModule, UtilsModule],
-    providers: [JwtService]
+    imports: [UsersModule, UtilsModule],
+    providers: [JwtService],
+    controllers: [AuthController]
 })
 })
 export class IamModule {}
 export class IamModule {}

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


+ 0 - 51
src/iam/login/login.controller.spec.ts

@@ -1,51 +0,0 @@
-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'
-}
-
-describe('Login Controller', () => {
-    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()
-
-        loginController = module.get<LoginController>(LoginController)
-        loginService = module.get<LoginService>(LoginService)
-    })
-
-    describe('Login user', () => {
-        it('should be defined', () => {
-            expect(loginController).toBeDefined()
-        })
-
-        it('should call method login in loginService', async () => {
-            const createSpy = jest.spyOn(loginService, 'login')
-
-            await loginController.login(loginDto)
-            expect(createSpy).toHaveBeenCalledWith(loginDto)
-        })
-    })
-})

+ 0 - 18
src/iam/login/login.controller.ts

@@ -1,18 +0,0 @@
-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) {}
-
-    @Post()
-    public async login(@Body() loginDto: LoginDto): Promise<any> {
-        return await this.loginService.login(loginDto)
-    }
-}

+ 0 - 37
src/iam/login/login.module.ts

@@ -1,37 +0,0 @@
-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]
-})
-export class LoginModule {}

+ 0 - 129
src/iam/login/login.service.spec.ts

@@ -1,129 +0,0 @@
-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'
-}
-
-const loginDto: LoginDto = {
-    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'
-    }
-}
-
-const payload = {
-    id: 1,
-    name: 'name #1',
-    email: 'test@example.com'
-}
-
-describe('LoginService', () => {
-    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()
-
-        loginService = module.get<LoginService>(LoginService)
-        usersService = module.get<UsersService>(UsersService)
-        hashingService = module.get<HashingService>(HashingService)
-    })
-
-    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)
-        })
-
-        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 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)
-        })
-    })
-})

+ 0 - 58
src/iam/login/login.service.ts

@@ -1,58 +0,0 @@
-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)
-        }
-    }
-
-    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
-        }
-    }
-}

+ 0 - 3
src/iam/register/dto/register-user.dto.ts

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

+ 0 - 81
src/iam/register/register.controller.spec.ts

@@ -1,81 +0,0 @@
-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'
-}
-
-describe('Register Controller', () => {
-    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()
-
-        registerController = module.get<RegisterController>(RegisterController)
-        registerService = module.get<RegisterService>(RegisterService)
-    })
-
-    describe('Registration user', () => {
-        it('should be defined', () => {
-            expect(registerController).toBeDefined()
-        })
-
-        it('should call method register in registerService', async () => {
-            const createSpy = jest.spyOn(registerService, 'register')
-
-            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)
-        })
-    })
-})

+ 0 - 27
src/iam/register/register.controller.ts

@@ -1,27 +0,0 @@
-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) {}
-
-    @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!')
-        }
-    }
-}

+ 0 - 23
src/iam/register/register.module.ts

@@ -1,23 +0,0 @@
-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
-    ]
-})
-export class RegisterModule {}

+ 0 - 80
src/iam/register/register.service.spec.ts

@@ -1,80 +0,0 @@
-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'
-}
-
-describe('RegisterService', () => {
-    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()
-
-        service = module.get<RegisterService>(RegisterService)
-        repository = module.get<Repository<Users>>(getRepositoryToken(Users))
-    })
-
-    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)
-        })
-    })
-})

+ 0 - 43
src/iam/register/register.service.ts

@@ -1,43 +0,0 @@
-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
-    ) {}
-
-    public async register(registerUserDto: RegisterUserDto): Promise<IUsers> {
-        registerUserDto.password = await this.hashingService.hash(registerUserDto.password)
-
-        this.sendMailRegisterUser(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)
-        }
-    }
-}

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

@@ -6,15 +6,31 @@ import { UsersController } from './users.controller'
 import { MailerModule } from '../shared/mailer/mailer.module'
 import { MailerModule } from '../shared/mailer/mailer.module'
 import { BcryptService } from '../shared/hashing/bcrypt.service'
 import { BcryptService } from '../shared/hashing/bcrypt.service'
 import { HashingService } from '../shared/hashing/hashing.service'
 import { HashingService } from '../shared/hashing/hashing.service'
+import jwtConfig from 'src/iam/config/jwt.config'
+import { JwtModule } from '@nestjs/jwt'
+import { ConfigModule } from '@nestjs/config'
+import { APP_GUARD } from '@nestjs/core'
+import { AuthenticationGuard } from 'src/iam/guards/authentication/authentication.guard'
+import { UtilsModule } from 'src/shared/utils/utils.module'
 
 
 @Module({
 @Module({
-    imports: [TypeOrmModule.forFeature([Users]), MailerModule],
+    imports: [
+        TypeOrmModule.forFeature([Users]),
+        MailerModule,
+        ConfigModule.forFeature(jwtConfig),
+        JwtModule.registerAsync(jwtConfig.asProvider()),
+        UtilsModule
+    ],
     controllers: [UsersController],
     controllers: [UsersController],
     providers: [
     providers: [
         {
         {
             provide: HashingService,
             provide: HashingService,
             useClass: BcryptService
             useClass: BcryptService
         },
         },
+        {
+            provide: APP_GUARD,
+            useClass: AuthenticationGuard
+        },
         UsersService
         UsersService
     ]
     ]
 })
 })

+ 148 - 2
src/users/users.service.ts

@@ -1,4 +1,12 @@
-import { Injectable, NotFoundException, HttpException, HttpStatus, BadRequestException } from '@nestjs/common'
+import {
+    Injectable,
+    NotFoundException,
+    HttpException,
+    HttpStatus,
+    BadRequestException,
+    Logger,
+    UnauthorizedException
+} from '@nestjs/common'
 import { Repository, UpdateResult } from 'typeorm'
 import { Repository, UpdateResult } from 'typeorm'
 import { InjectRepository } from '@nestjs/typeorm'
 import { InjectRepository } from '@nestjs/typeorm'
 import { Users } from './entities/users.entity'
 import { Users } from './entities/users.entity'
@@ -7,15 +15,96 @@ import { UserDto } from './dto/user.dto'
 import { UserProfileDto } from './dto/user-profile.dto'
 import { UserProfileDto } from './dto/user-profile.dto'
 import { UserUpdateDto } from './dto/user-update.dto'
 import { UserUpdateDto } from './dto/user-update.dto'
 import { HashingService } from '../shared/hashing/hashing.service'
 import { HashingService } from '../shared/hashing/hashing.service'
+import { MailerService } from 'src/shared/mailer/mailer.service'
+import { RegisterUserDto } from 'src/iam/dto/register-user.dto'
+import { LoginDto } from 'src/iam/dto/login.dto'
+import { JwtService } from '@nestjs/jwt'
+import { ConfigService } from '@nestjs/config'
+import { JWTPayload } from '../iam/interfaces/jwt-payload.interface'
+import { UtilsService } from 'src/shared/utils/utils.service'
+import { ForgotPasswordDto } from 'src/iam/dto/forgot-password.dto'
+import { ChangePasswordDto } from 'src/iam/dto/change-password.dto'
 
 
 @Injectable()
 @Injectable()
 export class UsersService {
 export class UsersService {
     constructor(
     constructor(
         @InjectRepository(Users)
         @InjectRepository(Users)
         private readonly userRepository: Repository<Users>,
         private readonly userRepository: Repository<Users>,
-        private readonly hashingService: HashingService
+        private readonly hashingService: HashingService,
+        private readonly mailerService: MailerService,
+        private readonly jwtService: JwtService,
+        private readonly configService: ConfigService,
+        private readonly utilsService: UtilsService
     ) {}
     ) {}
 
 
+    public async register(registerUserDto: RegisterUserDto): Promise<IUsers> {
+        registerUserDto.password = await this.hashingService.hash(registerUserDto.password)
+
+        this.sendMailRegisterUser(registerUserDto)
+
+        return this.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)
+        }
+    }
+
+    public async findUserByEmail(loginDto: LoginDto): Promise<IUsers> {
+        return await this.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)
+        }
+    }
+
+    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
+        }
+    }
+
     public async findAll(): Promise<Users[]> {
     public async findAll(): Promise<Users[]> {
         return await this.userRepository.find()
         return await this.userRepository.find()
     }
     }
@@ -106,4 +195,61 @@ export class UsersService {
         const user = await this.findById(id)
         const user = await this.findById(id)
         await this.userRepository.remove(user)
         await this.userRepository.remove(user)
     }
     }
+
+    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)
+
+        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)
+        }
+    }
+
+    public async changePassword(changePasswordDto: ChangePasswordDto): Promise<any> {
+        this.sendMailChangePassword(changePasswordDto)
+
+        return await this.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)
+        }
+    }
 }
 }

+ 1 - 1
test/app.e2e-spec.ts

@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
 import * as request from 'supertest';
 import * as request from 'supertest';
 import { AppModule } from './../src/app.module';
 import { AppModule } from './../src/app.module';
 import { HttpStatus, ValidationPipe } from '@nestjs/common';
 import { HttpStatus, ValidationPipe } from '@nestjs/common';
-import { AccessTokenGuard } from '../src/iam/login/guards/access-token/access-token.guard';
+import { AccessTokenGuard } from '../src/iam/guards/access-token/access-token.guard';
 
 
 describe('App (e2e)', () => {
 describe('App (e2e)', () => {
   let app;
   let app;

+ 1 - 1
test/change-password/change-password.e2e-spec.ts

@@ -3,7 +3,7 @@ import * as request from 'supertest'
 import { AppModule } from './../../src/app.module'
 import { AppModule } from './../../src/app.module'
 import { MailerService } from '../../src/shared/mailer/mailer.service'
 import { MailerService } from '../../src/shared/mailer/mailer.service'
 import { BadRequestException, HttpStatus, ValidationPipe } from '@nestjs/common'
 import { BadRequestException, HttpStatus, ValidationPipe } from '@nestjs/common'
-import { AccessTokenGuard } from '../../src/iam/login/guards/access-token/access-token.guard'
+import { AccessTokenGuard } from 'src/iam/guards/access-token/access-token.guard'
 
 
 const user = {
 const user = {
     email: 'test@example.com',
     email: 'test@example.com',

+ 1 - 1
test/forgot-password/forgot-password.e2e-spec.ts

@@ -7,7 +7,7 @@ import {
   HttpStatus,
   HttpStatus,
   ValidationPipe,
   ValidationPipe,
 } from '@nestjs/common';
 } from '@nestjs/common';
-import { ForgotPasswordDto } from 'src/iam/forgot-password/dto/forgot-password.dto';
+import { ForgotPasswordDto } from 'src/iam/dto/forgot-password.dto';
 import { UserDto } from '../../src/users/dto/user.dto';
 import { UserDto } from '../../src/users/dto/user.dto';
 
 
 const user = {
 const user = {

+ 1 - 1
test/users/users.e2e-spec.ts

@@ -3,7 +3,7 @@ import * as request from 'supertest';
 import { AppModule } from './../../src/app.module';
 import { AppModule } from './../../src/app.module';
 import { MailerService } from '../../src/shared/mailer/mailer.service';
 import { MailerService } from '../../src/shared/mailer/mailer.service';
 import { HttpStatus, ValidationPipe } from '@nestjs/common';
 import { HttpStatus, ValidationPipe } from '@nestjs/common';
-import { AccessTokenGuard } from '../../src/iam/login/guards/access-token/access-token.guard';
+import { AccessTokenGuard } from '../../src/iam/guards/access-token/access-token.guard';
 
 
 const users = [
 const users = [
   {
   {