Merge pull request #2650 from bluewave-labs/fix/route-reorder

fix: reorder routes for correctness
This commit is contained in:
Alexander Holliday
2025-07-21 09:56:50 -07:00
committed by GitHub
17 changed files with 123 additions and 127 deletions

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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
);
}

View File

@@ -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() {

View File

@@ -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",

View File

@@ -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() {

View File

@@ -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);
}

View File

@@ -30,7 +30,7 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>
We hope youre finding Checkmate helpful in monitoring your infrastructure.
Your support means a lot to us, and we <b>truly appreciate</b> having you as

View File

@@ -29,10 +29,12 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>One of the admins created an account for you on the Checkmate server.</p>
<p>You can go ahead and create your account using this link.</p>
<p><a href="{{link}}">{{link}}</a></p>
<p>
<a href="{{link}}">{{ link }}</a>
</p>
<p>Thank you.</p>
</mj-text>
</mj-column>

View File

@@ -47,10 +47,10 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>{{monitor}} at {{url}} has the following infrastructure alerts:</p>
<p>Hello {{ name }}!</p>
<p>{{ monitor }} at {{ url }} has the following infrastructure alerts:</p>
{{#each alerts}}
<p>• {{this}}</p>
<p>• {{ this }}</p>
{{/each}}
</mj-text>
</mj-column>

View File

@@ -45,7 +45,7 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>There were no incidents this week. Good job!</p>
<p><b>Current monitors:</b></p>
<p><b>Google:</b> 100% availability</p>

View File

@@ -31,10 +31,10 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>
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.
</p>
<a href="{{url}}">Reset Password</a>
<p>If you didn't request this, please ignore this email.</p>

View File

@@ -36,7 +36,7 @@
font-size="18px"
color="red"
>
{{monitor}} is down
{{ monitor }} is down
</mj-text>
<mj-divider
border-width="2px"
@@ -47,13 +47,13 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>
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.
</p>
<p><b>Monitor name:</b> {{monitor}}</p>
<p><b>URL:</b> {{url}}</p>
<p><b>Monitor name:</b> {{ monitor }}</p>
<p><b>URL:</b> {{ url }}</p>
</mj-text>
</mj-column>
<mj-column width="100%">

View File

@@ -36,7 +36,7 @@
font-size="18px"
color="green"
>
{{monitor}} is up
{{ monitor }} is up
</mj-text>
<mj-divider
border-width="2px"
@@ -47,10 +47,10 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>Your latest incident is resolved and your monitored service is up again.</p>
<p><b>Monitor name:</b> {{monitor}}</p>
<p><b>URL:</b> {{url}}</p>
<p><b>Monitor name:</b> {{ monitor }}</p>
<p><b>URL:</b> {{ url }}</p>
</mj-text>
</mj-column>
<mj-column width="100%">

View File

@@ -30,7 +30,7 @@
<mj-section>
<mj-column width="100%">
<mj-text>
<p>Hello {{name}}!</p>
<p>Hello {{ name }}!</p>
<p>
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.