Skip to content

Commit df3755e

Browse files
author
Wcoder547
committed
add the login and logut functionality in user controller
1 parent 9af8723 commit df3755e

File tree

6 files changed

+142
-7
lines changed

6 files changed

+142
-7
lines changed

project-backend/src/controllers/user.controller.js

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ const userRegister = AsyncHandler(async (req, res) => {
3232
throw new ApiError(409, "User Already Exsisted.Please Login");
3333
}
3434
// console.log(req.files);
35-
const avatarLocalPath = req.files?.avatar[0]?.path;
35+
let avatarLocalPath = null;
36+
if (req.files && req.files.avatar && req.files.avatar[0]) {
37+
avatarLocalPath = req.files.avatar[0].path;
38+
}
39+
3640
// const coverLocalPath = req.files?.coverimage[0]?.path;
3741
if (!avatarLocalPath) {
3842
throw new ApiError(400, "Avatar file is required!!");
@@ -67,4 +71,89 @@ const userRegister = AsyncHandler(async (req, res) => {
6771
.json(new ApiResponse(200, createdUser, "User Registered Successfully"));
6872
});
6973

70-
export default userRegister;
74+
const geneareAccessAndRefreshToken = async (userId) => {
75+
try {
76+
const user = await User.findById(userId);
77+
const accessToken = user.generateAccessToken();
78+
const refreshToken = user.generateRefreshToken();
79+
user.refreshtoken = refreshToken;
80+
await user.save({ validateBeforeSave: false });
81+
return { accessToken, refreshToken };
82+
} catch (error) {
83+
throw new ApiError(500, "Error !! cannot produce access and refreshtoken");
84+
}
85+
};
86+
const userLogin = AsyncHandler(async (req, res) => {
87+
//todos
88+
//req->body = data
89+
// username& email
90+
//check the user in database
91+
// check the password
92+
// access and refresh token
93+
// send in cookies
94+
95+
const { username, email, password } = req.body;
96+
if (!username || !email) {
97+
throw new ApiError(400, "Username or Email is required");
98+
}
99+
const user = await User.findOne({
100+
$or: [{ username }, { email }],
101+
});
102+
if (!user) {
103+
throw new ApiError(400, "you dont have account.please signup");
104+
}
105+
const isPasswordMatched = await User.isPasswordCorrect(password);
106+
if (!isPasswordMatched) {
107+
throw new ApiError(401, "Please provide corrected password");
108+
}
109+
const { accessToken, refreshToken } = geneareAccessAndRefreshToken(user._id);
110+
111+
const loggedInUser = await User.findById(user._id).select(
112+
"-password -refreshToken"
113+
);
114+
115+
const options = {
116+
httpOnly: true,
117+
secure: true,
118+
};
119+
return res
120+
.status(200)
121+
.cookies("accessToken", accessToken, options)
122+
.cookies("refreshToken", refreshToken, options)
123+
.json(
124+
new ApiResponse(
125+
200,
126+
{
127+
user: loggedInUser,
128+
accessToken,
129+
refreshToken,
130+
},
131+
"user Successfully Loggedin"
132+
)
133+
);
134+
});
135+
136+
const userLogout = AsyncHandler(async (req, res) => {
137+
await User.findByIdAndUpdate(
138+
req.user._id,
139+
{
140+
$set: {
141+
refreshtoken: undefined,
142+
},
143+
},
144+
{
145+
new: true,
146+
}
147+
);
148+
149+
const options = {
150+
httpOnly: true,
151+
secure: true,
152+
};
153+
154+
return res(200)
155+
.clearCookie("accessToken", options)
156+
.clearCookie("refreshToken", options)
157+
.json(new ApiResponse(200, {}, "Successfully Loggout"));
158+
});
159+
export { userRegister, userLogin, userLogout };
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import jwt from "json-web-token";
2+
import { User } from "../models/user.models";
3+
import { ApiError } from "../utils/ApiError";
4+
import { AsyncHandler } from "../utils/AsyncHandler";
5+
6+
export const verifyJwt = AsyncHandler(async (req, _, next) => {
7+
try {
8+
const token =
9+
req.cookies?.accessToken ||
10+
req.header("Authorization")?.replace("Bearer", " ");
11+
12+
if (!token) {
13+
throw new ApiError(401, "UnAuthorized Request");
14+
}
15+
16+
const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
17+
18+
const user = await User.findById(decodedToken?._id).select(
19+
"-password,-refreshToken"
20+
);
21+
22+
if (!user) {
23+
//TODOS discuss about front-end
24+
throw new ApiError(500, "invalid Access Token");
25+
}
26+
req.user = user;
27+
next();
28+
} catch (error) {
29+
throw new ApiError(401, error?.message || "invalid accessToken ");
30+
}
31+
});

project-backend/src/models/user.models.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ const userSchema = new Schema(
4848
{ timestamps: true }
4949
);
5050

51-
userSchema.pre("save", function (next) {
51+
userSchema.pre("save", async function (next) {
52+
console.log("hello");
5253
if (!this.isModified("passowrd")) return next();
53-
this.password = bcrypt.hash(this.password, 10);
54-
next();
54+
55+
try {
56+
const salt = await bcrypt.genSalt(10);
57+
this.password = await bcrypt.hash(this.password, salt);
58+
next();
59+
} catch (err) {
60+
next(err);
61+
}
5562
});
5663
userSchema.methods.isPasswordCorrect = async function (passowrd) {
5764
return await bcrypt.compare(passowrd, this.passowrd);
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import { Router } from "express";
2-
import userRegister from "../controllers/user.controller.js";
2+
import userRegister, {
3+
userLogin,
4+
userLogout,
5+
} from "../controllers/user.controller.js";
36
import { upload } from "../middlewares/multer.middleware.js";
7+
import { verifyJwt } from "../middlewares/auth.middleware.js";
48
const router = Router();
59
const cpUpload = upload.fields([
610
{ name: "avatar", maxCount: 1 },
711
{ name: "coverimage", maxCount: 1 },
812
]); //this will upload only one avatar and one coverimage
913

1014
router.route("/register").post(cpUpload, userRegister);
15+
router.route("/login").post(userLogin);
16+
17+
//Secured Routes
18+
router.route("/logout").post(verifyJwt, userLogout);
1119
export default router;

project-backend/src/utils/cloudinary.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const uploadOnCloudinary = async function (localFilePath) {
1919
// height: 500, // Transform the image: auto-crop to square aspect_ratio
2020
});
2121
//console.log("file is uploaded on cloudinary", await response.url);
22-
fs.unlink(filePath, (err) => {
22+
fs.unlink(localFilePath, (err) => {
2323
if (err) {
2424
console.error(`Error deleting file: ${err.message}`);
2525
return;

0 commit comments

Comments
 (0)