diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index b797570a30dd3fd0aa5798698dddf55a4773743a..9742d630f379c944bccd3fc94b13f510b34082f8 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -51,7 +51,7 @@ export class UsersController { @ApiResponse({ status: 201, description: 'Email confirmation send' }) @ApiResponse({ status: 401, description: 'Invalid Email' }) public async changeEmail(@Request() req, @Body() emailChangeDto: EmailChangeDto) { - return this.usersService.changeUserEmail(emailChangeDto.newEmail, emailChangeDto.oldEmail); + return this.usersService.changeUserEmail(emailChangeDto); } @UseGuards(JwtAuthGuard) diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index 938f5cb0a46c7dbdaba535c160a01a379959a38c..ced92c8a244f82ee32f73992a14ada14fe34136f 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -6,6 +6,7 @@ import { getModelToken } from '@nestjs/mongoose'; import { CreateUserDto } from './create-user.dto'; import { HttpException, HttpStatus } from '@nestjs/common'; import { LoginDto } from '../auth/login-dto'; +import { EmailChangeDto } from './change-email.dto'; describe('UsersService', () => { let service: UsersService; @@ -38,6 +39,8 @@ describe('UsersService', () => { emailVerified: false, email: 'jacques.dupont@mii.com', password: '$2a$12$vLQjJ9zAWyUwiXLeQDa6w.yazDArYIpf2WnQF1jRHOjBxADEjUEA3', + newEmail: '', + changeEmailToken: '', }; const userDto: CreateUserDto = { email: 'jacques.dupont@mii.com', password: 'test1A!!' }; //NOSONAR jest.spyOn(service, 'create').mockImplementation(async (): Promise<User> => result); @@ -71,6 +74,8 @@ describe('UsersService', () => { email: 'jacques.dupont@mii.com', password: '$2a$12$vLQjJ9zAWyUwiXLeQDa6w.yazDArYIpf2WnQF1jRHOjBxADEjUEA3', role: 0, + newEmail: '', + changeEmailToken: '', }; const loginDto: LoginDto = { email: 'jacques.dupont@mii.com', password: 'test1A!!' }; //NOSONAR jest.spyOn(service, 'findByLogin').mockImplementation(async (): Promise<User> => result); @@ -117,4 +122,61 @@ describe('UsersService', () => { expect(await service.changeUserPassword('add3d', 'azertyU1!d', 'azertyU1!d')).toBe(result); }); }); + + describe('changeUserEmail', () => { + it('should find and add token', async () => { + const result = { + validationToken: '', + emailVerified: true, + email: 'jacques.dupont@mii.com', + password: '$2a$12$vLQjJ9zAWyUwiXLeQDa6w.yazDArYIpf2WnQF1jRHOjBxADEjUEA3', + role: 0, + newEmail: 'test.dupont@mail.com', + changeEmailToken: + '9bb3542bdc5ca8801ad4cee00403c1052bc95dee768dcbb65b1f719870578ed79f71f52fdc3e6bf02fd200a72b8b6f56fc26950df30c8cd7e427a485f80181b9', + }; + const emailDto: EmailChangeDto = { newEmail: 'test.dupont@mail.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR + jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<User> => result); + expect(await service.changeUserEmail(emailDto)).toBe(result); + }); + it('user does not exist, should be unauthorized issue', async () => { + const result: HttpException = new HttpException('Email sent if account exist', HttpStatus.UNAUTHORIZED); + const emailDto: EmailChangeDto = { newEmail: 'test.dupont@mail.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR + jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<any> => result); + expect(await service.changeUserEmail(emailDto)).toBe(result); + }); + it('email already used, should be not acceptable issue', async () => { + const result: HttpException = new HttpException('Email already used', HttpStatus.NOT_ACCEPTABLE); + const emailDto: EmailChangeDto = { newEmail: 'jacques.dupont@mii.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR + jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<any> => result); + expect(await service.changeUserEmail(emailDto)).toBe(result); + }); + it('should change email', async () => { + const result = { + validationToken: '', + emailVerified: true, + email: 'test.dupont@mail.com', + password: '$2a$12$vLQjJ9zAWyUwiXLeQDa6w.yazDArYIpf2WnQF1jRHOjBxADEjUEA3', + role: 0, + newEmail: '', + changeEmailToken: '', + }; + const token: string = + '9bb3542bdc5ca8801ad4cee00403c1052bc95dee768dcbb65b1f719870578ed79f71f52fdc3e6bf02fd200a72b8b6f56fc26950df30c8cd7e427a485f80181b9'; //NOSONAR + jest.spyOn(service, 'verifyAndUpdateUserEmail').mockImplementation(async (): Promise<User> => result); + expect(await service.verifyAndUpdateUserEmail(token)).toBe(result); + }); + it('should not change email', async () => { + const result: HttpException = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED); + const token: string = '9bb3542bdc5ca8801aa72b8b6f56fc26950df30c8cd7e427a485f80181b9FAKETOKEN'; //NOSONAR + jest.spyOn(service, 'verifyAndUpdateUserEmail').mockImplementation(async (): Promise<any> => result); + expect(await service.verifyAndUpdateUserEmail(token)).toBe(result); + }); + + // it('should not change email', async () => { + // const result = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED); + // jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<HttpException> => result); + // expect(await service.changeUserEmail('test@test.fr', 'oldTest@test.fr')).toBe(result); + // }); + }); }); diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 1fcaecbab3fe69913ca595e6bc0fec6615737ed3..2c17d0e3518917ad73eafed52d2818982df2c173 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -9,6 +9,7 @@ import { CreateUserDto } from './create-user.dto'; import { User } from './user.schema'; import { MailerService } from '../mailer/mailer.service'; import { IUser } from './user.interface'; +import { EmailChangeDto } from './change-email.dto'; @Injectable() export class UsersService { @@ -134,9 +135,9 @@ export class UsersService { } } - public async changeUserEmail(newEmail: string, oldEmail: string) { - const user = await this.findOne(oldEmail); - const alreadyUsed = await this.findOne(newEmail); + public async changeUserEmail(emailDto: EmailChangeDto): Promise<any> { + const user = await this.findOne(emailDto.oldEmail); + const alreadyUsed = await this.findOne(emailDto.newEmail); if (user) { if (!alreadyUsed) { const config = this.mailerService.config; @@ -149,13 +150,13 @@ export class UsersService { }); this.mailerService.send(user.email, jsonConfig.subject, html); user.changeEmailToken = token; - user.newEmail = newEmail; + user.newEmail = emailDto.newEmail; user.save(); return user; } throw new HttpException('Email already used', HttpStatus.NOT_ACCEPTABLE); } - throw new HttpException('Email sent if account exist', HttpStatus.OK); + throw new HttpException('Email sent if account exist', HttpStatus.UNAUTHORIZED); } public async verifyAndUpdateUserEmail(token: string): Promise<any> {