diff --git a/src/controller/user/editUserPassword.spec.ts b/src/controller/user/editUserPassword.spec.ts new file mode 100644 index 0000000..55e132f --- /dev/null +++ b/src/controller/user/editUserPassword.spec.ts @@ -0,0 +1,65 @@ +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import request from 'supertest' +import { app } from '../../app' +import { createAndAuthenticateUser } from '../../utils/create-and-authenticate-user' + +let userAuth: { + token: string + userId: string +} + +describe('edit User Pass E2E', () => { + beforeAll(async () => { + await app.ready() + userAuth = await createAndAuthenticateUser(app) + }) + + afterAll(async () => { + await app.close() + }) + + it('should be able to edit a user pass', async () => { + const editUserPassResponse = await request(app.server) + .put(`/user/edit/pass`) + .send({ + newPassword: 'newAwesomePassword', + oldPassword: '12345678', + }) + .set('Authorization', `Bearer ${userAuth.token}`) + + expect(editUserPassResponse.statusCode).toEqual(200) + expect(editUserPassResponse.body.user).toEqual( + expect.objectContaining({ + name: 'John', + surname: 'Doe', + email: 'johndoe@example.com', + id: userAuth.userId, + }), + ) + + const userData = await request(app.server) + .post('/login') + .send({ email: 'johndoe@example.com', password: 'newAwesomePassword' }) + + expect(userData.statusCode).toEqual(200) + expect(userData.body).toEqual({ + user: expect.any(Object), + token: expect.any(String), + }) + }) + + it('should not be able to edit a user pass with the old pass wrong', async () => { + const editUserPassResponse = await request(app.server) + .put(`/user/edit/pass`) + .send({ + newPassword: 'newAwesomePassword', + oldPassword: 'WRONGPASS', + }) + .set('Authorization', `Bearer ${userAuth.token}`) + + expect(editUserPassResponse.statusCode).toEqual(401) + expect(editUserPassResponse.body).toEqual( + expect.objectContaining({ error: 'Invalid old Password!' }), + ) + }) +}) diff --git a/src/controller/user/editUserPassword.ts b/src/controller/user/editUserPassword.ts new file mode 100644 index 0000000..7574d4d --- /dev/null +++ b/src/controller/user/editUserPassword.ts @@ -0,0 +1,39 @@ +import { FastifyRequest, FastifyReply } from 'fastify' +import { z } from 'zod' +import { PrismaUsersRepository } from '../../repositories/prisma/prisma-users-repository' +import { EditUserPasswordUseCase } from '../../use-cases/user/editUserPasswordUseCase' +import { ResourceNotFoundError } from '../../use-cases/errors/ResourceNotFoundError' +import { InvalidCredentialsError } from '../../use-cases/errors/InvalidCredentialsError' + +export async function editUserPassword( + request: FastifyRequest, + response: FastifyReply, +) { + const registerBodySchema = z.object({ + oldPassword: z.string(), + newPassword: z.string().min(6), + }) + + const { oldPassword, newPassword } = registerBodySchema.parse(request.body) + + const usersRepository = new PrismaUsersRepository() + const editUserPasswordUseCase = new EditUserPasswordUseCase(usersRepository) + try { + const { user } = await editUserPasswordUseCase.execute({ + oldPassword, + newPassword, + userId: request.user.sub, + }) + return response + .status(200) + .send({ user: { ...user, password_hash: undefined } }) + } catch (error) { + if (error instanceof ResourceNotFoundError) { + return response.status(404).send({ error: 'User was not Found !' }) + } else if (error instanceof InvalidCredentialsError) { + return response.status(401).send({ error: 'Invalid old Password!' }) + } + + throw error + } +} diff --git a/src/controller/user/routes.ts b/src/controller/user/routes.ts index ef5ed66..b02abaa 100644 --- a/src/controller/user/routes.ts +++ b/src/controller/user/routes.ts @@ -6,6 +6,7 @@ import { editUserById } from './editUserById' import { addImageUser } from './addImageToUser' import FastifyMultipart from '@fastify/multipart' import { verifyJWT } from '../middlewares/verifyJwt' +import { editUserPassword } from './editUserPassword' export async function userRoutes(app: FastifyInstance) { app.register(FastifyMultipart, { @@ -18,5 +19,7 @@ export async function userRoutes(app: FastifyInstance) { app.get('/user/:id', { onRequest: verifyJWT }, getUserById) app.get('/user', { onRequest: verifyJWT }, getUserByEmail) app.put('/user/:userId/edit', { onRequest: verifyJWT }, editUserById) + app.put('/user/edit/pass', { onRequest: verifyJWT }, editUserPassword) + app.post('/user/:userId/photo', { onRequest: verifyJWT }, addImageUser) } diff --git a/src/repositories/prisma/prisma-users-repository.ts b/src/repositories/prisma/prisma-users-repository.ts index acfc514..f3fdfe7 100644 --- a/src/repositories/prisma/prisma-users-repository.ts +++ b/src/repositories/prisma/prisma-users-repository.ts @@ -53,7 +53,15 @@ export class PrismaUsersRepository implements UserRepository { password_hash, userId, }: editUserPasswordRequestPrisma): Promise { - throw new Error('Method not implemented.') + const user = await prisma.user.update({ + where: { + id: userId, + }, + data: { + password_hash, + }, + }) + return user } async addPhotoUrl(userId: string, photoUrl: string): Promise { diff --git a/src/use-cases/user/editUserPasswordUseCase.ts b/src/use-cases/user/editUserPasswordUseCase.ts index 1f14155..97d382a 100644 --- a/src/use-cases/user/editUserPasswordUseCase.ts +++ b/src/use-cases/user/editUserPasswordUseCase.ts @@ -31,7 +31,7 @@ export class EditUserPasswordUseCase { const passwordMatched = await compare(oldPassword, user.password_hash) if (!passwordMatched) { - throw new InvalidCredentialsError('Email e/ou senha inválido.') + throw new InvalidCredentialsError() } const password_hash = await hash(newPassword, 6)