From e2ddffe24bd9037c7825d621b0e3ee6697f203dd Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 21 Jul 2025 11:05:48 -0700 Subject: [PATCH] remove userId param from routes --- server/controllers/authController.js | 40 +++++++++++++++------------ server/db/mongo/modules/userModule.js | 26 ++++++++--------- server/routes/authRoute.js | 5 ++-- server/validation/joi.js | 5 ---- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/server/controllers/authController.js b/server/controllers/authController.js index a5c7d6cac..1cc1a747a 100755 --- a/server/controllers/authController.js +++ b/server/controllers/authController.js @@ -1,7 +1,6 @@ import { registrationBodyValidation, loginValidation, - editUserParamValidation, editUserBodyValidation, recoveryValidation, recoveryTokenValidation, @@ -186,14 +185,8 @@ class AuthController { */ editUser = asyncHandler( async (req, res, next) => { - await editUserParamValidation.validateAsync(req.params); await editUserBodyValidation.validateAsync(req.body); - // TODO is this neccessary any longer? Verify ownership middleware should handle this - if (req.params.userId !== req.user._id.toString()) { - throw createAuthError(this.stringService.unauthorized); - } - // Change Password check if (req.body.password && req.body.newPassword) { // Get token from headers @@ -216,7 +209,7 @@ class AuthController { req.body.password = req.body.newPassword; } - const updatedUser = await this.db.updateUser(req, res); + const updatedUser = await this.db.updateUser({ userId: req?.user?._id, user: req.body, file: req.file }); res.success({ msg: this.stringService.authUpdateUser, data: updatedUser, @@ -343,20 +336,31 @@ class AuthController { */ deleteUser = asyncHandler( async (req, res, next) => { - const token = getTokenFromHeaders(req.headers); - const decodedToken = jwt.decode(token); - const { email } = decodedToken; - - // Check if the user exists - const user = await this.db.getUserByEmail(email); + const email = req?.user?.email; + if (!email) { + throw new Error("No email in request"); + } // 1. Find all the monitors associated with the team ID if superadmin + const teamId = req?.user?.teamId; + const userId = req?.user?._id; + + if (!teamId) { + throw new Error("No team ID in request"); + } + + if (!userId) { + throw new Error("No user ID in request"); + } + + const roles = req.user.role; + const result = await this.db.getMonitorsByTeamId({ - teamId: user.teamId.toString(), + teamId: teamId, }); - if (user.role.includes("superadmin")) { - //2. Remove all jobs, delete checks and alerts + if (roles.includes("superadmin")) { + // 2. Remove all jobs, delete checks and alerts result?.monitors.length > 0 && (await Promise.all( result.monitors.map(async (monitor) => { @@ -365,7 +369,7 @@ class AuthController { )); } // 6. Delete the user by id - await this.db.deleteUser(user._id); + await this.db.deleteUser(userId); return res.success({ msg: this.stringService.authDeleteUser, diff --git a/server/db/mongo/modules/userModule.js b/server/db/mongo/modules/userModule.js index ffac2e4c0..cd609bb5d 100755 --- a/server/db/mongo/modules/userModule.js +++ b/server/db/mongo/modules/userModule.js @@ -92,26 +92,26 @@ const getUserByEmail = async (email) => { * @throws {Error} */ -const updateUser = async (req, res, parseBoolean = ParseBoolean, generateAvatarImage = GenerateAvatarImage) => { - const candidateUserId = req.params.userId; - try { - const candidateUser = { ...req.body }; - // ****************************************** - // Handle profile image - // ****************************************** +const updateUser = async ({ userId, user, file }) => { + if (!userId) { + throw new Error("No user in request"); + } - if (parseBoolean(candidateUser.deleteProfileImage) === true) { + try { + const candidateUser = { ...user }; + + if (ParseBoolean(candidateUser.deleteProfileImage) === true) { candidateUser.profileImage = null; candidateUser.avatarImage = null; - } else if (req.file) { + } else if (file) { // 1. Save the full size image candidateUser.profileImage = { - data: req.file.buffer, - contentType: req.file.mimetype, + data: file.buffer, + contentType: file.mimetype, }; // 2. Get the avatar sized image - const avatar = await generateAvatarImage(req.file); + const avatar = await GenerateAvatarImage(file); candidateUser.avatarImage = avatar; } @@ -120,7 +120,7 @@ const updateUser = async (req, res, parseBoolean = ParseBoolean, generateAvatarI // ****************************************** const updatedUser = await UserModel.findByIdAndUpdate( - candidateUserId, + userId, candidateUser, { new: true } // Returns updated user instead of pre-update user ) diff --git a/server/routes/authRoute.js b/server/routes/authRoute.js index 127456c02..6d8af52f8 100755 --- a/server/routes/authRoute.js +++ b/server/routes/authRoute.js @@ -23,10 +23,11 @@ class AuthRoutes { this.router.post("/recovery/reset/", this.authController.resetPassword); this.router.get("/users/superadmin", this.authController.checkSuperadminExists); + this.router.get("/users", verifyJWT, isAllowed(["admin", "superadmin"]), this.authController.getAllUsers); - this.router.put("/user/:userId", verifyJWT, upload.single("profileImage"), this.authController.editUser); - this.router.delete("/user/:userId", verifyJWT, verifyOwnership(User, "userId"), this.authController.deleteUser); + this.router.put("/user", verifyJWT, upload.single("profileImage"), this.authController.editUser); + this.router.delete("/user", verifyJWT, this.authController.deleteUser); } getRouter() { diff --git a/server/validation/joi.js b/server/validation/joi.js index 030fa8605..ec2274596 100755 --- a/server/validation/joi.js +++ b/server/validation/joi.js @@ -56,10 +56,6 @@ const registrationBodyValidation = joi.object({ inviteToken: joi.string().allow("").required(), }); -const editUserParamValidation = joi.object({ - userId: joi.string().required(), -}); - const editUserBodyValidation = joi.object({ firstName: nameValidation.required(), lastName: nameValidation.required(), @@ -644,7 +640,6 @@ export { editMonitorBodyValidation, pauseMonitorParamValidation, getMonitorURLByQueryValidation, - editUserParamValidation, editUserBodyValidation, createAlertParamValidation, createAlertBodyValidation,