From ab728a113ac8ffb243eba98f70812bef47b30afc Mon Sep 17 00:00:00 2001 From: juliecoust Date: Mon, 29 Jan 2024 08:50:49 +0100 Subject: [PATCH] TST - convergeance and reset password --- src/domain/use-cases/auth/reset-password.ts | 2 +- .../interfaces/middleware/auth-validation.ts | 1 + .../middleware/auth-validation.ts | 19 ++++++++ src/presentation/routers/auth-router.ts | 8 ++-- .../sqlite-user-data-source.test.todo.ts | 43 ++++++++----------- .../use-cases/auth/reset-password.test.ts | 2 +- test/presentation/routes/auth-router.test.ts | 3 +- 7 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/domain/use-cases/auth/reset-password.ts b/src/domain/use-cases/auth/reset-password.ts index a89399c..786540a 100644 --- a/src/domain/use-cases/auth/reset-password.ts +++ b/src/domain/use-cases/auth/reset-password.ts @@ -27,7 +27,7 @@ export class ResetPassword implements ResetPasswordUseCase { } ) // if the user does not exist or the reset_password_code is not valid - if (!preexistant_user) throw new Error("User does not exist or token is not valid"); + if (!preexistant_user) throw new Error("User does not exist or reset_password_code is not valid"); // is the user validated ? if (!preexistant_user.valid_email) throw new Error("User email is not validated"); diff --git a/src/presentation/interfaces/middleware/auth-validation.ts b/src/presentation/interfaces/middleware/auth-validation.ts index a49ea71..6937c8f 100644 --- a/src/presentation/interfaces/middleware/auth-validation.ts +++ b/src/presentation/interfaces/middleware/auth-validation.ts @@ -4,6 +4,7 @@ export interface IMiddlewareAuthValidation { rulesPassword: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[] rulesAuthUserCredentialsModel: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[] rulesRequestResetPassword: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[] + rulesResetPassword: (ValidationChain | ((req: Request, res: Response, next: NextFunction) => Response | undefined))[] } diff --git a/src/presentation/middleware/auth-validation.ts b/src/presentation/middleware/auth-validation.ts index 1b808b3..7ab2657 100644 --- a/src/presentation/middleware/auth-validation.ts +++ b/src/presentation/middleware/auth-validation.ts @@ -90,4 +90,23 @@ export class MiddlewareAuthValidation implements IMiddlewareAuthValidation { }, ]; + rulesResetPassword = [ + // New password Validation + check('new_password') + .isLength({ min: 8 }).withMessage('Password must be at least 8 characters long.') + .matches(/\d/).withMessage('Password must contain a number.') + .matches(/[a-z]/).withMessage('Password must contain a lowercase letter.') + .matches(/[A-Z]/).withMessage('Password must contain an uppercase letter.') + .matches(/[@!#$%^&*()_+.,;:]/).withMessage('Password must contain a special character.') + .bail(), + // Error Handling Middleware + (req: Request, res: Response, next: NextFunction) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + // Centralized error handling for validation errors + return res.status(422).json({ errors: errors.array() }); + } + next(); + }, + ]; } diff --git a/src/presentation/routers/auth-router.ts b/src/presentation/routers/auth-router.ts index 252c3c1..72b3a59 100644 --- a/src/presentation/routers/auth-router.ts +++ b/src/presentation/routers/auth-router.ts @@ -119,7 +119,7 @@ export default function AuthRouter( }) // reset password confirm - router.put('/password/reset', async (req: Request, res: Response) => { + router.put('/password/reset', middlewareAuthValidation.rulesResetPassword, async (req: Request, res: Response) => { try { await resetPasswordUseCase.execute(req.body) res @@ -128,9 +128,9 @@ export default function AuthRouter( } catch (err) { console.log(err) if (err.message === "Token is not valid") res.status(401).send({ errors: ["Can't reset password"] }) - if (err.message === "No token provided") res.status(401).send({ errors: ["Can't reset password"] }) - if (err.message === "User does not exist or token is not valid") res.status(404).send({ errors: ["Can't reset password"] }) - if (err.message === "User email is not validated") res.status(403).send({ errors: ["Can't reset password"] }) + else if (err.message === "No token provided") res.status(401).send({ errors: ["Can't reset password"] }) + else if (err.message === "User does not exist or reset_password_code is not valid") res.status(404).send({ errors: ["Can't reset password"] }) + else if (err.message === "User email is not validated") res.status(403).send({ errors: ["Can't reset password"] }) else res.status(500).send({ errors: ["Can't reset password"] }) } }) diff --git a/test/data/data-sources/sqlite/sqlite-user-data-source.test.todo.ts b/test/data/data-sources/sqlite/sqlite-user-data-source.test.todo.ts index 6eefc1f..6f0d87d 100644 --- a/test/data/data-sources/sqlite/sqlite-user-data-source.test.todo.ts +++ b/test/data/data-sources/sqlite/sqlite-user-data-source.test.todo.ts @@ -53,31 +53,26 @@ describe("PG DataSource", () => { expect(result).toStrictEqual([OutputData]) }) - // TODO - test("create", async () => { - const InputData: UserRequesCreationtModel = { - last_name: "Smith", - first_name: "John", - email: "john@gmail.com", - password: "test123!", - organisation: "LOV", - country: "France", - user_planned_usage: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - } - const ds = new SQLiteUserDataSource(mockDatabase); - const inputData: UserRequesCreationtModel = { - last_name: "Smith", - first_name: "John", - email: "john@gmail.com", - password: "123test!", - organisation: "LOV", - country: "France", - user_planned_usage: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - } - await ds.create(inputData); - expect(mockDatabase.run).toHaveBeenCalledWith("INSERT INTO user (name) VALUES ($1)", ["Smith"]) - }) + describe('create method', () => { + test('should insert a user into the database', async () => { + const ds = new SQLiteUserDataSource(mockDatabase); + const inputData: UserRequesCreationtModel = { + last_name: "Smith", + first_name: "John", + email: "john@gmail.com", + password: "123test!", + organisation: "LOV", + country: "France", + user_planned_usage: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + await ds.create(inputData); + expect(mockDatabase.run).toHaveBeenCalledWith("INSERT INTO user (name) VALUES ($1)", ["Smith"]) + }); + + + }); + // test("deleteOne", async () => { // const ds = new SQLiteUserDataSource(mockDatabase); diff --git a/test/domain/use-cases/auth/reset-password.test.ts b/test/domain/use-cases/auth/reset-password.test.ts index 222ccc9..0a706dc 100644 --- a/test/domain/use-cases/auth/reset-password.test.ts +++ b/test/domain/use-cases/auth/reset-password.test.ts @@ -200,7 +200,7 @@ describe("Change password Use Case", () => { await reset_password.execute(InputData); } catch (error) { - expect(error.message).toBe("User does not exist or token is not valid"); + expect(error.message).toBe("User does not exist or reset_password_code is not valid"); } expect(mockUserRepository.verifyResetPasswordToken).toHaveBeenCalledWith(InputData.reset_password_token); diff --git a/test/presentation/routes/auth-router.test.ts b/test/presentation/routes/auth-router.test.ts index cc5a2c2..2336f06 100644 --- a/test/presentation/routes/auth-router.test.ts +++ b/test/presentation/routes/auth-router.test.ts @@ -30,6 +30,7 @@ class MockRefreshTokenUseCase implements RefreshTokenUseCase { } } class MockMiddlewareAuthValidation implements IMiddlewareAuthValidation { + rulesResetPassword = []; rulesRequestResetPassword = []; rulesPassword = [] rulesAuthUserCredentialsModel = []; @@ -488,7 +489,7 @@ describe("User Router", () => { new_password: "test123!!!!!!!", reset_password_token: "reset_password_token", } - const error_message = "User does not exist or token is not valid" + const error_message = "User does not exist or reset_password_code is not valid" const expectedResponse = { errors: ["Can't reset password"] } jest.spyOn(mockResetPasswordUseCase, "execute").mockImplementation(() => Promise.reject(new Error(error_message)))