Added signin route in backend
This commit is contained in:
130
backend/package-lock.json
generated
130
backend/package-lock.json
generated
@@ -10,9 +10,11 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.1.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.21.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongoose": "^8.8.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
@@ -324,6 +326,12 @@
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
@@ -427,6 +435,28 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
|
||||
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "0.7.2",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser/node_modules/cookie": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
@@ -530,6 +560,15 @@
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -1013,6 +1052,55 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
|
||||
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^1.4.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/kareem": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
|
||||
@@ -1028,18 +1116,60 @@
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.mergewith": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.1.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.21.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongoose": "^8.8.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
|
||||
@@ -3,4 +3,5 @@ dotenv.config();
|
||||
|
||||
export const PORT = Number(process.env.PORT);
|
||||
export const DB_URL = process.env.DB_CONNECTION;
|
||||
export const SALT = Number(process.env.SALT_ROUNDS);
|
||||
export const SALT = Number(process.env.SALT_ROUNDS);
|
||||
export const JWT_PRIVATE = process.env.JWT_PRIVATE;
|
||||
@@ -1,28 +1,55 @@
|
||||
import { signupService } from "../services/user.service.js";
|
||||
import { signinService, 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
|
||||
})
|
||||
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,
|
||||
});
|
||||
}
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function signinController(req, res) {
|
||||
try {
|
||||
const { email, password } = req.body;
|
||||
const { token, userData } = await signinService(email, password);
|
||||
res.cookie("access-token", token, {
|
||||
httpOnly: true,
|
||||
maxAge: 10 * 24 * 60 * 60 * 1000, // 10 days
|
||||
}).status(200).json({
|
||||
success : true,
|
||||
message : "User signedin successfully.",
|
||||
user : userData
|
||||
});
|
||||
|
||||
} 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ 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';
|
||||
import cookieParser from "cookie-parser";
|
||||
|
||||
|
||||
const app = express();
|
||||
@@ -20,6 +21,7 @@ const io = new Server(httpServer, {
|
||||
}
|
||||
})
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
app.get("/ping", (_req, res) => {
|
||||
|
||||
@@ -13,4 +13,14 @@ export const createUser = async (username, email, password) => {
|
||||
catch(err) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export async function findUserByEmail(email) {
|
||||
try{
|
||||
const user = await UserModel.findOne({email});
|
||||
return user;
|
||||
}
|
||||
catch(err){
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import express from "express";
|
||||
import { signupController } from "../../controllers/user.controller.js";
|
||||
import { signinController, signupController } from "../../controllers/user.controller.js";
|
||||
import validate from "../../validations/validator.js";
|
||||
import signupSchema from "../../validations/signupValidation.js";
|
||||
import signinSchema from "../../validations/signinValidation.js";
|
||||
const userRouter = express.Router();
|
||||
|
||||
/**
|
||||
@@ -39,4 +40,6 @@ userRouter.get("/test", (req, res) => {
|
||||
*/
|
||||
userRouter.post("/signup", validate(signupSchema), signupController);
|
||||
|
||||
userRouter.post("/signin", validate(signinSchema), signinController);
|
||||
|
||||
export default userRouter;
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SALT } from "../config/veriables.js";
|
||||
import { createUser } from "../repositories/user.repo.js";
|
||||
import { JWT_PRIVATE, SALT } from "../config/veriables.js";
|
||||
import { createUser, findUserByEmail } from "../repositories/user.repo.js";
|
||||
import bcrypt from "bcrypt";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
export async function signupService(username, email, password) {
|
||||
try {
|
||||
@@ -24,3 +25,35 @@ export async function signupService(username, email, password) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function signinService(email, password) {
|
||||
try{
|
||||
if (email.trim() == "" || password.trim() == "") {
|
||||
throw {
|
||||
statusCode: 400,
|
||||
message: "All fields are required",
|
||||
};
|
||||
}
|
||||
|
||||
const user = await findUserByEmail(email);
|
||||
if (!user){
|
||||
throw {
|
||||
statusCode : 404,
|
||||
message : "User not found."
|
||||
}
|
||||
}
|
||||
if (!bcrypt.compareSync(password, user?.password)){
|
||||
throw {
|
||||
statusCode : 401,
|
||||
message : "Password isn't correct."
|
||||
}
|
||||
}
|
||||
|
||||
const token = jwt.sign({id : user._id}, JWT_PRIVATE);
|
||||
const {password:pass, ...userData} = user._doc;
|
||||
return {token, userData};
|
||||
}
|
||||
catch(err){
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
20
backend/src/validations/signinValidation.js
Normal file
20
backend/src/validations/signinValidation.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const signinSchema = z.object({
|
||||
email: z
|
||||
.string({
|
||||
required_error: "Email is required.",
|
||||
})
|
||||
.min(1, "Email is required.")
|
||||
.max(200, "Email cant be more then 200 charecters.")
|
||||
.email("Invalid email input"),
|
||||
|
||||
password: z
|
||||
.string({
|
||||
required_error: "Password is required",
|
||||
})
|
||||
.min(6, "Password cant be less than 6 charecters")
|
||||
.max(50, "Password cant be more than 50 charecters"),
|
||||
});
|
||||
|
||||
export default signinSchema;
|
||||
Reference in New Issue
Block a user