From 8578304ca40a33d724a3e7088f2490a67645e922 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Thu, 10 Oct 2024 08:59:44 +0800 Subject: [PATCH] refactor validation error and general error handling to reduce code duplicatoin --- Server/controllers/authController.js | 587 +++++++++--------- Server/controllers/checkController.js | 61 +- Server/controllers/controllerUtils.js | 19 + Server/controllers/inviteController.js | 135 ++-- .../maintenanceWindowController.js | 71 +-- Server/controllers/monitorController.js | 122 +--- Server/controllers/queueController.js | 20 +- Server/controllers/settingsController.js | 15 +- Server/middleware/verifyJWT.js | 16 +- 9 files changed, 446 insertions(+), 600 deletions(-) create mode 100644 Server/controllers/controllerUtils.js diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index f3ad6fba4..84b4346c3 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -1,19 +1,20 @@ const { - registrationBodyValidation, - loginValidation, - editUserParamValidation, - editUserBodyValidation, - recoveryValidation, - recoveryTokenValidation, - newPasswordValidation, + registrationBodyValidation, + loginValidation, + editUserParamValidation, + editUserBodyValidation, + recoveryValidation, + recoveryTokenValidation, + newPasswordValidation, } = require("../validation/joi"); const logger = require("../utils/logger"); require("dotenv").config(); -const {errorMessages, successMessages} = require("../utils/messages"); +const { errorMessages, successMessages } = require("../utils/messages"); const jwt = require("jsonwebtoken"); const SERVICE_NAME = "AuthController"; -const {getTokenFromHeaders} = require("../utils/utils"); +const { getTokenFromHeaders } = require("../utils/utils"); const crypto = require("crypto"); +const { handleValidationError, handleError } = require("./controllerUtils"); /** * Creates and returns JWT token with an arbitrary payload @@ -24,14 +25,12 @@ const crypto = require("crypto"); * @throws {Error} */ const issueToken = (payload, appSettings) => { - try { - const tokenTTL = appSettings.jwtTTL ? appSettings.jwtTTL : "2h"; - return jwt.sign(payload, appSettings.jwtSecret, {expiresIn: tokenTTL}); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "issueToken") : null; - throw error; - } + try { + const tokenTTL = appSettings.jwtTTL ? appSettings.jwtTTL : "2h"; + return jwt.sign(payload, appSettings.jwtSecret, { expiresIn: tokenTTL }); + } catch (error) { + throw handleError(error, SERVICE_NAME, "issueToken"); + } }; /** @@ -47,56 +46,61 @@ const issueToken = (payload, appSettings) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const registerUser = async (req, res, next) => { - // joi validation - try { - await registrationBodyValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; + // joi validation + try { + await registrationBodyValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } + // Create a new user + try { + const { inviteToken } = req.body; + // If superAdmin exists, a token should be attached to all further register requests + const superAdminExists = await req.db.checkSuperadmin(req, res); + if (superAdminExists) { + await req.db.getInviteTokenAndDelete(inviteToken); + } else { + // This is the first account, create JWT secret to use if one is not supplied by env + const jwtSecret = crypto.randomBytes(64).toString("hex"); + await req.db.updateAppSettings({ jwtSecret }); } - // Create a new user - try { - const {inviteToken} = req.body; - // If superAdmin exists, a token should be attached to all further register requests - const superAdminExists = await req.db.checkSuperadmin(req, res); - if (superAdminExists) { - await req.db.getInviteTokenAndDelete(inviteToken); - } else { - // This is the first account, create JWT secret to use if one is not supplied by env - const jwtSecret = crypto.randomBytes(64).toString("hex"); - await req.db.updateAppSettings({jwtSecret}); - } - const newUser = await req.db.insertUser({...req.body}, req.file); - logger.info(successMessages.AUTH_CREATE_USER, { - service: SERVICE_NAME, userId: newUser._id, + const newUser = await req.db.insertUser({ ...req.body }, req.file); + logger.info(successMessages.AUTH_CREATE_USER, { + service: SERVICE_NAME, + userId: newUser._id, + }); + + const userForToken = { ...newUser._doc }; + delete userForToken.profileImage; + delete userForToken.avatarImage; + + const appSettings = await req.settingsService.getSettings(); + const token = issueToken(userForToken, appSettings); + req.emailService + .buildAndSendEmail( + "welcomeEmailTemplate", + { name: newUser.firstName }, + newUser.email, + "Welcome to Uptime Monitor" + ) + .catch((error) => { + logger.error("Error sending welcome email", { + service: SERVICE_NAME, + error: error.message, }); + }); - const userForToken = {...newUser._doc}; - delete userForToken.profileImage; - delete userForToken.avatarImage; - - const appSettings = await req.settingsService.getSettings(); - const token = issueToken(userForToken, appSettings); - req.emailService - .buildAndSendEmail("welcomeEmailTemplate", {name: newUser.firstName}, newUser.email, "Welcome to Uptime Monitor") - .catch((error) => { - logger.error("Error sending welcome email", { - service: SERVICE_NAME, error: error.message, - }); - }); - - return res.status(200).json({ - success: true, msg: successMessages.AUTH_CREATE_USER, data: {user: newUser, token: token}, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "registerController") : null; - next(error); - } + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_CREATE_USER, + data: { user: newUser, token: token }, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "registerController")); + } }; /** @@ -112,47 +116,44 @@ const registerUser = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422) or the password is incorrect. */ const loginUser = async (req, res, next) => { - try { - await loginValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; + try { + await loginValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } + try { + const { email, password } = req.body; + // Check if user exists + const user = await req.db.getUserByEmail(email); + + // Compare password + const match = await user.comparePassword(password); + if (match !== true) { + next(new Error(errorMessages.AUTH_INCORRECT_PASSWORD)); + return; } - try { - const {email, password} = req.body; - // Check if user exists - const user = await req.db.getUserByEmail(email); - // Compare password - const match = await user.comparePassword(password); - if (match !== true) { - next(new Error(errorMessages.AUTH_INCORRECT_PASSWORD)); - return; - } + // Remove password from user object. Should this be abstracted to DB layer? + const userWithoutPassword = { ...user._doc }; + delete userWithoutPassword.password; + delete userWithoutPassword.avatarImage; - // Remove password from user object. Should this be abstracted to DB layer? - const userWithoutPassword = {...user._doc}; - delete userWithoutPassword.password; - delete userWithoutPassword.avatarImage; + // Happy path, return token + const appSettings = req.settingsService.getSettings(); + const token = issueToken(userWithoutPassword, appSettings); + // reset avatar image + userWithoutPassword.avatarImage = user.avatarImage; - // Happy path, return token - const appSettings = req.settingsService.getSettings(); - const token = issueToken(userWithoutPassword, appSettings); - // reset avatar image - userWithoutPassword.avatarImage = user.avatarImage; - - return res.status(200).json({ - success: true, msg: successMessages.AUTH_LOGIN_USER, data: {user: userWithoutPassword, token: token}, - }); - } catch (error) { - error.status = 500; - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "loginController") : null; - next(error); - } + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_LOGIN_USER, + data: { user: userWithoutPassword, token: token }, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "loginController")); + } }; /** @@ -170,60 +171,58 @@ const loginUser = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422), the user is unauthorized (401), or the password is incorrect (403). */ const editUser = async (req, res, next) => { - try { - await editUserParamValidation.validateAsync(req.params); - await editUserBodyValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; + try { + await editUserParamValidation.validateAsync(req.params); + await editUserBodyValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } + + // TODO is this neccessary any longer? Verify ownership middleware should handle this + if (req.params.userId !== req.user._id.toString()) { + const error = new Error(errorMessages.AUTH_UNAUTHORIZED); + error.status = 401; + error.service = SERVICE_NAME; + next(error); + return; + } + + try { + // Change Password check + if (req.body.password && req.body.newPassword) { + // Get token from headers + const token = getTokenFromHeaders(req.headers); + // Get email from token + const { jwtSecret } = req.settingsService.getSettings(); + const { email } = jwt.verify(token, jwtSecret); + // Add user email to body for DB operation + req.body.email = email; + // Get user + const user = await req.db.getUserByEmail(email); + // Compare passwords + const match = await user.comparePassword(req.body.password); + // If not a match, throw a 403 + if (!match) { + const error = new Error(errorMessages.AUTH_INCORRECT_PASSWORD); + error.status = 403; next(error); return; + } + // If a match, update the password + req.body.password = req.body.newPassword; } - // TODO is this neccessary any longer? Verify ownership middleware should handle this - if (req.params.userId !== req.user._id.toString()) { - const error = new Error(errorMessages.AUTH_UNAUTHORIZED); - error.status = 401; - error.service = SERVICE_NAME; - next(error); - return; - } - - try { - // Change Password check - if (req.body.password && req.body.newPassword) { - // Get token from headers - const token = getTokenFromHeaders(req.headers); - // Get email from token - const {jwtSecret} = req.settingsService.getSettings(); - const {email} = jwt.verify(token, jwtSecret); - // Add user email to body for DB operation - req.body.email = email; - // Get user - const user = await req.db.getUserByEmail(email); - // Compare passwords - const match = await user.comparePassword(req.body.password); - // If not a match, throw a 403 - if (!match) { - const error = new Error(errorMessages.AUTH_INCORRECT_PASSWORD); - error.status = 403; - next(error) - return; - } - // If a match, update the password - req.body.password = req.body.newPassword; - } - - const updatedUser = await req.db.updateUser(req, res); - return res.status(200).json({ - success: true, msg: successMessages.AUTH_UPDATE_USER, data: updatedUser, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "userEditController") : null; - next(error); - } + const updatedUser = await req.db.updateUser(req, res); + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_UPDATE_USER, + data: updatedUser, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "userEditController")); + } }; /** @@ -236,16 +235,16 @@ const editUser = async (req, res, next) => { * @throws {Error} If there is an error during the process. */ const checkSuperAdminExists = async (req, res, next) => { - try { - const superAdminExists = await req.db.checkSuperadmin(req, res); - return res.status(200).json({ - success: true, msg: successMessages.AUTH_ADMIN_EXISTS, data: superAdminExists, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "checkSuperadminController") : null; - next(error); - } + try { + const superAdminExists = await req.db.checkSuperadmin(req, res); + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_ADMIN_EXISTS, + data: superAdminExists, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "checkSuperadminController")); + } }; /** @@ -260,41 +259,44 @@ const checkSuperAdminExists = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const requestRecovery = async (req, res, next) => { - try { - await recoveryValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; - } - - try { - const {email} = req.body; - const user = await req.db.getUserByEmail(email); - if (user) { - const recoveryToken = await req.db.requestRecoveryToken(req, res); - const name = user.firstName; - const email = req.body.email; - const {clientHost} = req.settingsService.getSettings(); - const url = `${clientHost}/set-new-password/${recoveryToken.token}`; - - const msgId = await req.emailService.buildAndSendEmail("passwordResetTemplate", { - name, - email, - url - }, email, "Bluewave Uptime Password Reset"); - - return res.status(200).json({ - success: true, msg: successMessages.AUTH_CREATE_RECOVERY_TOKEN, data: msgId, - }); - } - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "recoveryRequestController") : null; - next(error); + try { + await recoveryValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } + + try { + const { email } = req.body; + const user = await req.db.getUserByEmail(email); + if (user) { + const recoveryToken = await req.db.requestRecoveryToken(req, res); + const name = user.firstName; + const email = req.body.email; + const { clientHost } = req.settingsService.getSettings(); + const url = `${clientHost}/set-new-password/${recoveryToken.token}`; + + const msgId = await req.emailService.buildAndSendEmail( + "passwordResetTemplate", + { + name, + email, + url, + }, + email, + "Bluewave Uptime Password Reset" + ); + + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_CREATE_RECOVERY_TOKEN, + data: msgId, + }); } + } catch (error) { + next(handleError(error, SERVICE_NAME, "recoveryRequestController")); + } }; /** @@ -309,26 +311,23 @@ const requestRecovery = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const validateRecovery = async (req, res, next) => { - try { - await recoveryTokenValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; - } + try { + await recoveryTokenValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } - try { - await req.db.validateRecoveryToken(req, res); - return res.status(200).json({ - success: true, msg: successMessages.AUTH_VERIFY_RECOVERY_TOKEN, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "validateRecoveryTokenController") : null; - next(error); - } + try { + await req.db.validateRecoveryToken(req, res); + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_VERIFY_RECOVERY_TOKEN, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "validateRecoveryTokenController")); + } }; /** @@ -344,28 +343,26 @@ const validateRecovery = async (req, res, next) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const resetPassword = async (req, res, next) => { - try { - await newPasswordValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; - } - try { - const user = await req.db.resetPassword(req, res); + try { + await newPasswordValidation.validateAsync(req.body); + } catch (error) { + const validationError = handleValidationError(error, SERVICE_NAME); + next(validationError); + return; + } + try { + const user = await req.db.resetPassword(req, res); - const appSettings = await req.settingsService.getSettings(); - const token = issueToken(user._doc, appSettings); - res.status(200).json({ - success: true, msg: successMessages.AUTH_RESET_PASSWORD, data: {user, token}, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "resetPasswordController") : null; - next(error); - } + const appSettings = await req.settingsService.getSettings(); + const token = issueToken(user._doc, appSettings); + res.status(200).json({ + success: true, + msg: successMessages.AUTH_RESET_PASSWORD, + data: { user, token }, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "resetPasswordController")); + } }; /** @@ -378,73 +375,73 @@ const resetPassword = async (req, res, next) => { * @throws {Error} If user validation fails or user is not found in the database. */ const deleteUser = async (req, res, next) => { - try { - const token = getTokenFromHeaders(req.headers); - const decodedToken = jwt.decode(token); - const {email} = decodedToken; + try { + const token = getTokenFromHeaders(req.headers); + const decodedToken = jwt.decode(token); + const { email } = decodedToken; - // Check if the user exists - const user = await req.db.getUserByEmail(email); - if (!user) { - next(new Error(errorMessages.DB_USER_NOT_FOUND)); - return; - } - - // 1. Find all the monitors associated with the team ID if superadmin - - const result = await req.db.getMonitorsByTeamId({ - params: {teamId: user.teamId}, - }); - if (user.role.includes("superadmin")) { - //2. Remove all jobs, delete checks and alerts - result?.monitors.length > 0 && (await Promise.all(result.monitors.map(async (monitor) => { - await req.jobQueue.deleteJob(monitor); - await req.db.deleteChecks(monitor._id); - await req.db.deletePageSpeedChecksByMonitorId(monitor._id); - await req.db.deleteNotificationsByMonitorId(monitor._id); - }))); - - // 3. Delete team - await req.db.deleteTeam(user.teamId); - // 4. Delete all other team members - await req.db.deleteAllOtherUsers(); - // 5. Delete each monitor - await req.db.deleteMonitorsByUserId(user._id); - } - // 6. Delete the user by id - await req.db.deleteUser(user._id); - - return res.status(200).json({ - success: true, msg: successMessages.AUTH_DELETE_USER, - }); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteUserController") : null; - next(error); + // Check if the user exists + const user = await req.db.getUserByEmail(email); + if (!user) { + next(new Error(errorMessages.DB_USER_NOT_FOUND)); + return; } + + // 1. Find all the monitors associated with the team ID if superadmin + + const result = await req.db.getMonitorsByTeamId({ + params: { teamId: user.teamId }, + }); + if (user.role.includes("superadmin")) { + //2. Remove all jobs, delete checks and alerts + result?.monitors.length > 0 && + (await Promise.all( + result.monitors.map(async (monitor) => { + await req.jobQueue.deleteJob(monitor); + await req.db.deleteChecks(monitor._id); + await req.db.deletePageSpeedChecksByMonitorId(monitor._id); + await req.db.deleteNotificationsByMonitorId(monitor._id); + }) + )); + + // 3. Delete team + await req.db.deleteTeam(user.teamId); + // 4. Delete all other team members + await req.db.deleteAllOtherUsers(); + // 5. Delete each monitor + await req.db.deleteMonitorsByUserId(user._id); + } + // 6. Delete the user by id + await req.db.deleteUser(user._id); + + return res.status(200).json({ + success: true, + msg: successMessages.AUTH_DELETE_USER, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "deleteUserController")); + } }; const getAllUsers = async (req, res) => { - try { - const allUsers = await req.db.getAllUsers(req, res); - res - .status(200) - .json({success: true, msg: "Got all users", data: allUsers}); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getAllUsersController") : null; - next(error); - } + try { + const allUsers = await req.db.getAllUsers(req, res); + res + .status(200) + .json({ success: true, msg: "Got all users", data: allUsers }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "getAllUsersController")); + } }; module.exports = { - registerUser, - loginUser, - editUser, - checkSuperadminExists: checkSuperAdminExists, - requestRecovery, - validateRecovery, - resetPassword, - deleteUser, - getAllUsers, + registerUser, + loginUser, + editUser, + checkSuperadminExists: checkSuperAdminExists, + requestRecovery, + validateRecovery, + resetPassword, + deleteUser, + getAllUsers, }; diff --git a/Server/controllers/checkController.js b/Server/controllers/checkController.js index 17507e0b2..b0e98ed38 100644 --- a/Server/controllers/checkController.js +++ b/Server/controllers/checkController.js @@ -13,17 +13,14 @@ const { successMessages } = require("../utils/messages"); const jwt = require("jsonwebtoken"); const { getTokenFromHeaders } = require("../utils/utils"); const SERVICE_NAME = "checkController"; +const { handleValidationError, handleError } = require("./controllerUtils"); const createCheck = async (req, res, next) => { try { await createCheckParamValidation.validateAsync(req.params); await createCheckBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -34,9 +31,7 @@ const createCheck = async (req, res, next) => { .status(200) .json({ success: true, msg: successMessages.CHECK_CREATE, data: check }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "createCheck") : null; - next(error); + next(handleError(error, SERVICE_NAME, "createCheck")); } }; @@ -45,11 +40,7 @@ const getChecks = async (req, res, next) => { await getChecksParamValidation.validateAsync(req.params); await getChecksQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -62,9 +53,7 @@ const getChecks = async (req, res, next) => { data: { checksCount, checks }, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getChecks") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getChecks")); } }; @@ -73,11 +62,7 @@ const getTeamChecks = async (req, res, next) => { await getTeamChecksParamValidation.validateAsync(req.params); await getTeamChecksQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } try { @@ -88,9 +73,7 @@ const getTeamChecks = async (req, res, next) => { data: checkData, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getTeamChecks") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getTeamChecks")); } }; @@ -98,11 +81,7 @@ const deleteChecks = async (req, res, next) => { try { await deleteChecksParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -114,9 +93,7 @@ const deleteChecks = async (req, res, next) => { data: { deletedCount }, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteChecks") : null; - next(error); + next(handleError(error, SERVICE_NAME, "deleteChecks")); } }; @@ -124,10 +101,7 @@ const deleteChecksByTeamId = async (req, res, next) => { try { await deleteChecksByTeamIdParamValidation.validateAsync(req.params); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteChecksByTeam") : null; - error.status = 422; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -139,9 +113,7 @@ const deleteChecksByTeamId = async (req, res, next) => { data: { deletedCount }, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteChecksByTeamId") : null; - next(error); + next(handleError(error, SERVICE_NAME, "deleteChecksByTeamId")); } }; @@ -151,12 +123,7 @@ const updateChecksTTL = async (req, res, next) => { try { await updateChecksTTLBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "updateChecksTTL") : null; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -172,9 +139,7 @@ const updateChecksTTL = async (req, res, next) => { msg: successMessages.CHECK_UPDATE_TTL, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "updateTTL") : null; - next(error); + next(handleError(error, SERVICE_NAME, "updateTTL")); } }; diff --git a/Server/controllers/controllerUtils.js b/Server/controllers/controllerUtils.js new file mode 100644 index 000000000..1b3994f2f --- /dev/null +++ b/Server/controllers/controllerUtils.js @@ -0,0 +1,19 @@ +const handleValidationError = (error, serviceName) => { + error.status = 422; + error.service = serviceName; + error.message = + error.details?.[0]?.message || error.message || "Validation Error"; + return error; +}; + +const handleError = (error, serviceName, method, code = 500) => { + error.code === undefined ? (error.code = code) : null; + error.service === undefined ? (error.service = serviceName) : null; + error.method === undefined ? (error.method = method) : null; + return error; +}; + +module.exports = { + handleValidationError, + handleError, +}; diff --git a/Server/controllers/inviteController.js b/Server/controllers/inviteController.js index 9863f9666..56d6b08f6 100644 --- a/Server/controllers/inviteController.js +++ b/Server/controllers/inviteController.js @@ -1,22 +1,23 @@ const { - inviteRoleValidation, - inviteBodyValidation, - inviteVerificationBodyValidation, + inviteRoleValidation, + inviteBodyValidation, + inviteVerificationBodyValidation, } = require("../validation/joi"); const logger = require("../utils/logger"); require("dotenv").config(); const jwt = require("jsonwebtoken"); +const { handleError, handleValidationError } = require("./controllerUtils"); const SERVICE_NAME = "inviteController"; const getTokenFromHeaders = (headers) => { - const authorizationHeader = headers.authorization; - if (!authorizationHeader) throw new Error("No auth headers"); + const authorizationHeader = headers.authorization; + if (!authorizationHeader) throw new Error("No auth headers"); - const parts = authorizationHeader.split(" "); - if (parts.length !== 2 || parts[0] !== "Bearer") - throw new Error("Invalid auth headers"); + const parts = authorizationHeader.split(" "); + if (parts.length !== 2 || parts[0] !== "Bearer") + throw new Error("Invalid auth headers"); - return parts[1]; + return parts[1]; }; /** @@ -33,79 +34,65 @@ const getTokenFromHeaders = (headers) => { * @throws {Error} If there is an error during the process, especially if there is a validation error (422). */ const issueInvitation = async (req, res, next) => { + try { + // Only admins can invite + const token = getTokenFromHeaders(req.headers); + const { role, firstname, teamId } = jwt.decode(token); + req.body.teamId = teamId; try { - // Only admins can invite - const token = getTokenFromHeaders(req.headers); - const {role, firstname, teamId} = jwt.decode(token); - req.body.teamId = teamId; - try { - await inviteRoleValidation.validateAsync({roles: role}); - await inviteBodyValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; - } - - const inviteToken = await req.db.requestInviteToken({...req.body}); - const {clientHost} = req.settingsService.getSettings(); - req.emailService - .buildAndSendEmail( - "employeeActivationTemplate", - { - name: firstname, - link: `${clientHost}/register/${inviteToken.token}`, - }, - req.body.email, - "Welcome to Uptime Monitor" - ) - .catch((error) => { - logger.error("Error sending invite email", { - service: SERVICE_NAME, - error: error.message, - }); - }); - - return res - .status(200) - .json({success: true, msg: "Invite sent", data: inviteToken}); + await inviteRoleValidation.validateAsync({ roles: role }); + await inviteBodyValidation.validateAsync(req.body); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "inviteController") : null; - next(error); + next(handleValidationError(error, SERVICE_NAME)); + return; } + + const inviteToken = await req.db.requestInviteToken({ ...req.body }); + const { clientHost } = req.settingsService.getSettings(); + req.emailService + .buildAndSendEmail( + "employeeActivationTemplate", + { + name: firstname, + link: `${clientHost}/register/${inviteToken.token}`, + }, + req.body.email, + "Welcome to Uptime Monitor" + ) + .catch((error) => { + logger.error("Error sending invite email", { + service: SERVICE_NAME, + error: error.message, + }); + }); + + return res + .status(200) + .json({ success: true, msg: "Invite sent", data: inviteToken }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "inviteController")); + } }; const inviteVerifyController = async (req, res, next) => { - try { - await inviteVerificationBodyValidation.validateAsync(req.body); - } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); - return; - } + try { + await inviteVerificationBodyValidation.validateAsync(req.body); + } catch (error) { + next(handleValidationError(error, SERVICE_NAME)); + return; + } - try { - const invite = await req.db.getInviteToken(req.body.token); - res - .status(200) - .json({status: "success", msg: "Invite verified", data: invite}); - } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "inviteVerifyController") - : null; - next(error); - } + try { + const invite = await req.db.getInviteToken(req.body.token); + res + .status(200) + .json({ status: "success", msg: "Invite verified", data: invite }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "inviteVerifyController")); + } }; module.exports = { - inviteController: issueInvitation, - inviteVerifyController, + inviteController: issueInvitation, + inviteVerifyController, }; diff --git a/Server/controllers/maintenanceWindowController.js b/Server/controllers/maintenanceWindowController.js index 7dc130b7c..c6c34b7eb 100644 --- a/Server/controllers/maintenanceWindowController.js +++ b/Server/controllers/maintenanceWindowController.js @@ -10,17 +10,14 @@ const { const jwt = require("jsonwebtoken"); const { getTokenFromHeaders } = require("../utils/utils"); const { successMessages } = require("../utils/messages"); +const { handleValidationError, handleError } = require("./controllerUtils"); const SERVICE_NAME = "maintenanceWindowController"; const createMaintenanceWindows = async (req, res, next) => { try { await createMaintenanceWindowBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } try { @@ -45,11 +42,7 @@ const createMaintenanceWindows = async (req, res, next) => { msg: successMessages.MAINTENANCE_WINDOW_CREATE, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "createMaintenanceWindow") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "createMaintenanceWindow")); } }; @@ -57,11 +50,7 @@ const getMaintenanceWindowById = async (req, res, next) => { try { await getMaintenanceWindowByIdParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } try { @@ -74,11 +63,7 @@ const getMaintenanceWindowById = async (req, res, next) => { data: maintenanceWindow, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "getMaintenanceWindowById") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMaintenanceWindowById")); } }; @@ -86,11 +71,7 @@ const getMaintenanceWindowsByTeamId = async (req, res, next) => { try { await getMaintenanceWindowsByTeamIdQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -109,11 +90,7 @@ const getMaintenanceWindowsByTeamId = async (req, res, next) => { data: maintenanceWindows, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "getMaintenanceWindowsByUserId") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMaintenanceWindowsByUserId")); } }; @@ -123,11 +100,7 @@ const getMaintenanceWindowsByMonitorId = async (req, res, next) => { req.params ); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -142,11 +115,7 @@ const getMaintenanceWindowsByMonitorId = async (req, res, next) => { data: maintenanceWindows, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "getMaintenanceWindowsByMonitorId") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMaintenanceWindowsByMonitorId")); } }; @@ -154,11 +123,7 @@ const deleteMaintenanceWindow = async (req, res, next) => { try { await deleteMaintenanceWindowByIdParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } try { @@ -168,10 +133,7 @@ const deleteMaintenanceWindow = async (req, res, next) => { msg: successMessages.MAINTENANCE_WINDOW_DELETE, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "deleteMaintenanceWindow") - : null; + next(handleError(error, SERVICE_NAME, "deleteMaintenanceWindow")); } }; @@ -180,11 +142,7 @@ const editMaintenanceWindow = async (req, res, next) => { await editMaintenanceWindowByIdParamValidation.validateAsync(req.params); await editMaintenanceByIdWindowBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } try { @@ -198,10 +156,7 @@ const editMaintenanceWindow = async (req, res, next) => { data: editedMaintenanceWindow, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "editMaintenanceWindow") - : null; + next(handleError(error, SERVICE_NAME, "editMaintenanceWindow")); } }; diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 3f77a412e..b7e27451b 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -19,6 +19,7 @@ const { errorMessages, successMessages } = require("../utils/messages"); const jwt = require("jsonwebtoken"); const { getTokenFromHeaders } = require("../utils/utils"); const logger = require("../utils/logger"); +const { handleError, handleValidationError } = require("./controllerUtils"); /** * Returns all monitors @@ -38,9 +39,7 @@ const getAllMonitors = async (req, res, next) => { data: monitors, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getAllMonitors") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getAllMonitors")); } }; @@ -58,10 +57,7 @@ const getMonitorStatsById = async (req, res, next) => { await getMonitorStatsByIdParamValidation.validateAsync(req.params); await getMonitorStatsByIdQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -73,9 +69,7 @@ const getMonitorStatsById = async (req, res, next) => { data: monitorStats, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getMonitorStatsById") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMonitorStatsById")); } }; @@ -83,10 +77,7 @@ const getMonitorCertificate = async (req, res, next) => { try { await getCertificateParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); } try { @@ -110,11 +101,7 @@ const getMonitorCertificate = async (req, res, next) => { }); } } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "getMonitorCertificate") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMonitorCertificate")); } }; @@ -134,10 +121,7 @@ const getMonitorById = async (req, res, next) => { await getMonitorByIdParamValidation.validateAsync(req.params); await getMonitorByIdQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -154,9 +138,7 @@ const getMonitorById = async (req, res, next) => { data: monitor, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getMonitorById") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMonitorById")); } }; @@ -179,14 +161,8 @@ const getMonitorsAndSummaryByTeamId = async (req, res, next) => { req.params ); await getMonitorsAndSummaryByTeamIdQueryValidation.validateAsync(req.query); - //validation } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.method === undefined? error.method = "getMonitorsAndSummaryByTeamId": null; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -203,11 +179,7 @@ const getMonitorsAndSummaryByTeamId = async (req, res, next) => { data: monitorsSummary, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined - ? (error.method = "getMonitorsAndSummaryByTeamId") - : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMonitorsAndSummaryByTeamId")); } }; @@ -228,11 +200,7 @@ const getMonitorsByTeamId = async (req, res, next) => { await getMonitorsByTeamIdValidation.validateAsync(req.params); await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -245,8 +213,7 @@ const getMonitorsByTeamId = async (req, res, next) => { data: monitors, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getMonitorsByTeamId") : null; + next(handleError(error, SERVICE_NAME, "getMonitorsByTeamId")); next(error); } }; @@ -266,12 +233,7 @@ const createMonitor = async (req, res, next) => { try { await createMonitorBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -281,10 +243,10 @@ const createMonitor = async (req, res, next) => { if (notifications && notifications.length !== 0) { monitor.notifications = await Promise.all( - notifications.map(async (notification) => { - notification.monitorId = monitor._id; - await req.db.createNotification(notification); - }) + notifications.map(async (notification) => { + notification.monitorId = monitor._id; + await req.db.createNotification(notification); + }) ); await monitor.save(); } @@ -296,9 +258,7 @@ const createMonitor = async (req, res, next) => { data: monitor, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "createMonitor") : null; - next(error); + next(handleError(error, SERVICE_NAME, "createMonitor")); } }; @@ -317,11 +277,7 @@ const deleteMonitor = async (req, res, next) => { try { await getMonitorByIdParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -347,9 +303,7 @@ const deleteMonitor = async (req, res, next) => { .status(200) .json({ success: true, msg: successMessages.MONITOR_DELETE }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteMonitor") : null; - next(error); + next(handleError(error, SERVICE_NAME, "deleteMonitor")); } }; @@ -382,9 +336,7 @@ const deleteAllMonitors = async (req, res, next) => { .status(200) .json({ success: true, msg: `Deleted ${deletedCount} monitors` }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "deleteAllMonitors") : null; - next(error); + next(handleError(error, SERVICE_NAME, "deleteAllMonitors")); } }; @@ -406,11 +358,7 @@ const editMonitor = async (req, res, next) => { await getMonitorByIdParamValidation.validateAsync(req.params); await editMonitorBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -444,9 +392,7 @@ const editMonitor = async (req, res, next) => { data: editedMonitor, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "editMonitor") : null; - next(error); + next(handleError(error, SERVICE_NAME, "editMonitor")); } }; @@ -465,11 +411,7 @@ const pauseMonitor = async (req, res, next) => { try { await pauseMonitorParamValidation.validateAsync(req.params); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); } try { @@ -490,9 +432,7 @@ const pauseMonitor = async (req, res, next) => { data: monitor, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "pauseMonitor") : null; - next(error); + next(handleError(error, SERVICE_NAME, "pauseMonitor")); } }; @@ -511,21 +451,19 @@ const addDemoMonitors = async (req, res, next) => { try { const token = getTokenFromHeaders(req.headers); const { jwtSecret } = req.settingsService.getSettings(); - const { _id, teamId } = jwt.verify(token, jwtSecret); const demoMonitors = await req.db.addDemoMonitors(_id, teamId); - await demoMonitors.forEach(async (monitor) => { - await req.jobQueue.addJob(monitor._id, monitor); - }); + await Promise.all( + demoMonitors.map((monitor) => req.jobQueue.addJob(monitor._id, monitor)) + ); + return res.status(200).json({ success: true, message: successMessages.MONITOR_DEMO_ADDED, data: demoMonitors.length, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "addDemoMonitors") : null; - next(error); + next(handleError(error, SERVICE_NAME, "addDemoMonitors")); } }; diff --git a/Server/controllers/queueController.js b/Server/controllers/queueController.js index bbb3304ee..341c4b76b 100644 --- a/Server/controllers/queueController.js +++ b/Server/controllers/queueController.js @@ -1,3 +1,5 @@ +const { handleError } = require("./controllerUtils"); + const SERVICE_NAME = "JobQueueController"; const getMetrics = async (req, res, next) => { @@ -7,9 +9,7 @@ const getMetrics = async (req, res, next) => { .status(200) .json({ success: true, msg: "Metrics retrieved", data: metrics }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getMetrics") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getMetrics")); return; } }; @@ -19,9 +19,7 @@ const getJobs = async (req, res, next) => { const jobs = await req.jobQueue.getJobStats(); return res.status(200).json({ jobs }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getJobs") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getJobs")); return; } }; @@ -31,21 +29,17 @@ const addJob = async (req, res, next) => { await req.jobQueue.addJob(Math.random().toString(36).substring(7)); return res.send("Added job"); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "addJob") : null; - next(error); + next(handleError(error, SERVICE_NAME, "addJob")); return; } }; const obliterateQueue = async (req, res, next) => { try { - const obliterated = await req.jobQueue.obliterate(); + await req.jobQueue.obliterate(); return res.status(200).send("Obliterated queue"); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "obliterateQueue") : null; - next(error); + next(handleError(error, SERVICE_NAME, "obliterateQueue")); return; } }; diff --git a/Server/controllers/settingsController.js b/Server/controllers/settingsController.js index 8c9390ad8..3e4e3c304 100644 --- a/Server/controllers/settingsController.js +++ b/Server/controllers/settingsController.js @@ -1,6 +1,7 @@ const { successMessages } = require("../utils/messages"); const SERVICE_NAME = "SettingsController"; const { updateAppSettingsBodyValidation } = require("../validation/joi"); +const { handleValidationError, handleError } = require("./controllerUtils"); const getAppSettings = async (req, res, next) => { try { @@ -12,9 +13,7 @@ const getAppSettings = async (req, res, next) => { data: settings, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "getAppSettings") : null; - next(error); + next(handleError(error, SERVICE_NAME, "getAppSettings")); } }; @@ -22,11 +21,7 @@ const updateAppSettings = async (req, res, next) => { try { await updateAppSettingsBodyValidation.validateAsync(req.body); } catch (error) { - error.status = 422; - error.service = SERVICE_NAME; - error.message = - error.details?.[0]?.message || error.message || "Validation Error"; - next(error); + next(handleValidationError(error, SERVICE_NAME)); return; } @@ -40,9 +35,7 @@ const updateAppSettings = async (req, res, next) => { data: updatedSettings, }); } catch (error) { - error.service === undefined ? (error.service = SERVICE_NAME) : null; - error.method === undefined ? (error.method = "updateAppSettings") : null; - next(error); + next(handleError(error, SERVICE_NAME, "updateAppSettings")); } }; diff --git a/Server/middleware/verifyJWT.js b/Server/middleware/verifyJWT.js index fa1fc3afa..3bae3318a 100644 --- a/Server/middleware/verifyJWT.js +++ b/Server/middleware/verifyJWT.js @@ -38,16 +38,14 @@ const verifyJWT = (req, res, next) => { const { jwtSecret } = req.settingsService.getSettings(); jwt.verify(parsedToken, jwtSecret, (err, decoded) => { if (err) { - if (err.name === "TokenExpiredError") { - res - .status(401) - .json({ success: false, msg: errorMessages.EXPIRED_AUTH_TOKEN }); - } - return res - .status(401) - .json({ success: false, msg: errorMessages.INVALID_AUTH_TOKEN }); + const errorMessage = + err.name === "TokenExpiredError" + ? errorMessages.EXPIRED_AUTH_TOKEN + : errorMessages.INVALID_AUTH_TOKEN; + return res.status(401).json({ success: false, msg: errorMessage }); } - //Add the user to the request object for use in the route + + // Add the user to the request object for use in the route req.user = decoded; next(); });