From a3e2f7a5e72b2d7520d88cf95e6db0ced912ef35 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Fri, 22 Nov 2024 01:09:52 +0530 Subject: [PATCH] Apply csrf to user controller --- controllers/user.controller.js | 29 +++++++++++++++++++++++------ index.js | 5 ++++- middleware/verifyJWT.middleware.js | 8 ++++---- routes/user.route.js | 7 +++---- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/controllers/user.controller.js b/controllers/user.controller.js index 4d73e83..36ab48b 100644 --- a/controllers/user.controller.js +++ b/controllers/user.controller.js @@ -86,6 +86,7 @@ const registerUser = asyncHandler(async (req, res) => { }); const loginUser = asyncHandler(async (req, res) => { + console.log(req.csrfToken()); // Get data vaidated data from frontend let { usernameOrEmail, password } = req.body; @@ -124,17 +125,22 @@ const loginUser = asyncHandler(async (req, res) => { return ApiResponse.success( res, + "User logged In Successfully", { user: rolesObjectToArray(loggedInUser), accessToken, refreshToken, + csrfToken: req.csrfToken(), }, - "User logged In Successfully", 200 ); }); const logout = asyncHandler(async (req, res) => { + if (!req.user?._id) { + ApiResponse.notFound(res, "User not loggedin"); + } + // Remove remove user credentials from Db await User.findByIdAndUpdate( req.user._id, @@ -158,7 +164,12 @@ const logout = asyncHandler(async (req, res) => { //Send response back - ApiResponse.success(res, "User logged out successfully", {}, 200); + ApiResponse.success( + res, + "User logged out successfully", + { csrfToken: req.csrfToken() }, + 200 + ); }); const refreshAccessToken = asyncHandler(async (req, res) => { @@ -201,11 +212,12 @@ const refreshAccessToken = asyncHandler(async (req, res) => { ApiResponse.success( res, + "New Tokens generated succesfully", { accessToken, refreshToken: newRefreshToken, + csrfToken: req.csrfToken(), }, - "New Tokens generated succesfully", 200 ); } catch (error) { @@ -238,8 +250,8 @@ const updateUserInfo = asyncHandler(async (req, res) => { console.log("User updated successfully"); ApiResponse.success( res, - rolesObjectToArray(updatedUser), "User updated successfully", + { user: rolesObjectToArray(updatedUser), csrfToken: req.csrfToken() }, 200 ); } catch (err) { @@ -307,7 +319,12 @@ const updateAvatar = asyncHandler(async (req, res) => { } }); } - ApiResponse.success(res, user, "User avatar updated successfully", 200); + ApiResponse.success( + res, + "User avatar updated successfully", + { user: rolesObjectToArray(user), csrfToken: req.csrfToken() }, + 200 + ); }); const updateUsername = asyncHandler(async (req, res) => { @@ -341,7 +358,7 @@ const updateUsername = asyncHandler(async (req, res) => { ApiResponse.success( res, "User updated successfully", - rolesObjectToArray(user), + { user: rolesObjectToArray(user), csrfToken: req.csrfToken() }, 200 ); }); diff --git a/index.js b/index.js index 2927c8b..28dd287 100644 --- a/index.js +++ b/index.js @@ -12,7 +12,6 @@ const connectDB = require("./config/dbConn"); const restrictDirectoryAccess = require("./middleware/uploads.middleware"); const expressSession = require("./middleware/espressSession.middleware"); const csrfProtection = require("./middleware/csrf.middleware"); -const limiter = require("./middleware/rateLimit.middleware"); const PORT = process.env.PORT || 3000; @@ -53,6 +52,10 @@ app.use( express.static(path.join(__dirname, "public/uploads")) ); +app.get("/api/v1/csrf-token", csrfProtection, (req, res) => { + res.status(200).json({ csrfToken: req.csrfToken() }); +}); + //routes app.use("/api/v1", require("./routes/root")); app.use("/api/v1/user", require("./routes/user.route")); diff --git a/middleware/verifyJWT.middleware.js b/middleware/verifyJWT.middleware.js index 2cad785..d2c84d7 100644 --- a/middleware/verifyJWT.middleware.js +++ b/middleware/verifyJWT.middleware.js @@ -1,5 +1,5 @@ const User = require("../model/user.model"); -const apiXRes = require("../utils/ApiResponse"); +const ApiResponse = require("../utils/ApiResponse"); const asyncHandler = require("../utils/asyncHandler"); const jwt = require("jsonwebtoken"); @@ -10,7 +10,7 @@ const verifyJWT = asyncHandler(async (req, res, next) => { req.header("Authorisation")?.replace("Bearer ", ""); // req.header for requests which came from mobile application if (!token) { - apiXRes.unauthorized( + return ApiResponse.unauthorized( res, "Unauthorised request make sure you are logged in and you have proper access rights" ); @@ -23,14 +23,14 @@ const verifyJWT = asyncHandler(async (req, res, next) => { ); if (!user) { - apiXRes.notFound(res, "Invalid access token"); + return ApiResponse.notFound(res, "Invalid access token"); } req.user = user; next(); } catch (error) { - apiXRes.unauthorized(res, error?.message || "Invalid access token"); + ApiResponse.unauthorized(res, error?.message || "Invalid access token"); } }); diff --git a/routes/user.route.js b/routes/user.route.js index fe3c3ed..40ed2c7 100644 --- a/routes/user.route.js +++ b/routes/user.route.js @@ -14,16 +14,15 @@ const limiter = require("../middleware/rateLimit.middleware"); const upload = require("../middleware/multer.middleware"); const verifyJWT = require("../middleware/verifyJWT.middleware"); const verifyRoles = require("../middleware/verifyRoles.middleware"); +const csrfProtection = require("../middleware/csrf.middleware"); const router = require("express").Router(); router.route("/register").post(upload.single("avatar"), registerUser); -router.route("/login").post(limiter("30s", 2), loginUser); // if using form data in frontend then add upload.none() middleware in the route -// or check:=> Content-Type multipart/form-data (in postman) -// or send data in form data in postman as: x-www-form-urlencoded +router.route("/login").post(limiter("15m", 100), csrfProtection, loginUser); //Secured Routes -router.route("/logout").post(limiter("30s", 1), verifyJWT, logout); +router.route("/logout").post(limiter("15m", 100), verifyJWT, logout); router.route("/refresh-access-token").get(verifyJWT, refreshAccessToken); router.route("/update-user").patch(verifyJWT, updateUserInfo); router.route("/update-username").patch(verifyJWT, updateUsername);