diff --git a/__test__/user.test.ts b/__test__/user.test.ts index 739538e..32e9a70 100644 --- a/__test__/user.test.ts +++ b/__test__/user.test.ts @@ -44,14 +44,14 @@ test('should return 409 when registering with an existing email', async () => { .send(userData); expect(response.status).toBe(409); }, 20000); -test('should return 500 when registering with an invalid credential', async () => { +test('should return 400 when registering with an invalid credential', async () => { const userData = { email: 'test@mail.com', name: "", username: 'existinguser', }; const response = await request(app) .post('/api/v1/users/register') .send(userData); - expect(response.status).toBe(500); }, 20000); }); + expect(response.status).toBe(400); }, 20000); }); test("should return all users in db --> given '/api/v1/users'", async () => { const spy = jest.spyOn(User, "findAll"); diff --git a/package.json b/package.json index e8bd346..e693874 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,9 @@ "cross-env": "^7.0.3", "cryptr": "^6.3.0", "dotenv": "^16.4.5", + "email-validator": "^2.0.4", "express": "^4.19.2", + "joi": "^17.12.3", "jsonwebtoken": "^9.0.2", "path": "^0.12.7", "pg": "^8.11.5", diff --git a/src/controllers/userControllers.ts b/src/controllers/userControllers.ts index bf37e46..f3fed45 100644 --- a/src/controllers/userControllers.ts +++ b/src/controllers/userControllers.ts @@ -56,14 +56,17 @@ export const userLogin = async(req:Request,res:Response) =>{ export const createUserController = async (req: Request, res: Response) => { - try { + try { const { name, email, username, password } = req.body; const user = await createUserService(name, email, username, password); + if (!user) { return res.status(409).json({ status: 409, - message: 'User already exists' }); + message: 'Username or email already exists' + }); } + res.status(201).json({ status: 201, message: "User successfully created." diff --git a/src/middleware/validator.ts b/src/middleware/validator.ts new file mode 100644 index 0000000..93cc2b8 --- /dev/null +++ b/src/middleware/validator.ts @@ -0,0 +1,35 @@ +import { Request, Response, NextFunction } from 'express'; +import validator from 'email-validator'; +import { Schema } from 'joi'; + +export const emailValidation = (req: Request, res: Response, next: NextFunction) => { + const { email } = req.body; + + if (!email) { + return res.status(400).json({ + status: 400, + message: "Email is required" + }); + } + + const isValid = validator.validate(email); + if (isValid) { + next(); + } else { + return res.status(400).json({ + status: 400, + message: "Email is not valid." + }); + } +}; + + +export const validateSchema = (schema: Schema) => { + return (req: Request, res: Response, next: NextFunction) => { + const { error } = schema.validate(req.body); + if (error) { + return res.status(400).json({ message: error.details[0].message }); + } + next(); + }; +}; \ No newline at end of file diff --git a/src/routes/userRoutes.ts b/src/routes/userRoutes.ts index 3b60d5d..23d9f47 100644 --- a/src/routes/userRoutes.ts +++ b/src/routes/userRoutes.ts @@ -4,12 +4,21 @@ import { createUserController, userLogin } from "../controllers/userControllers"; +import { + emailValidation, + validateSchema, + } from "../middleware/validator"; +import signUpSchema from "../schemas/signUpSchema"; const userRoutes = Router(); userRoutes.get("/", fetchAllUsers); userRoutes.post('/login',userLogin); -userRoutes.post("/register", createUserController) +userRoutes.post("/register", + emailValidation, + validateSchema(signUpSchema), + createUserController +) -export default userRoutes; +export default userRoutes; diff --git a/src/schemas/signUpSchema.ts b/src/schemas/signUpSchema.ts new file mode 100644 index 0000000..030fcd3 --- /dev/null +++ b/src/schemas/signUpSchema.ts @@ -0,0 +1,21 @@ +import Joi from "joi"; + +export const signUpSchema = Joi.object({ + name: Joi.string() + .min(5) + .max(40) + .required(), + username: Joi.string() + .min(4) + .required(), + email: Joi.string() + .min(6) + .required() + .email(), + password: Joi.string() + .min(6) + .max(20) + .required() +}).options({ allowUnknown: false }); + +export default signUpSchema \ No newline at end of file diff --git a/src/services/user.service.ts b/src/services/user.service.ts index 0f12e3d..dbdeae8 100644 --- a/src/services/user.service.ts +++ b/src/services/user.service.ts @@ -1,6 +1,7 @@ import { errors } from "undici-types"; import User from "../sequelize/models/users"; -import { hashedPassword } from "../helpers/hashPassword"; +import { hashedPassword } from "../utils/hashPassword"; +import { Op } from "sequelize"; export const getAllUsers = async () => { try { @@ -30,7 +31,11 @@ export const loggedInUser = async(email:string) => { }; }; export const createUserService = async (name: string, email: string, username: string, password: string): Promise => { - const existingUser = await User.findOne({ where: { email } }); + const existingUser = await User.findOne({ + where: { + [Op.or]: [{ email }, { username }] + } + }); if (existingUser) { return null; } diff --git a/src/helpers/hashPassword.ts b/src/utils/hashPassword.ts similarity index 100% rename from src/helpers/hashPassword.ts rename to src/utils/hashPassword.ts