Added signup route 👤

This commit is contained in:
Manik Maity
2024-11-07 21:08:08 +05:30
parent a3c5140bb4
commit 8741f40304
12 changed files with 1096 additions and 3 deletions

View File

@@ -2,4 +2,5 @@ import dotenv from "dotenv";
dotenv.config();
export const PORT = Number(process.env.PORT);
export const DB_URL = process.env.DB_CONNECTION;
export const DB_URL = process.env.DB_CONNECTION;
export const SALT = Number(process.env.SALT_ROUNDS);

View File

@@ -0,0 +1,28 @@
import { signupService } from "../services/user.service.js";
export async function signupController(req, res) {
try {
const { username, email, password } = req.body;
const user = await signupService(username, email, password);
res.status(201).json({
success : true,
message : "User created successfully",
data : user
})
}
catch(err){
console.log(err);
if (err.statusCode){
res.status(err.statusCode).json({
success : false,
message : err.message
})
}
else {
res.status(500).json({
success : false,
message : err.message
})
}
}
}

View File

@@ -4,10 +4,16 @@ import { createServer } from 'http'
import { Server } from 'socket.io'
import { PORT } from './config/veriables.js';
import { connectDB } from './config/dbConfig.js';
import userRouter from './routes/v1/user.route.js';
import swaggerDocs from '../swagger.js';
import swaggerUi from 'swagger-ui-express';
const app = express();
const httpServer = createServer(app);
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));
const io = new Server(httpServer, {
cors: {
origin: "*"
@@ -19,6 +25,7 @@ app.use(express.json())
app.get("/ping", (_req, res) => {
res.json({ message: "pong" })
})
app.use("/api/v1/user", userRouter);
await connectDB();
httpServer.listen(PORT, () => {

View File

@@ -0,0 +1,28 @@
import mongoose, { Schema } from "mongoose";
const userSchema = new Schema({
username : {
type : String,
required : true,
trim : true
},
email : {
type : String,
required : true,
trim : true,
unique : true
},
password : {
type : String,
required : true
},
bookmarks : {
type : [Schema.Types.ObjectId],
ref : "Poll",
default : []
}
}, {timestamps : true});
const UserModel = mongoose.model("User", userSchema);
export default UserModel;

View File

@@ -0,0 +1,16 @@
import UserModel from "../models/user.model.js"
export const createUser = async (username, email, password) => {
try {
const createdUser = await UserModel.create({
username,
email,
password
})
return createdUser;
}
catch(err) {
throw err
}
}

View File

@@ -0,0 +1,42 @@
import express from "express";
import { signupController } from "../../controllers/user.controller.js";
import validate from "../../validations/validator.js";
import signupSchema from "../../validations/signupValidation.js";
const userRouter = express.Router();
/**
* @swagger
* /user/test:
* get:
* summary: Test route for user
* tags: [User]
* responses:
* 200:
* description: Success
*/
userRouter.get("/test", (req, res) => {
res.json({
success: true,
message : "User route is working✔"
})
})
/**
* @swagger
* /user/signup:
* post:
* summary: User signup
* tags: [User]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/User'
* responses:
* 200:
* description: Success
*/
userRouter.post("/signup", validate(signupSchema), signupController);
export default userRouter;

View File

@@ -0,0 +1,26 @@
import { SALT } from "../config/veriables.js";
import { createUser } from "../repositories/user.repo.js";
import bcrypt from "bcrypt";
export async function signupService(username, email, password) {
try {
if (username.trim() == "" || email.trim() == "" || password.trim() == "") {
throw {
statusCode: 400,
message: "All fields are required",
};
}
const hashedPassword = bcrypt.hashSync(password, SALT);
const user = await createUser(username, email, hashedPassword);
return user;
} catch (err) {
if (err.code == 11000) {
throw {
statusCode: 409,
message: "User already exists",
};
} else {
throw err;
}
}
}

View File

@@ -0,0 +1,27 @@
import { z } from "zod";
const signupSchema = z.object({
username: z
.string({
required_error: "Username is required",
invalid_type_error: "Username must be a string",
})
.min(3, "Username must be at least 3 characters long")
.max(50, "Username must be at most 50 characters long")
.trim(),
email: z
.string({
required_error: "Email is required",
invalid_type_error: "Email must be a string",
})
.email("Invalid email"),
password: z
.string({
required_error: "Password is required",
invalid_type_error: "Password must be a string",
})
.min(6, "Password must be at least 6 characters long")
.max(50, "Password must be at most 50 characters long"),
});
export default signupSchema;

View File

@@ -0,0 +1,17 @@
function validate (schema){
return async (req, res, next) => {
try {
await schema.parseAsync(req.body);
next();
}
catch(err){
res.status(400).json({
success : false,
message : "Validation error",
errors : err.errors
})
}
}
}
export default validate;