Skip to content

Commit

Permalink
added RefreshAccessToken
Browse files Browse the repository at this point in the history
  • Loading branch information
DrDead0 committed Nov 3, 2024
1 parent 49e17aa commit 00a93cf
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 62 deletions.
148 changes: 88 additions & 60 deletions src/controllers/user.controllers.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
// Imports
import { asyncHandler } from "../utils/asyncHandler.js";
import { User } from "../models/user.model.js";
import { uploadOnCloudinary } from "../utils/cloudinary.js";
import { apiResponse } from "../utils/apiResponse.js";
import { ApiError } from "../utils/apiError.js";
import mongoose from "mongoose";
import jwt from "jsonwebtoken";
import { refreshAccessToken } from "./path/to/user.controllers.js";

// Helper function: generateAccessAndRefreshToken
const generateAccessAndRefreshToken = async (userId) => {
try {
const userID = await User.findById(userId);
const accessToken = userID.generateAccessToken();
const refreshToken = userID.generateRefreshToken();
userID.refreshToken = refreshToken;
await userID.save({ validateBeforeSave: false });
const user = await User.findById(userId);
const accessToken = user.generateAccessToken();
const refreshToken = user.generateRefreshToken();
user.refreshToken = refreshToken;
await user.save({ validateBeforeSave: false });
return { accessToken, refreshToken };
} catch (error) {
throw new ApiError(405, "Something went wrong while generating Access Token and Refresh Token");
throw new ApiError(405, "Error generating access and refresh tokens.");
}
};

