diff --git a/server/notification-providers/flashduty.js b/server/notification-providers/flashduty.js index c340ed06f..381fc5c47 100644 --- a/server/notification-providers/flashduty.js +++ b/server/notification-providers/flashduty.js @@ -7,6 +7,81 @@ const successMessage = "Sent Successfully."; class FlashDuty extends NotificationProvider { name = "FlashDuty"; + /** + * Sanitize and validate a URL string + * @param {string} urlStr URL to validate + * @returns {string|null} Sanitized URL or null if invalid + */ + validateURL(urlStr) { + try { + const url = new URL(urlStr); + // Only allow http and https protocols + if (![ "http:", "https:" ].includes(url.protocol)) { + return null; + } + return url.toString(); + } catch { + return null; + } + } + + /** + * Generate a monitor url from the monitors information + * @param {object} monitorInfo Monitor details + * @returns {string|undefined} Monitor URL + */ + genMonitorUrl(monitorInfo) { + if (!monitorInfo) { + return undefined; + } + + // For port type monitors + if (monitorInfo.type === "port" && monitorInfo.port) { + // Validate port number + const port = parseInt(monitorInfo.port, 10); + if (isNaN(port) || port < 1 || port > 65535) { + return undefined; + } + + // Try to construct a valid URL + try { + // If hostname already includes protocol, use it + const hasProtocol = /^[a-zA-Z]+:\/\//.test(monitorInfo.hostname); + const urlStr = hasProtocol ? + monitorInfo.hostname + ":" + port : + "http://" + monitorInfo.hostname + ":" + port; + + const url = new URL(urlStr); + return url.toString(); + } catch { + return undefined; + } + } + + // For hostname-based monitors + if (monitorInfo.hostname != null) { + try { + // If hostname already includes protocol, use it + const hasProtocol = /^[a-zA-Z]+:\/\//.test(monitorInfo.hostname); + const urlStr = hasProtocol ? + monitorInfo.hostname : + "http://" + monitorInfo.hostname; + + const url = new URL(urlStr); + return url.toString(); + } catch { + return undefined; + } + } + + // For URL-based monitors + if (monitorInfo.url) { + return this.validateURL(monitorInfo.url); + } + + return undefined; + } + /** * @inheritdoc */ @@ -37,21 +112,6 @@ class FlashDuty extends NotificationProvider { } } - /** - * Generate a monitor url from the monitors infomation - * @param {object} monitorInfo Monitor details - * @returns {string|undefined} Monitor URL - */ - genMonitorUrl(monitorInfo) { - if (monitorInfo.type === "port" && monitorInfo.port) { - return monitorInfo.hostname + ":" + monitorInfo.port; - } - if (monitorInfo.hostname != null) { - return monitorInfo.hostname; - } - return monitorInfo.url; - } - /** * Send the message * @param {BeanModel} notification Message title