diff --git a/Server/controllers/notificationController.js b/Server/controllers/notificationController.js index dadf86a58..6f28579ff 100644 --- a/Server/controllers/notificationController.js +++ b/Server/controllers/notificationController.js @@ -6,53 +6,21 @@ class NotificationController { } async triggerNotification(req, res) { - const { monitorId, type, config } = req.body; - - if (!monitorId || !type) { - return res.status(400).json({ - success: false, - msg: "monitorId and type are required" - }); - } - try { + const { monitorId, type, config } = req.body; + const networkResponse = { monitor: { _id: monitorId, name: "Test Monitor", url: "http://www.google.com" }, status: false, statusChanged: true, prevStatus: true, }; - if (type === "webhook") { - if (!config?.type) { - return res.status(400).json({ - success: false, - msg: "webhook type is required in config" - }); - } - - if (config.type === "telegram") { - if (!config.botToken || !config.chatId) { - return res.status(400).json({ - success: false, - msg: "botToken and chatId are required for Telegram notifications" - }); - } - } else if (["discord", "slack"].includes(config.type)) { - if (!config.webhookUrl) { - return res.status(400).json({ - success: false, - msg: `webhookUrl is required for ${config.type} notifications` - }); - } - } - await this.notificationService.sendWebhookNotification( networkResponse, config ); } - res.json({ success: true, msg: "Notification sent successfully" }); } catch (error) { logger.error({ diff --git a/Server/routes/notificationRoute.js b/Server/routes/notificationRoute.js index d1c420af6..4f8ae8539 100644 --- a/Server/routes/notificationRoute.js +++ b/Server/routes/notificationRoute.js @@ -1,5 +1,6 @@ import express from 'express'; import { verifyJWT } from '../middleware/verifyJWT.js'; +import { triggerNotificationBodyValidation } from '../validation/joi.js'; class NotificationRoutes { constructor(notificationController) { @@ -8,8 +9,35 @@ class NotificationRoutes { this.initializeRoutes(); } + validateRequest(schema) { + return (req, res, next) => { + const { error } = schema.validate(req.body, { + abortEarly: false, + stripUnknown: true + }); + + if (error) { + const errorMessage = error.details + .map(detail => detail.message) + .join(', '); + + return res.status(400).json({ + success: false, + msg: errorMessage + }); + } + + next(); + }; + } + initializeRoutes() { - this.router.post('/trigger', verifyJWT, this.notificationController.triggerNotification.bind(this.notificationController)); + this.router.post( + '/trigger', + verifyJWT, + this.validateRequest(triggerNotificationBodyValidation), + this.notificationController.triggerNotification.bind(this.notificationController) + ); } getRouter() { @@ -17,4 +45,4 @@ class NotificationRoutes { } } -export default NotificationRoutes; +export default NotificationRoutes; \ No newline at end of file diff --git a/Server/validation/joi.js b/Server/validation/joi.js index b60022fc5..a03b03055 100644 --- a/Server/validation/joi.js +++ b/Server/validation/joi.js @@ -475,6 +475,59 @@ const imageValidation = joi "any.required": "Image file is required", }); + const telegramWebhookConfigValidation = joi.object({ + type: joi.string().valid('telegram').required(), + botToken: joi.string().required().messages({ + 'string.empty': 'Telegram bot token is required', + 'any.required': 'Telegram bot token is required' + }), + chatId: joi.string().required().messages({ + 'string.empty': 'Telegram chat ID is required', + 'any.required': 'Telegram chat ID is required' + }) + }); + + const discordWebhookConfigValidation = joi.object({ + type: joi.string().valid('discord').required(), + webhookUrl: joi.string().uri().required().messages({ + 'string.empty': 'Discord webhook URL is required', + 'string.uri': 'Discord webhook URL must be a valid URL', + 'any.required': 'Discord webhook URL is required' + }) + }); + + const slackWebhookConfigValidation = joi.object({ + type: joi.string().valid('slack').required(), + webhookUrl: joi.string().uri().required().messages({ + 'string.empty': 'Slack webhook URL is required', + 'string.uri': 'Slack webhook URL must be a valid URL', + 'any.required': 'Slack webhook URL is required' + }) + }); + + const triggerNotificationBodyValidation = joi.object({ + monitorId: joi.string().required().messages({ + 'string.empty': 'Monitor ID is required', + 'any.required': 'Monitor ID is required' + }), + type: joi.string().valid('webhook').required().messages({ + 'string.empty': 'Notification type is required', + 'any.required': 'Notification type is required', + 'any.only': 'Notification type must be webhook' + }), + config: joi.alternatives() + .conditional('type', { + is: 'webhook', + then: joi.alternatives().try( + telegramWebhookConfigValidation, + discordWebhookConfigValidation, + slackWebhookConfigValidation + ).required().messages({ + 'any.required': 'Webhook configuration is required' + }) + }) + }); + export { roleValidatior, loginValidation, @@ -533,5 +586,9 @@ export { createStatusPageBodyValidation, getStatusPageParamValidation, getStatusPageQueryValidation, - imageValidation, + imageValidation, + triggerNotificationBodyValidation, + telegramWebhookConfigValidation, + discordWebhookConfigValidation, + slackWebhookConfigValidation };