diff --git a/server/src/config/routes.ts b/server/src/config/routes.ts index d38ac69ae..8707009a8 100644 --- a/server/src/config/routes.ts +++ b/server/src/config/routes.ts @@ -1,4 +1,5 @@ import { createVerifyJWT } from "../middleware/verifyJWT.js"; +import { createVerifyStatusPageAccess } from "../middleware/verifyStatusPageAccess.js"; import { authApiLimiter } from "../middleware/rateLimiter.js"; import AuthRoutes from "../routes/authRoute.js"; @@ -25,7 +26,8 @@ export const setupRoutes = (app: any, controllers: Record, services const maintenanceWindowRoutes = new MaintenanceWindowRoutes(controllers.maintenanceWindowController); const queueRoutes = new QueueRoutes(controllers.queueController); const logRoutes = new LogRoutes(controllers.logController); - const statusPageRoutes = new StatusPageRoutes(controllers.statusPageController, verifyJWT); + const verifyStatusPageAccess = createVerifyStatusPageAccess(services.statusPagesRepository, verifyJWT); + const statusPageRoutes = new StatusPageRoutes(controllers.statusPageController, verifyJWT, verifyStatusPageAccess); const notificationRoutes = new NotificationRoutes(controllers.notificationController); const diagnosticRoutes = new DiagnosticRoutes(controllers.diagnosticController, verifyJWT); const incidentRoutes = new IncidentRoutes(controllers.incidentController); diff --git a/server/src/controllers/statusPageController.ts b/server/src/controllers/statusPageController.ts index f9cca161e..b936ff5ad 100644 --- a/server/src/controllers/statusPageController.ts +++ b/server/src/controllers/statusPageController.ts @@ -78,6 +78,14 @@ class StatusPageController { } const statusPage = await this.statusPageService.getStatusPageByUrl(req.params.url as string); + + if (!statusPage.isPublished) { + const teamId = requireTeamId(req?.user?.teamId); + if (statusPage.teamId !== teamId) { + throw new AppError({ message: "Forbidden", status: 403 }); + } + } + const settings = await this.settingsService.getDBSettings(); const showURL = settings.showURL; diff --git a/server/src/middleware/verifyStatusPageAccess.ts b/server/src/middleware/verifyStatusPageAccess.ts new file mode 100644 index 000000000..7f8d8baba --- /dev/null +++ b/server/src/middleware/verifyStatusPageAccess.ts @@ -0,0 +1,22 @@ +import { NextFunction, Request, RequestHandler, Response } from "express"; +import { IStatusPagesRepository } from "@/repositories/index.js"; +import { AppError } from "@/utils/AppError.js"; + +export const createVerifyStatusPageAccess = (statusPagesRepository: IStatusPagesRepository, verifyJWT: RequestHandler) => { + return async (req: Request, res: Response, next: NextFunction) => { + try { + const url = req.params.url; + if (!url) { + throw new AppError({ message: "Status page URL is required", status: 400 }); + } + const statusPage = await statusPagesRepository.findByUrl(url); + if (statusPage.isPublished) { + next(); // Published — no auth needed + } else { + verifyJWT(req, res, next); // Unpublished — require JWT + } + } catch (error) { + next(error); + } + }; +}; diff --git a/server/src/routes/statusPageRoute.ts b/server/src/routes/statusPageRoute.ts index 1468f9d16..a53aa04d9 100755 --- a/server/src/routes/statusPageRoute.ts +++ b/server/src/routes/statusPageRoute.ts @@ -6,19 +6,19 @@ class StatusPageRoutes { private router: Router; private statusPageController: any; - constructor(statusPageController: any, verifyJWT: RequestHandler) { + constructor(statusPageController: any, verifyJWT: RequestHandler, verifyStatusPageAccess: RequestHandler) { this.router = Router(); this.statusPageController = statusPageController; - this.initRoutes(verifyJWT); + this.initRoutes(verifyJWT, verifyStatusPageAccess); } - initRoutes(verifyJWT: RequestHandler) { + initRoutes(verifyJWT: RequestHandler, verifyStatusPageAccess: RequestHandler) { this.router.get("/team", verifyJWT, this.statusPageController.getStatusPagesByTeamId); this.router.post("/", upload.single("logo"), verifyJWT, this.statusPageController.createStatusPage); this.router.put("/:id", upload.single("logo"), verifyJWT, this.statusPageController.updateStatusPage); - this.router.get("/:url", this.statusPageController.getStatusPageByUrl); + this.router.get("/:url", verifyStatusPageAccess, this.statusPageController.getStatusPageByUrl); this.router.delete("/:id", verifyJWT, this.statusPageController.deleteStatusPage); }