// Controller: registerUser
const registerUser = asyncHandler(async (req, res) => {
const { fullname, email, username, password } = req.body;
if ([fullname, email, username, password].some((field) => field?.trim() === "")) {
throw new ApiError(400, "All fields are required");
throw new ApiError(400, "All fields are required.");
}

const existUser = await User.findOne({
$or: [{ username }, { email }],
});
const existUser = await User.findOne({ $or: [{ username }, { email }] });
if (existUser) {
throw new ApiError(409, "User Already Exist");
throw new ApiError(409, "User already exists.");
}

const avatarLocalPath = req.files?.avatar[0]?.path;
let coverImageLocalPath;
if (req.files && req.files.coverImage && Array.isArray(req.files.coverImage) && req.files.coverImage.length > 0) {
coverImageLocalPath = req.files.coverImage[0].path;
}
let coverImageLocalPath = req.files?.coverImage?.[0]?.path;

if (!avatarLocalPath) {
throw new ApiError(400, "Avatar file is required");
throw new ApiError(400, "Avatar file is required.");
}

const avatar = await uploadOnCloudinary(avatarLocalPath);
const coverImage = await uploadOnCloudinary(coverImageLocalPath);
if (!avatar || !avatar.url) {
throw new ApiError(400, "Avatar file is required");
throw new ApiError(400, "Error uploading avatar.");
}

const newuser = await User.create({
const newUser = await User.create({
fullname,
avatar: avatar.url,
coverImage: coverImage?.url || "",
Expand All @@ -56,85 +56,113 @@ const registerUser = asyncHandler(async (req, res) => {
username: username.toLowerCase(),
});

const createdUser = await User.findById(newuser._id).select("-password -refreshToken");
const createdUser = await User.findById(newUser._id).select("-password -refreshToken");

if (!createdUser) {
throw new ApiError(500, "Something went wrong while registering the user");
throw new ApiError(500, "Error registering user.");
}
return res.status(201).json(new apiResponse(201, createdUser, "User registered successfully"));
return res.status(201).json(new apiResponse(201, createdUser, "User registered successfully."));
});

// Controller: loginUser
const loginUser = asyncHandler(async (req, res) => {
const { email, password, username } = req.body;

if (!((email || username) && password)) {
throw new ApiError(404, "Email or Username and Password are required.");
throw new ApiError(400, "Email or Username and Password are required.");
}

const lUser = await User.findOne({
$or: [{ email }, { username }],
});

if (!lUser) {
throw new ApiError(400, "User not found.");
}
const lUser = await User.findOne({ $or: [{ email }, { username }] });

const isPasswordValid = await lUser.isPasswordCorrect(password);
if (!isPasswordValid) {
throw new ApiError(401, "Invalid Password");
if (!lUser || !(await lUser.comparePassword(password))) {
throw new ApiError(401, "Invalid Email/Username or Password.");
}

const { accessToken, refreshToken } = await generateAccessAndRefreshToken(lUser._id);

const loggedInUser = await User.findById(lUser._id).select("-password -refreshToken");

const options = {
httpOnly: true,
secure: true,
};

return res.status(200)
return res
.status(200)
.cookie("accessToken", accessToken, options)
.cookie("refreshToken", refreshToken, options)
.json(new apiResponse(200, {
user: loggedInUser,
accessToken,
refreshToken,
}, "User logged in successfully"));
.json(new apiResponse(200, loggedInUser, "User logged in successfully."));
});


const logoutUser = asyncHandler(async (req, res) => {
if (!req.user || !req.user._id) {
throw new ApiError(401, "User not authenticated");
throw new ApiError(401, "User not authenticated.");
}

await User.findByIdAndUpdate(
req.user._id,
{
$set: {
refreshToken: undefined,
},
},
{ new: true }
);
await User.findByIdAndUpdate(req.user._id, { $set: { refreshToken: undefined } }, { new: true });

const options = {
httpOnly: true,
secure: true,
};

return res.status(200)
return res
.status(200)
.clearCookie("accessToken", options)
.clearCookie("refreshToken", options)
.json(new apiResponse(200, {}, "User Successfully Logged Out"));
.json(new apiResponse(200, {}, "User successfully logged out."));
});
const refreshAccessToken = asyncHandler(async(req,res)=>{
const incomingAccessToken = req.cookie.refreshToken || req.body.refreshToken
if(!incomingAccessToken){
throw new ApiError(401,"Unauthorized Request ")


const refreshAccessToken = asyncHandler(async (req, res) => {
const incomingRefreshToken = req.cookies.refreshToken || req.body.refreshToken;

if (!incomingRefreshToken) {
throw new ApiError(401, "Unauthorized request.");
}

try {
const decodedToken = jwt.verify(
incomingRefreshToken,
process.env.REFRESH_TOKEN_SECRET
);

const user = await User.findById(decodedToken._id);

if (!user) {
throw new ApiError(401, "Invalid refresh token.");
}

if (incomingRefreshToken !== user.refreshToken) {
throw new ApiError(401, "Expired refresh token.");
}

const options = {
httpOnly: true,
secure: true,
};

const { accessToken, refreshToken } = await generateAccessAndRefreshToken(user._id);

return res
.status(200)
.cookie("accessToken", accessToken, options)
.cookie("refreshToken", refreshToken, options)
.json(
new apiResponse(
200,
{ accessToken, refreshToken },
"Access token refreshed successfully."
)
);
} catch (error) {
throw new ApiError(
401,
error.message || "Invalid refresh token."
);
}
const decodedToken = jwt.verify(
incomingAccessToken,
process.env.REFRESH_TOKEN_SECRET
)
})
export { registerUser, loginUser, logoutUser };
});


export { registerUser, loginUser, logoutUser, refreshAccessToken };
4 changes: 2 additions & 2 deletions src/routes/user.router.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Router } from 'express';
import { loginUser, logoutUser, registerUser } from '../controllers/user.controllers.js';
import { loginUser, logoutUser, registerUser,refreshAccessToken } from '../controllers/user.controllers.js';
import { verifyJWT } from '../middlewares/auth.middleware.js';
import { upload } from '../middlewares/multer.middleware.js';

Expand All @@ -17,5 +17,5 @@ userRouter.route("/login").post(loginUser);

// Secure Routes made by ashish chaurasiya hehehehe
userRouter.route("/logout").post(verifyJWT, logoutUser);

userRouter.route("refresh-Token").post(refreshAccessToken)
export default userRouter;

0 comments on commit 00a93cf

Please sign in to comment.