diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js index 6fe90477a..0ffa612f3 100644 --- a/Server/controllers/authController.js +++ b/Server/controllers/authController.js @@ -115,8 +115,7 @@ class AuthController { }); }); - return res.status(200).json({ - success: true, + res.success({ msg: successMessages.AUTH_CREATE_USER, data: { user: newUser, token: token, refreshToken: refreshToken }, }); @@ -154,7 +153,9 @@ class AuthController { // Compare password const match = await user.comparePassword(password); if (match !== true) { - next(new Error(errorMessages.AUTH_INCORRECT_PASSWORD)); + const error = new Error(errorMessages.AUTH_INCORRECT_PASSWORD); + error.status = 401; + next(error); return; } @@ -174,12 +175,16 @@ class AuthController { // reset avatar image userWithoutPassword.avatarImage = user.avatarImage; - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.AUTH_LOGIN_USER, - data: { user: userWithoutPassword, token: token, refreshToken: refreshToken }, + data: { + user: userWithoutPassword, + token: token, + refreshToken: refreshToken, + }, }); } catch (error) { + error.status = 401; next(handleError(error, SERVICE_NAME, "loginUser")); } }; @@ -237,8 +242,7 @@ class AuthController { appSettings ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.AUTH_TOKEN_REFRESHED, data: { user: payloadData, token: newAuthToken, refreshToken: refreshToken }, }); @@ -306,8 +310,7 @@ class AuthController { } const updatedUser = await this.db.updateUser(req, res); - return res.status(200).json({ - success: true, + res.success({ msg: successMessages.AUTH_UPDATE_USER, data: updatedUser, }); @@ -328,8 +331,8 @@ class AuthController { checkSuperadminExists = async (req, res, next) => { try { const superAdminExists = await this.db.checkSuperadmin(req, res); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.AUTH_ADMIN_EXISTS, data: superAdminExists, }); @@ -375,8 +378,7 @@ class AuthController { "Checkmate Password Reset" ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.AUTH_CREATE_RECOVERY_TOKEN, data: msgId, }); @@ -406,8 +408,8 @@ class AuthController { try { await this.db.validateRecoveryToken(req, res); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.AUTH_VERIFY_RECOVERY_TOKEN, }); } catch (error) { @@ -439,8 +441,8 @@ class AuthController { const user = await this.db.resetPassword(req, res); const appSettings = await this.settingsService.getSettings(); const token = this.issueToken(user._doc, tokenType.ACCESS_TOKEN, appSettings); - res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.AUTH_RESET_PASSWORD, data: { user, token }, }); @@ -493,8 +495,8 @@ class AuthController { } // 6. Delete the user by id await this.db.deleteUser(user._id); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.AUTH_DELETE_USER, }); } catch (error) { @@ -505,7 +507,11 @@ class AuthController { getAllUsers = async (req, res, next) => { try { const allUsers = await this.db.getAllUsers(req, res); - res.status(200).json({ success: true, msg: "Got all users", data: allUsers }); + + return res.success({ + msg: successMessages.AUTH_GET_ALL_USERS, + data: allUsers, + }); } catch (error) { next(handleError(error, SERVICE_NAME, "getAllUsersController")); } diff --git a/Server/controllers/checkController.js b/Server/controllers/checkController.js index fce245b69..8988df6d8 100644 --- a/Server/controllers/checkController.js +++ b/Server/controllers/checkController.js @@ -34,9 +34,11 @@ class CheckController { try { const checkData = { ...req.body }; const check = await this.db.createCheck(checkData); - return res - .status(200) - .json({ success: true, msg: successMessages.CHECK_CREATE, data: check }); + + return res.success({ + msg: successMessages.CHECK_CREATE, + data: check, + }); } catch (error) { next(handleError(error, SERVICE_NAME, "createCheck")); } @@ -54,8 +56,8 @@ class CheckController { try { const checks = await this.db.getChecks(req); const checksCount = await this.db.getChecksCount(req); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.CHECK_GET, data: { checksCount, checks }, }); @@ -74,8 +76,8 @@ class CheckController { } try { const checkData = await this.db.getTeamChecks(req); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.CHECK_GET, data: checkData, }); @@ -94,8 +96,8 @@ class CheckController { try { const deletedCount = await this.db.deleteChecks(req.params.monitorId); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.CHECK_DELETE, data: { deletedCount }, }); @@ -114,8 +116,8 @@ class CheckController { try { const deletedCount = await this.db.deleteChecksByTeamId(req.params.teamId); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.CHECK_DELETE, data: { deletedCount }, }); @@ -141,8 +143,8 @@ class CheckController { const { teamId } = jwt.verify(token, jwtSecret); const ttl = parseInt(req.body.ttl, 10) * SECONDS_PER_DAY; await this.db.updateChecksTTL(teamId, ttl); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.CHECK_UPDATE_TTL, }); } catch (error) { diff --git a/Server/controllers/controllerUtils.js b/Server/controllers/controllerUtils.js index bee091db8..ec7f1122f 100644 --- a/Server/controllers/controllerUtils.js +++ b/Server/controllers/controllerUtils.js @@ -13,18 +13,14 @@ const handleError = (error, serviceName, method, status = 500) => { }; const fetchMonitorCertificate = async (sslChecker, monitor) => { - try { - const monitorUrl = new URL(monitor.url); - const hostname = monitorUrl.hostname; - const cert = await sslChecker(hostname); - // Throw an error if no cert or if cert.validTo is not present - if (cert?.validTo === null || cert?.validTo === undefined) { - throw new Error("Certificate not found"); - } - return cert; - } catch (error) { - throw error; + const monitorUrl = new URL(monitor.url); + const hostname = monitorUrl.hostname; + const cert = await sslChecker(hostname); + // Throw an error if no cert or if cert.validTo is not present + if (cert?.validTo === null || cert?.validTo === undefined) { + throw new Error("Certificate not found"); } + return cert; }; export { handleValidationError, handleError, fetchMonitorCertificate }; diff --git a/Server/controllers/inviteController.js b/Server/controllers/inviteController.js index d4eedd502..a40f43a32 100644 --- a/Server/controllers/inviteController.js +++ b/Server/controllers/inviteController.js @@ -7,7 +7,7 @@ import logger from "../utils/logger.js"; import jwt from "jsonwebtoken"; import { handleError, handleValidationError } from "./controllerUtils.js"; import { getTokenFromHeaders } from "../utils/utils.js"; - +import { successMessages } from "../utils/messages.js"; const SERVICE_NAME = "inviteController"; class InviteController { @@ -65,9 +65,10 @@ class InviteController { }); }); - return res - .status(200) - .json({ success: true, msg: "Invite sent", data: inviteToken }); + return res.success({ + msg: successMessages.INVITE_ISSUED, + data: inviteToken, + }); } catch (error) { next(handleError(error, SERVICE_NAME, "inviteController")); } @@ -83,7 +84,11 @@ class InviteController { try { const invite = await this.db.getInviteToken(req.body.token); - res.status(200).json({ status: "success", msg: "Invite verified", data: invite }); + + return res.success({ + msg: successMessages.INVITE_VERIFIED, + data: invite, + }); } catch (error) { next(handleError(error, SERVICE_NAME, "inviteVerifyController")); } diff --git a/Server/controllers/maintenanceWindowController.js b/Server/controllers/maintenanceWindowController.js index 72b8dc27b..b301ba94c 100644 --- a/Server/controllers/maintenanceWindowController.js +++ b/Server/controllers/maintenanceWindowController.js @@ -43,8 +43,8 @@ class MaintenanceWindowController { }); }); await Promise.all(dbTransactions); - return res.status(201).json({ - success: true, + + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_CREATE, }); } catch (error) { @@ -61,8 +61,8 @@ class MaintenanceWindowController { } try { const maintenanceWindow = await this.db.getMaintenanceWindowById(req.params.id); - return res.status(200).json({ - success: true, + + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_GET_BY_ID, data: maintenanceWindow, }); @@ -88,8 +88,7 @@ class MaintenanceWindowController { req.query ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_GET_BY_TEAM, data: maintenanceWindows, }); @@ -111,8 +110,7 @@ class MaintenanceWindowController { req.params.monitorId ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_GET_BY_USER, data: maintenanceWindows, }); @@ -130,8 +128,7 @@ class MaintenanceWindowController { } try { await this.db.deleteMaintenanceWindowById(req.params.id); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_DELETE, }); } catch (error) { @@ -152,8 +149,7 @@ class MaintenanceWindowController { req.params.id, req.body ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MAINTENANCE_WINDOW_EDIT, data: editedMaintenanceWindow, }); diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 839f2bb13..097172854 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -42,8 +42,7 @@ class MonitorController { getAllMonitors = async (req, res, next) => { try { const monitors = await this.db.getAllMonitors(); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_GET_ALL, data: monitors, }); @@ -64,8 +63,7 @@ class MonitorController { getAllMonitorsWithUptimeStats = async (req, res, next) => { try { const monitors = await this.db.getAllMonitorsWithUptimeStats(); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_GET_ALL, data: monitors, }); @@ -77,8 +75,7 @@ class MonitorController { getUptimeDetailsById = async (req, res, next) => { try { const monitor = await this.db.getUptimeDetailsById(req); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_GET_BY_ID, data: monitor, }); @@ -107,8 +104,7 @@ class MonitorController { try { const monitorStats = await this.db.getMonitorStatsById(req); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_STATS_BY_ID, data: monitorStats, }); @@ -136,8 +132,7 @@ class MonitorController { } try { const monitor = await this.db.getHardwareDetailsById(req); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_GET_BY_ID, data: monitor, }); @@ -158,8 +153,7 @@ class MonitorController { const monitor = await this.db.getMonitorById(monitorId); const certificate = await fetchMonitorCertificate(sslChecker, monitor); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_CERTIFICATE, data: { certificateDate: new Date(certificate.validTo), @@ -192,8 +186,7 @@ class MonitorController { try { const monitor = await this.db.getMonitorById(req.params.monitorId); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_GET_BY_ID, data: monitor, }); @@ -237,8 +230,7 @@ class MonitorController { await monitor.save(); // Add monitor to job queue this.jobQueue.addJob(monitor._id, monitor); - return res.status(201).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_CREATE, data: monitor, }); @@ -272,11 +264,9 @@ class MonitorController { timeout: 5000, validateStatus: () => true, }); - return res.status(200).json({ - success: true, - code: response.status, - statusText: response.statusText, - msg: `URL resolved successfully`, + return res.success({ + status: response.status, + msg: response.statusText, }); } catch (error) { next(handleError(error, SERVICE_NAME, "checkEndpointResolution")); @@ -319,7 +309,7 @@ class MonitorController { stack: error.stack, }); } - return res.status(200).json({ success: true, msg: successMessages.MONITOR_DELETE }); + return res.success({ msg: successMessages.MONITOR_DELETE }); } catch (error) { next(handleError(error, SERVICE_NAME, "deleteMonitor")); } @@ -359,9 +349,7 @@ class MonitorController { } }) ); - return res - .status(200) - .json({ success: true, msg: `Deleted ${deletedCount} monitors` }); + return res.success({ msg: `Deleted ${deletedCount} monitors` }); } catch (error) { next(handleError(error, SERVICE_NAME, "deleteAllMonitors")); } @@ -412,8 +400,7 @@ class MonitorController { await this.jobQueue.deleteJob(monitorBeforeEdit); // Add the new job back to the queue await this.jobQueue.addJob(editedMonitor._id, editedMonitor); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_EDIT, data: editedMonitor, }); @@ -449,8 +436,7 @@ class MonitorController { monitor.isActive = !monitor.isActive; monitor.status = undefined; monitor.save(); - return res.status(200).json({ - success: true, + return res.ssuccess({ msg: monitor.isActive ? successMessages.MONITOR_RESUME : successMessages.MONITOR_PAUSE, @@ -482,8 +468,7 @@ class MonitorController { demoMonitors.map((monitor) => this.jobQueue.addJob(monitor._id, monitor)) ); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.MONITOR_DEMO_ADDED, data: demoMonitors.length, }); @@ -502,9 +487,8 @@ class MonitorController { try { const monitors = await this.db.getMonitorsByTeamId(req); - return res.status(200).json({ - success: true, - msg: "good", + return res.success({ + msg: successMessages.MONITOR_GET_BY_TEAM_ID, data: monitors, }); } catch (error) { diff --git a/Server/controllers/queueController.js b/Server/controllers/queueController.js index 501074d42..f62b9fdeb 100644 --- a/Server/controllers/queueController.js +++ b/Server/controllers/queueController.js @@ -11,8 +11,7 @@ class JobQueueController { getMetrics = async (req, res, next) => { try { const metrics = await this.jobQueue.getMetrics(); - res.status(200).json({ - success: true, + res.success({ msg: successMessages.QUEUE_GET_METRICS, data: metrics, }); @@ -25,8 +24,7 @@ class JobQueueController { getJobs = async (req, res, next) => { try { const jobs = await this.jobQueue.getJobStats(); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.QUEUE_GET_METRICS, data: jobs, }); @@ -39,8 +37,7 @@ class JobQueueController { addJob = async (req, res, next) => { try { await this.jobQueue.addJob(Math.random().toString(36).substring(7)); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.QUEUE_ADD_JOB, }); } catch (error) { @@ -52,9 +49,9 @@ class JobQueueController { obliterateQueue = async (req, res, next) => { try { await this.jobQueue.obliterate(); - return res - .status(200) - .json({ success: true, msg: successMessages.QUEUE_OBLITERATE }); + return res.success({ + msg: successMessages.QUEUE_OBLITERATE, + }); } catch (error) { next(handleError(error, SERVICE_NAME, "obliterateQueue")); return; diff --git a/Server/controllers/settingsController.js b/Server/controllers/settingsController.js index 06a446dec..496ed057a 100644 --- a/Server/controllers/settingsController.js +++ b/Server/controllers/settingsController.js @@ -13,8 +13,7 @@ class SettingsController { try { const settings = { ...(await this.settingsService.getSettings()) }; delete settings.jwtSecret; - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.GET_APP_SETTINGS, data: settings, }); @@ -35,8 +34,7 @@ class SettingsController { await this.db.updateAppSettings(req.body); const updatedSettings = { ...(await this.settingsService.reloadSettings()) }; delete updatedSettings.jwtSecret; - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.UPDATE_APP_SETTINGS, data: updatedSettings, }); diff --git a/Server/controllers/statusPageController.js b/Server/controllers/statusPageController.js index bbb7a18ee..a4ceb8039 100644 --- a/Server/controllers/statusPageController.js +++ b/Server/controllers/statusPageController.js @@ -22,8 +22,7 @@ class StatusPageController { try { const statusPage = await this.db.createStatusPage(req.body); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.STATUS_PAGE_CREATE, data: statusPage, }); @@ -42,8 +41,7 @@ class StatusPageController { try { const { url } = req.params; const statusPage = await this.db.getStatusPageByUrl(url); - return res.status(200).json({ - success: true, + return res.success({ msg: successMessages.STATUS_PAGE_BY_URL, data: statusPage, }); diff --git a/Server/index.js b/Server/index.js index aa77fc0f6..7a4129bc9 100644 --- a/Server/index.js +++ b/Server/index.js @@ -8,6 +8,7 @@ import cors from "cors"; import logger from "./utils/logger.js"; import { verifyJWT } from "./middleware/verifyJWT.js"; import { handleErrors } from "./middleware/handleErrors.js"; +import { responseHandler } from "./middleware/responseHandler.js"; import { fileURLToPath } from "url"; import AuthRoutes from "./routes/authRoute.js"; @@ -272,6 +273,8 @@ const startApp = async () => { app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(openApiSpec)); //routes + app.use(responseHandler); + app.use("/api/v1/auth", authRoutes.getRouter()); app.use("/api/v1/settings", verifyJWT, settingsRoutes.getRouter()); app.use("/api/v1/invite", inviteRoutes.getRouter()); diff --git a/Server/middleware/handleErrors.js b/Server/middleware/handleErrors.js index bff2341c3..fa9af4c0b 100644 --- a/Server/middleware/handleErrors.js +++ b/Server/middleware/handleErrors.js @@ -11,7 +11,10 @@ const handleErrors = (error, req, res, next) => { method: error.method, stack: error.stack, }); - res.status(status).json({ success: false, msg: message }); + res.error({ + status, + msg: message, + }); }; export { handleErrors }; diff --git a/Server/middleware/responseHandler.js b/Server/middleware/responseHandler.js new file mode 100644 index 000000000..061422f50 --- /dev/null +++ b/Server/middleware/responseHandler.js @@ -0,0 +1,20 @@ +const responseHandler = (req, res, next) => { + res.success = ({ status = 200, msg = "OK", data = null }) => { + return res.status(status).json({ + success: true, + msg: msg, + data: data, + }); + }; + + res.error = ({ status = 500, msg = "Internal server error", data = null }) => { + return res.status(status).json({ + success: false, + msg, + data, + }); + }; + next(); +}; + +export { responseHandler }; diff --git a/Server/utils/messages.js b/Server/utils/messages.js index f2b29ccb8..5fc3c70bc 100644 --- a/Server/utils/messages.js +++ b/Server/utils/messages.js @@ -73,6 +73,7 @@ const successMessages = { ALERT_EDIT: "Alert edited successfully", ALERT_DELETE: "Alert deleted successfully", + // Auth Controller AUTH_CREATE_USER: "User created successfully", AUTH_LOGIN_USER: "User logged in successfully", AUTH_LOGOUT_USER: "User logged out successfully", @@ -83,6 +84,11 @@ const successMessages = { AUTH_ADMIN_CHECK: "Admin check completed successfully", AUTH_DELETE_USER: "User deleted successfully", AUTH_TOKEN_REFRESHED: "Auth token is refreshed", + AUTH_GET_ALL_USERS: "Got all users successfully", + + // Invite Controller + INVITE_ISSUED: "Invite sent successfully", + INVITE_VERIFIED: "Invite verified successfully", // Check Controller CHECK_CREATE: "Check created successfully", @@ -94,6 +100,7 @@ const successMessages = { MONITOR_GET_ALL: "Got all monitors successfully", MONITOR_STATS_BY_ID: "Got monitor stats by Id successfully", MONITOR_GET_BY_ID: "Got monitor by Id successfully", + MONITOR_GET_BY_TEAM_ID: "Got monitors by Team Id successfully", MONITOR_GET_BY_USER_ID: (userId) => `Got monitor for ${userId} successfully"`, MONITOR_CREATE: "Monitor created successfully", MONITOR_DELETE: "Monitor deleted successfully",