From 9adbd04538714740506708d6fa610e433be4d2a4 Mon Sep 17 00:00:00 2001 From: Nawaz Dhandala Date: Mon, 30 Mar 2026 09:50:40 +0100 Subject: [PATCH] feat: add user authentication middleware to notification API routes --- App/FeatureSet/Notification/API/Call.ts | 3 +++ .../Notification/API/PhoneNumber.ts | 11 +++++++++ App/FeatureSet/Notification/API/SMS.ts | 3 +++ App/FeatureSet/Notification/API/SMTPConfig.ts | 3 +++ App/FeatureSet/Notification/API/WhatsApp.ts | 3 +++ Common/Server/API/StatusPageAPI.ts | 6 ++++- Common/Server/Middleware/UserAuthorization.ts | 24 +++++++++++++++++++ 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/App/FeatureSet/Notification/API/Call.ts b/App/FeatureSet/Notification/API/Call.ts index fcbbb9b8a4..0e37543d91 100644 --- a/App/FeatureSet/Notification/API/Call.ts +++ b/App/FeatureSet/Notification/API/Call.ts @@ -16,6 +16,7 @@ import Express, { } from "Common/Server/Utils/Express"; import logger from "Common/Server/Utils/Logger"; import Response from "Common/Server/Utils/Response"; +import UserMiddleware from "Common/Server/Middleware/UserAuthorization"; import ProjectCallSMSConfig from "Common/Models/DatabaseModels/ProjectCallSMSConfig"; const router: ExpressRouter = Express.getRouter(); @@ -60,6 +61,8 @@ router.post( router.post( "/test", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body; diff --git a/App/FeatureSet/Notification/API/PhoneNumber.ts b/App/FeatureSet/Notification/API/PhoneNumber.ts index 82839aa4f1..17f542265e 100644 --- a/App/FeatureSet/Notification/API/PhoneNumber.ts +++ b/App/FeatureSet/Notification/API/PhoneNumber.ts @@ -13,6 +13,7 @@ import { JSONObject } from "Common/Types/JSON"; import ObjectID from "Common/Types/ObjectID"; import IncomingCallPolicyService from "Common/Server/Services/IncomingCallPolicyService"; import ProjectService from "Common/Server/Services/ProjectService"; +import UserMiddleware from "Common/Server/Middleware/UserAuthorization"; import Express, { ExpressRequest, ExpressResponse, @@ -30,6 +31,8 @@ const router: ExpressRouter = Express.getRouter(); // Search available phone numbers router.post( "/search", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body as JSONObject; @@ -154,6 +157,8 @@ router.post( // List owned phone numbers (already purchased in Twilio account) router.post( "/list-owned", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body as JSONObject; @@ -237,6 +242,8 @@ router.post( // Assign an existing phone number to a policy router.post( "/assign-existing", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body as JSONObject; @@ -385,6 +392,8 @@ router.post( // Purchase a phone number router.post( "/purchase", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body as JSONObject; @@ -528,6 +537,8 @@ router.post( // Release a phone number router.delete( "/release/:incomingCallPolicyId", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const incomingCallPolicyId: ObjectID | undefined = req.params[ diff --git a/App/FeatureSet/Notification/API/SMS.ts b/App/FeatureSet/Notification/API/SMS.ts index 20de92383e..b91c6a2373 100644 --- a/App/FeatureSet/Notification/API/SMS.ts +++ b/App/FeatureSet/Notification/API/SMS.ts @@ -15,6 +15,7 @@ import Express, { } from "Common/Server/Utils/Express"; import logger from "Common/Server/Utils/Logger"; import Response from "Common/Server/Utils/Response"; +import UserMiddleware from "Common/Server/Middleware/UserAuthorization"; import ProjectCallSMSConfig from "Common/Models/DatabaseModels/ProjectCallSMSConfig"; const router: ExpressRouter = Express.getRouter(); @@ -59,6 +60,8 @@ router.post( router.post( "/test", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body; diff --git a/App/FeatureSet/Notification/API/SMTPConfig.ts b/App/FeatureSet/Notification/API/SMTPConfig.ts index 763f6ab4e6..ede185a244 100644 --- a/App/FeatureSet/Notification/API/SMTPConfig.ts +++ b/App/FeatureSet/Notification/API/SMTPConfig.ts @@ -18,12 +18,15 @@ import Express, { } from "Common/Server/Utils/Express"; import logger from "Common/Server/Utils/Logger"; import Response from "Common/Server/Utils/Response"; +import UserMiddleware from "Common/Server/Middleware/UserAuthorization"; import ProjectSmtpConfig from "Common/Models/DatabaseModels/ProjectSmtpConfig"; const router: ExpressRouter = Express.getRouter(); router.post( "/test", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body; diff --git a/App/FeatureSet/Notification/API/WhatsApp.ts b/App/FeatureSet/Notification/API/WhatsApp.ts index 75f962ffa1..9c766d9026 100644 --- a/App/FeatureSet/Notification/API/WhatsApp.ts +++ b/App/FeatureSet/Notification/API/WhatsApp.ts @@ -12,6 +12,7 @@ import { } from "Common/Types/WhatsApp/WhatsAppTemplates"; import WhatsAppStatus from "Common/Types/WhatsAppStatus"; import ClusterKeyAuthorization from "Common/Server/Middleware/ClusterKeyAuthorization"; +import UserMiddleware from "Common/Server/Middleware/UserAuthorization"; import WhatsAppAuthorization from "Common/Server/Middleware/WhatsAppAuthorization"; import WhatsAppLogService from "Common/Server/Services/WhatsAppLogService"; import GlobalConfigService from "Common/Server/Services/GlobalConfigService"; @@ -443,6 +444,8 @@ router.post( router.post( "/test", + UserMiddleware.getUserMiddleware, + UserMiddleware.requireUserAuthentication, async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const body: JSONObject = req.body as JSONObject; diff --git a/Common/Server/API/StatusPageAPI.ts b/Common/Server/API/StatusPageAPI.ts index 6a77548a43..180c203458 100644 --- a/Common/Server/API/StatusPageAPI.ts +++ b/Common/Server/API/StatusPageAPI.ts @@ -2234,7 +2234,11 @@ export default class StatusPageAPI extends BaseAPI< incidentStateTimelines, IncidentStateTimeline, ), - statusPage: BaseModel.toJSONObject(statusPage, StatusPage), + statusPage: (() => { + const statusPageJson: JSONObject = BaseModel.toJSONObject(statusPage, StatusPage); + delete statusPageJson["projectId"]; + return statusPageJson; + })(), scheduledMaintenanceStateTimelines: BaseModel.toJSONArray( scheduledMaintenanceStateTimelines, ScheduledMaintenanceStateTimeline, diff --git a/Common/Server/Middleware/UserAuthorization.ts b/Common/Server/Middleware/UserAuthorization.ts index f275c1c48c..d374af7990 100644 --- a/Common/Server/Middleware/UserAuthorization.ts +++ b/Common/Server/Middleware/UserAuthorization.ts @@ -336,6 +336,30 @@ export default class UserMiddleware { return next(); } + @CaptureSpan() + public static async requireUserAuthentication( + req: ExpressRequest, + res: ExpressResponse, + next: NextFunction, + ): Promise { + const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest; + + if ( + !oneuptimeRequest.userType || + oneuptimeRequest.userType === UserType.Public + ) { + return Response.sendErrorResponse( + req, + res, + new NotAuthenticatedException( + "Authentication required. Please log in to access this resource.", + ), + ); + } + + return next(); + } + @CaptureSpan() public static async getUserTenantAccessPermissionWithTenantId(data: { req: ExpressRequest;