From 0c04db3299e72cf77ac1996f93007c6bf54ae692 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 21 Jul 2025 09:55:49 -0700 Subject: [PATCH] reorder routes for correctness --- server/middleware/verifyJWT.js | 17 ++-- server/routes/checkRoute.js | 14 +-- server/routes/diagnosticRoute.js | 5 +- server/routes/inviteRoute.js | 13 ++- server/routes/maintenanceWindowRoute.js | 20 ++--- server/routes/monitorRoute.js | 103 +++++++++++----------- server/routes/notificationRoute.js | 7 +- server/routes/queueRoute.js | 30 +++---- server/routes/statusPageRoute.js | 3 +- server/templates/addReview.mjml | 2 +- server/templates/employeeActivation.mjml | 6 +- server/templates/hardwareIncident.mjml | 6 +- server/templates/noIncidentsThisWeek.mjml | 2 +- server/templates/passwordReset.mjml | 4 +- server/templates/serverIsDown.mjml | 8 +- server/templates/serverIsUp.mjml | 8 +- server/templates/welcomeEmail.mjml | 2 +- 17 files changed, 123 insertions(+), 127 deletions(-) diff --git a/server/middleware/verifyJWT.js b/server/middleware/verifyJWT.js index bd17edcfd..bab832502 100755 --- a/server/middleware/verifyJWT.js +++ b/server/middleware/verifyJWT.js @@ -39,13 +39,16 @@ const verifyJWT = (req, res, next) => { const { jwtSecret } = ServiceRegistry.get(SettingsService.SERVICE_NAME).getSettings(); jwt.verify(parsedToken, jwtSecret, (err, decoded) => { if (err) { - if (err) { - const errorMessage = - err.name === "TokenExpiredError" - ? stringService.expiredAuthToken - : stringService.invalidAuthToken; - return res.status(401).json({ success: false, msg: errorMessage }); - } + const errorMessage = + err.name === "TokenExpiredError" + ? stringService.expiredAuthToken + : stringService.invalidAuthToken; + err.details = { msg: errorMessage }; + err.status = 401; + err.service = SERVICE_NAME; + err.method = "verifyJWT"; + next(err); + return; } else { // Token is valid, carry on req.user = decoded; diff --git a/server/routes/checkRoute.js b/server/routes/checkRoute.js index f215cbe37..7165d73f1 100755 --- a/server/routes/checkRoute.js +++ b/server/routes/checkRoute.js @@ -13,23 +13,24 @@ class CheckRoutes { } initRoutes() { - this.router.get("/team", this.checkController.getChecksByTeam); this.router.get("/team/summary", this.checkController.getChecksSummaryByTeamId); + this.router.get("/team", this.checkController.getChecksByTeam); + this.router.put( + "/team/ttl", + isAllowed(["admin", "superadmin"]), + this.checkController.updateChecksTTL + ); this.router.delete( "/team", isAllowed(["admin", "superadmin"]), this.checkController.deleteChecksByTeamId ); + this.router.put( "/check/:checkId", verifyTeamAccess(Check, "checkId"), this.checkController.ackCheck ); - this.router.put( - "/team/ttl", - isAllowed(["admin", "superadmin"]), - this.checkController.updateChecksTTL - ); this.router.get("/:monitorId", this.checkController.getChecksByMonitor); this.router.post( @@ -42,6 +43,7 @@ class CheckRoutes { verifyOwnership(Monitor, "monitorId"), this.checkController.deleteChecks ); + this.router.put("/:path/:monitorId?", this.checkController.ackAllChecks); } diff --git a/server/routes/diagnosticRoute.js b/server/routes/diagnosticRoute.js index 0d8f4df84..920eddebf 100755 --- a/server/routes/diagnosticRoute.js +++ b/server/routes/diagnosticRoute.js @@ -7,13 +7,12 @@ class DiagnosticRoutes { this.initRoutes(); } initRoutes() { + this.router.post("/db/stats", this.diagnosticController.getDbStats); + this.router.get("/system", this.diagnosticController.getSystemStats); this.router.get( "/db/get-monitors-by-team-id/:teamId", this.diagnosticController.getMonitorsByTeamIdExecutionStats ); - - this.router.post("/db/stats", this.diagnosticController.getDbStats); - this.router.get("/system", this.diagnosticController.getSystemStats); } getRouter() { diff --git a/server/routes/inviteRoute.js b/server/routes/inviteRoute.js index 301959389..4c14400ba 100755 --- a/server/routes/inviteRoute.js +++ b/server/routes/inviteRoute.js @@ -10,15 +10,14 @@ class InviteRoutes { } initRoutes() { - this.router.post( - "/", - isAllowed(["admin", "superadmin"]), - verifyJWT, - this.inviteController.getInviteToken - ); - this.router.post("/send", this.inviteController.sendInviteEmail); this.router.post("/verify", this.inviteController.inviteVerifyController); + this.router.post( + "/", + verifyJWT, + isAllowed(["admin", "superadmin"]), + this.inviteController.getInviteToken + ); } getRouter() { diff --git a/server/routes/maintenanceWindowRoute.js b/server/routes/maintenanceWindowRoute.js index 36f982e25..03160ad76 100755 --- a/server/routes/maintenanceWindowRoute.js +++ b/server/routes/maintenanceWindowRoute.js @@ -6,35 +6,29 @@ import MaintenanceWindow from "../db/models/MaintenanceWindow.js"; class MaintenanceWindowRoutes { constructor(maintenanceWindowController) { this.router = Router(); - this.maintenanceWindowController = maintenanceWindowController; + this.mwController = maintenanceWindowController; this.initRoutes(); } initRoutes() { - this.router.post("/", this.maintenanceWindowController.createMaintenanceWindows); + this.router.post("/", this.mwController.createMaintenanceWindows); + this.router.get("/team/", this.mwController.getMaintenanceWindowsByTeamId); this.router.get( "/monitor/:monitorId", verifyOwnership(Monitor, "monitorId"), - this.maintenanceWindowController.getMaintenanceWindowsByMonitorId + this.mwController.getMaintenanceWindowsByMonitorId ); - this.router.get( - "/team/", - this.maintenanceWindowController.getMaintenanceWindowsByTeamId - ); - - this.router.get("/:id", this.maintenanceWindowController.getMaintenanceWindowById); - + this.router.get("/:id", this.mwController.getMaintenanceWindowById); this.router.put( "/:id", verifyTeamAccess(MaintenanceWindow, "id"), - this.maintenanceWindowController.editMaintenanceWindow + this.mwController.editMaintenanceWindow ); - this.router.delete( "/:id", verifyTeamAccess(MaintenanceWindow, "id"), - this.maintenanceWindowController.deleteMaintenanceWindow + this.mwController.deleteMaintenanceWindow ); } diff --git a/server/routes/monitorRoute.js b/server/routes/monitorRoute.js index 168f8b88d..3e39f4459 100755 --- a/server/routes/monitorRoute.js +++ b/server/routes/monitorRoute.js @@ -17,22 +17,43 @@ class MonitorRoutes { } initRoutes() { - this.router.get("/", this.monitorController.getAllMonitors); + // Team routes + this.router.get("/team", this.monitorController.getMonitorsByTeamId); + this.router.get( + "/team/with-checks", + this.monitorController.getMonitorsWithChecksByTeamId + ); + this.router.get( + "/summary/team", + this.monitorController.getMonitorsAndSummaryByTeamId + ); // TODO should be /team/summary + + // Uptime routes this.router.get("/uptime", this.monitorController.getAllMonitorsWithUptimeStats); this.router.get( - "/export", - isAllowed(["admin", "superadmin"]), - this.monitorController.exportMonitorsToCSV + "/uptime/details/:monitorId", + this.monitorController.getUptimeDetailsById ); - this.router.get("/stats/:monitorId", this.monitorController.getMonitorStatsById); + + // Hardware routes this.router.get( "/hardware/details/:monitorId", this.monitorController.getHardwareDetailsById ); + // General monitor routes + this.router.post( + "/pause/:monitorId", + isAllowed(["admin", "superadmin"]), + this.monitorController.pauseMonitor + ); + this.router.get("/stats/:monitorId", this.monitorController.getMonitorStatsById); + + // Util routes this.router.get( - "/uptime/details/:monitorId", - this.monitorController.getUptimeDetailsById + "/resolution/url", + isAllowed(["admin", "superadmin"]), + this.monitorController.checkEndpointResolution ); this.router.get("/certificate/:monitorId", (req, res, next) => { this.monitorController.getMonitorCertificate( @@ -42,78 +63,58 @@ class MonitorRoutes { fetchMonitorCertificate ); }); - this.router.get("/team", this.monitorController.getMonitorsByTeamId); - - this.router.get("/:monitorId", this.monitorController.getMonitorById); - - this.router.get( - "/summary/team", - this.monitorController.getMonitorsAndSummaryByTeamId - ); - - this.router.get( - "/team/with-checks", - this.monitorController.getMonitorsWithChecksByTeamId - ); - - this.router.get( - "/resolution/url", - isAllowed(["admin", "superadmin"]), - this.monitorController.checkEndpointResolution - ); - - this.router.delete( - "/:monitorId", - verifyOwnership(Monitor, "monitorId"), - isAllowed(["admin", "superadmin"]), - this.monitorController.deleteMonitor - ); + // General monitor CRUD routes + this.router.get("/", this.monitorController.getAllMonitors); this.router.post( "/", isAllowed(["admin", "superadmin"]), this.monitorController.createMonitor ); - - this.router.put( - "/:monitorId", - verifyTeamAccess(Monitor, "monitorId"), - isAllowed(["admin", "superadmin"]), - this.monitorController.editMonitor - ); - this.router.delete( "/", isAllowed(["superadmin"]), this.monitorController.deleteAllMonitors ); - this.router.post( - "/pause/:monitorId", - isAllowed(["admin", "superadmin"]), - this.monitorController.pauseMonitor - ); - + // Other static routes this.router.post( "/demo", isAllowed(["admin", "superadmin"]), this.monitorController.addDemoMonitors ); - + this.router.get( + "/export", + isAllowed(["admin", "superadmin"]), + this.monitorController.exportMonitorsToCSV + ); + this.router.post("/seed", isAllowed(["superadmin"]), this.monitorController.seedDb); this.router.post( "/bulk", isAllowed(["admin", "superadmin"]), upload.single("csvFile"), this.monitorController.createBulkMonitors ); - - this.router.post("/seed", isAllowed(["superadmin"]), this.monitorController.seedDb); - this.router.post( "/test-email", isAllowed(["admin", "superadmin"]), this.monitorController.sendTestEmail ); + + // Individual monitor CRUD routes + this.router.get("/:monitorId", this.monitorController.getMonitorById); + this.router.put( + "/:monitorId", + verifyTeamAccess(Monitor, "monitorId"), + isAllowed(["admin", "superadmin"]), + this.monitorController.editMonitor + ); + this.router.delete( + "/:monitorId", + verifyOwnership(Monitor, "monitorId"), + isAllowed(["admin", "superadmin"]), + this.monitorController.deleteMonitor + ); } getRouter() { diff --git a/server/routes/notificationRoute.js b/server/routes/notificationRoute.js index 09becd16c..9d3e95e63 100755 --- a/server/routes/notificationRoute.js +++ b/server/routes/notificationRoute.js @@ -13,11 +13,11 @@ class NotificationRoutes { initializeRoutes() { this.router.use(verifyJWT); - this.router.post("/test", this.notificationController.testNotification); - this.router.post("/test/all", this.notificationController.testAllNotifications); - this.router.post("/", this.notificationController.createNotification); + this.router.post("/test/all", this.notificationController.testAllNotifications); + this.router.post("/test", this.notificationController.testNotification); + this.router.get("/team", this.notificationController.getNotificationsByTeamId); this.router.delete( @@ -25,7 +25,6 @@ class NotificationRoutes { verifyOwnership(Notification, "id"), this.notificationController.deleteNotification ); - this.router.get("/:id", this.notificationController.getNotificationById); this.router.put( "/:id", diff --git a/server/routes/queueRoute.js b/server/routes/queueRoute.js index c40d21528..e54378d7a 100755 --- a/server/routes/queueRoute.js +++ b/server/routes/queueRoute.js @@ -7,41 +7,37 @@ class QueueRoutes { this.initRoutes(); } initRoutes() { - this.router.get( - "/metrics", - isAllowed(["admin", "superadmin"]), - this.queueController.getMetrics - ); - this.router.get( "/jobs", isAllowed(["admin", "superadmin"]), this.queueController.getJobs ); - - this.router.get( - "/all-metrics", - isAllowed(["admin", "superadmin"]), - this.queueController.getAllMetrics - ); - this.router.post( "/jobs", isAllowed(["admin", "superadmin"]), this.queueController.addJob ); - this.router.post( - "/flush", + this.router.get( + "/metrics", isAllowed(["admin", "superadmin"]), - this.queueController.flushQueue + this.queueController.getMetrics ); - this.router.get( "/health", isAllowed(["admin", "superadmin"]), this.queueController.checkQueueHealth ); + this.router.get( + "/all-metrics", + isAllowed(["admin", "superadmin"]), + this.queueController.getAllMetrics + ); + this.router.post( + "/flush", + isAllowed(["admin", "superadmin"]), + this.queueController.flushQueue + ); } getRouter() { diff --git a/server/routes/statusPageRoute.js b/server/routes/statusPageRoute.js index 98b3a3433..b348e9f82 100755 --- a/server/routes/statusPageRoute.js +++ b/server/routes/statusPageRoute.js @@ -13,7 +13,6 @@ class StatusPageRoutes { initRoutes() { this.router.get("/", this.statusPageController.getStatusPage); this.router.get("/team", verifyJWT, this.statusPageController.getStatusPagesByTeamId); - this.router.get("/:url", this.statusPageController.getStatusPageByUrl); this.router.post( "/", @@ -27,6 +26,8 @@ class StatusPageRoutes { verifyJWT, this.statusPageController.updateStatusPage ); + + this.router.get("/:url", this.statusPageController.getStatusPageByUrl); this.router.delete("/:url(*)", verifyJWT, this.statusPageController.deleteStatusPage); } diff --git a/server/templates/addReview.mjml b/server/templates/addReview.mjml index 9d00be7d0..644970f6e 100755 --- a/server/templates/addReview.mjml +++ b/server/templates/addReview.mjml @@ -30,7 +30,7 @@ -

Hello {{name}}!

+

Hello {{ name }}!

We hope you’re finding Checkmate helpful in monitoring your infrastructure. Your support means a lot to us, and we truly appreciate having you as diff --git a/server/templates/employeeActivation.mjml b/server/templates/employeeActivation.mjml index 3e35db6e8..317832c1f 100755 --- a/server/templates/employeeActivation.mjml +++ b/server/templates/employeeActivation.mjml @@ -29,10 +29,12 @@ -

Hello {{name}}!

+

Hello {{ name }}!

One of the admins created an account for you on the Checkmate server.

You can go ahead and create your account using this link.

-

{{link}}

+

+ {{ link }} +

Thank you.

diff --git a/server/templates/hardwareIncident.mjml b/server/templates/hardwareIncident.mjml index 19fb589fc..3f50a3d58 100755 --- a/server/templates/hardwareIncident.mjml +++ b/server/templates/hardwareIncident.mjml @@ -47,10 +47,10 @@ -

Hello {{name}}!

-

{{monitor}} at {{url}} has the following infrastructure alerts:

+

Hello {{ name }}!

+

{{ monitor }} at {{ url }} has the following infrastructure alerts:

{{#each alerts}} -

• {{this}}

+

• {{ this }}

{{/each}}
diff --git a/server/templates/noIncidentsThisWeek.mjml b/server/templates/noIncidentsThisWeek.mjml index d31d63d10..d160e44de 100755 --- a/server/templates/noIncidentsThisWeek.mjml +++ b/server/templates/noIncidentsThisWeek.mjml @@ -45,7 +45,7 @@ -

Hello {{name}}!

+

Hello {{ name }}!

There were no incidents this week. Good job!

Current monitors:

Google: 100% availability

diff --git a/server/templates/passwordReset.mjml b/server/templates/passwordReset.mjml index e0b85a4f4..5da29b341 100755 --- a/server/templates/passwordReset.mjml +++ b/server/templates/passwordReset.mjml @@ -31,10 +31,10 @@ -

Hello {{name}}!

+

Hello {{ name }}!

You are receiving this email because a password reset request has been made - for {{email}}. Please use the link below on the site to reset your password. + for {{ email }}. Please use the link below on the site to reset your password.

Reset Password

If you didn't request this, please ignore this email.

diff --git a/server/templates/serverIsDown.mjml b/server/templates/serverIsDown.mjml index b75d970e6..d46011070 100755 --- a/server/templates/serverIsDown.mjml +++ b/server/templates/serverIsDown.mjml @@ -36,7 +36,7 @@ font-size="18px" color="red" > - {{monitor}} is down + {{ monitor }} is down
-

Hello {{name}}!

+

Hello {{ name }}!

We detected an incident on one of your monitors. Your service is currently down. We'll send a message to you once it is up again.

-

Monitor name: {{monitor}}

-

URL: {{url}}

+

Monitor name: {{ monitor }}

+

URL: {{ url }}

diff --git a/server/templates/serverIsUp.mjml b/server/templates/serverIsUp.mjml index beb34481d..074c5e3dd 100755 --- a/server/templates/serverIsUp.mjml +++ b/server/templates/serverIsUp.mjml @@ -36,7 +36,7 @@ font-size="18px" color="green" > - {{monitor}} is up + {{ monitor }} is up
-

Hello {{name}}!

+

Hello {{ name }}!

Your latest incident is resolved and your monitored service is up again.

-

Monitor name: {{monitor}}

-

URL: {{url}}

+

Monitor name: {{ monitor }}

+

URL: {{ url }}

diff --git a/server/templates/welcomeEmail.mjml b/server/templates/welcomeEmail.mjml index 663518ec2..372e4c8ae 100755 --- a/server/templates/welcomeEmail.mjml +++ b/server/templates/welcomeEmail.mjml @@ -30,7 +30,7 @@ -

Hello {{name}}!

+

Hello {{ name }}!

Thank you for trying out Checkmate! We developed it with great care to meet our own needs, and we're excited to share it with you.