From fbfa5a33ed2fb44b33d8b85359ddd3654630b73a Mon Sep 17 00:00:00 2001 From: Matthew Nickson Date: Sat, 11 Jun 2022 17:23:12 +0100 Subject: [PATCH 01/51] Added Clickable hostname on status page. #1221 This should fully implement #1221 by modifying the API and adding two new properties to the result. The `sendUrl` property denotes if the URL is sent and `url` is included when required. Client side checks have been implemented in order to only show a link when the URL is vaugely correct. I.e not "" or "https://". This prevents the link from being included if the monitor type is not HTTP without having to publicly expose the monitor type. The exposure of the URL is configuarable for each monitor on each status page by clicking on the link icon. Signed-off-by: Matthew Nickson --- db/patch-add-clickable-status-page-link.sql | 5 ++ server/database.js | 1 + server/model/group.js | 2 +- server/model/monitor.js | 6 +++ .../status-page-socket-handler.js | 1 + src/components/PublicGroupList.vue | 48 ++++++++++++++++++- src/icon.js | 1 + 7 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 db/patch-add-clickable-status-page-link.sql diff --git a/db/patch-add-clickable-status-page-link.sql b/db/patch-add-clickable-status-page-link.sql new file mode 100644 index 000000000..bacd669bd --- /dev/null +++ b/db/patch-add-clickable-status-page-link.sql @@ -0,0 +1,5 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; +ALTER TABLE monitor_group + ADD send_url BOOLEAN DEFAULT 0 NOT NULL; +COMMIT; diff --git a/server/database.js b/server/database.js index b17e7f4ed..8c93fed6a 100644 --- a/server/database.js +++ b/server/database.js @@ -58,6 +58,7 @@ class Database { "patch-monitor-expiry-notification.sql": true, "patch-status-page-footer-css.sql": true, "patch-added-mqtt-monitor.sql": true, + "patch-add-clickable-status-page-link.sql": true, }; /** diff --git a/server/model/group.js b/server/model/group.js index 599b758bc..3f3b3b129 100644 --- a/server/model/group.js +++ b/server/model/group.js @@ -31,7 +31,7 @@ class Group extends BeanModel { */ async getMonitorList() { return R.convertToBeans("monitor", await R.getAll(` - SELECT monitor.* FROM monitor, monitor_group + SELECT monitor.*, monitor_group.send_url FROM monitor, monitor_group WHERE monitor.id = monitor_group.monitor_id AND group_id = ? ORDER BY monitor_group.weight diff --git a/server/model/monitor.js b/server/model/monitor.js index 643d34a6f..b46c0e323 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -34,7 +34,13 @@ class Monitor extends BeanModel { let obj = { id: this.id, name: this.name, + sendUrl: this.sendUrl, }; + + if (this.sendUrl) { + obj.url = this.url; + } + if (showTags) { obj.tags = await this.getTags(); } diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index 0a0dc6865..80017e7d2 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -202,6 +202,7 @@ module.exports.statusPageSocketHandler = (socket) => { relationBean.weight = monitorOrder++; relationBean.group_id = groupBean.id; relationBean.monitor_id = monitor.id; + relationBean.send_url = monitor.sendUrl; await R.store(relationBean); } diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue index df94eec98..cbd8aeffe 100644 --- a/src/components/PublicGroupList.vue +++ b/src/components/PublicGroupList.vue @@ -39,7 +39,21 @@ - {{ monitor.element.name }} + + {{ monitor.element.name }} + +

{{ monitor.element.name }}

+
@@ -101,6 +115,27 @@ export default { removeMonitor(groupIndex, index) { this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1); }, + + /** + * Toggle the value of sendUrl + * @param {number} groupIndex Index of group monitor is member of + * @param {number} index Index of monitor within group + */ + toggleLink(groupIndex, index) { + this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl = !this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl; + }, + + /** + * Should a link to the monitor be shown? + * Attempts to guess if a link should be shown based upon if + * sendUrl is set and if the URL is default or not. + * @param {Object} monitor Monitor to check + * @returns {boolean} + */ + showLink(monitor) { + return monitor.element.sendUrl && monitor.element.url && monitor.element.url !== "https://"; + + }, } }; @@ -119,6 +154,17 @@ export default { min-height: 46px; } +.item-name { + padding-left: 5px; + padding-right: 5px; + margin: 0; + display: inline-block; +} + +.link-active { + color: #4caf50; +} + .flip-list-move { transition: transform 0.5s; } diff --git a/src/icon.js b/src/icon.js index d83034fa7..23513bccf 100644 --- a/src/icon.js +++ b/src/icon.js @@ -81,6 +81,7 @@ library.add( faUndo, faPlusCircle, faAngleDown, + faLink, ); export { FontAwesomeIcon }; From 5f6347d277695f8af5a68b186b373809f7a03272 Mon Sep 17 00:00:00 2001 From: Daeho Ro Date: Sun, 12 Jun 2022 04:02:44 +0900 Subject: [PATCH 02/51] pull request for adding alertnow notification --- server/notification-providers/alertnow.js | 50 ++++++++++ server/notification.js | 68 ++++++------- src/components/notifications/AlertNow.vue | 13 +++ src/components/notifications/index.js | 112 +++++++++++----------- 4 files changed, 155 insertions(+), 88 deletions(-) create mode 100644 server/notification-providers/alertnow.js create mode 100644 src/components/notifications/AlertNow.vue diff --git a/server/notification-providers/alertnow.js b/server/notification-providers/alertnow.js new file mode 100644 index 000000000..d778b01d3 --- /dev/null +++ b/server/notification-providers/alertnow.js @@ -0,0 +1,50 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); +const { setting } = require("../util-server"); +const { getMonitorRelativeURL, UP, DOWN } = require("../../src/util"); + +class AlertNow extends NotificationProvider { + + name = "AlertNow"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + try { + let textMsg = ""; + let status = "open"; + let eventType = "ERROR"; + let eventId = new Date().toISOString().slice(0, 10).replace(/-/g, ""); + + if (heartbeatJSON && heartbeatJSON.status === UP) { + textMsg = `[${heartbeatJSON.name}] ✅ Application is back online`; + status = "close"; + eventType = "INFO"; + eventId += `_${heartbeatJSON.name.replace(/\s/g, "")}`; + } else if (heartbeatJSON && heartbeatJSON.status === DOWN) { + textMsg = `[${heartbeatJSON.name}] 🔴 Application went down`; + } + + textMsg += ` - ${msg}`; + + const baseURL = await setting("primaryBaseURL"); + if (baseURL && monitorJSON) { + textMsg += ` >> ${baseURL + getMonitorRelativeURL(monitorJSON.id)}`; + } + + const data = { + "summary": textMsg, + "status": status, + "event_type": eventType, + "event_id": eventId, + }; + + await axios.post(notification.alertNowWebhookURL, data); + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + + } +} + +module.exports = AlertNow; diff --git a/server/notification.js b/server/notification.js index c457ed144..a3b3a70b6 100644 --- a/server/notification.js +++ b/server/notification.js @@ -1,40 +1,41 @@ const { R } = require("redbean-node"); +const { log } = require("../src/util"); +const Alerta = require("./notification-providers/alerta"); +const AlertNow = require("./notification-providers/alertnow"); +const AliyunSms = require("./notification-providers/aliyun-sms"); const Apprise = require("./notification-providers/apprise"); +const Bark = require("./notification-providers/bark"); +const ClickSendSMS = require("./notification-providers/clicksendsms"); +const DingDing = require("./notification-providers/dingding"); const Discord = require("./notification-providers/discord"); +const Feishu = require("./notification-providers/feishu"); +const GoogleChat = require("./notification-providers/google-chat"); +const Gorush = require("./notification-providers/gorush"); const Gotify = require("./notification-providers/gotify"); -const Ntfy = require("./notification-providers/ntfy"); const Line = require("./notification-providers/line"); const LunaSea = require("./notification-providers/lunasea"); -const Mattermost = require("./notification-providers/mattermost"); const Matrix = require("./notification-providers/matrix"); +const Mattermost = require("./notification-providers/mattermost"); +const Ntfy = require("./notification-providers/ntfy"); const Octopush = require("./notification-providers/octopush"); +const OneBot = require("./notification-providers/onebot"); +const PagerDuty = require("./notification-providers/pagerduty"); const PromoSMS = require("./notification-providers/promosms"); -const ClickSendSMS = require("./notification-providers/clicksendsms"); const Pushbullet = require("./notification-providers/pushbullet"); +const PushDeer = require("./notification-providers/pushdeer"); const Pushover = require("./notification-providers/pushover"); const Pushy = require("./notification-providers/pushy"); -const TechulusPush = require("./notification-providers/techulus-push"); const RocketChat = require("./notification-providers/rocket-chat"); +const SerwerSMS = require("./notification-providers/serwersms"); const Signal = require("./notification-providers/signal"); const Slack = require("./notification-providers/slack"); const SMTP = require("./notification-providers/smtp"); +const Stackfield = require("./notification-providers/stackfield"); const Teams = require("./notification-providers/teams"); +const TechulusPush = require("./notification-providers/techulus-push"); const Telegram = require("./notification-providers/telegram"); const Webhook = require("./notification-providers/webhook"); -const Feishu = require("./notification-providers/feishu"); -const AliyunSms = require("./notification-providers/aliyun-sms"); -const DingDing = require("./notification-providers/dingding"); -const Bark = require("./notification-providers/bark"); -const { log } = require("../src/util"); -const SerwerSMS = require("./notification-providers/serwersms"); -const Stackfield = require("./notification-providers/stackfield"); const WeCom = require("./notification-providers/wecom"); -const GoogleChat = require("./notification-providers/google-chat"); -const PagerDuty = require("./notification-providers/pagerduty"); -const Gorush = require("./notification-providers/gorush"); -const Alerta = require("./notification-providers/alerta"); -const OneBot = require("./notification-providers/onebot"); -const PushDeer = require("./notification-providers/pushdeer"); class Notification { @@ -47,41 +48,42 @@ class Notification { this.providerList = {}; const list = [ - new Apprise(), + new Alerta(), + new AlertNow(), new AliyunSms(), + new Apprise(), + new Bark(), + new ClickSendSMS(), new DingDing(), new Discord(), - new Teams(), + new Feishu(), + new GoogleChat(), + new Gorush(), new Gotify(), - new Ntfy(), new Line(), new LunaSea(), - new Feishu(), - new Mattermost(), new Matrix(), + new Mattermost(), + new Ntfy(), new Octopush(), + new OneBot(), + new PagerDuty(), new PromoSMS(), - new ClickSendSMS(), new Pushbullet(), + new PushDeer(), new Pushover(), new Pushy(), - new TechulusPush(), new RocketChat(), + new SerwerSMS(), new Signal(), new Slack(), new SMTP(), + new Stackfield(), + new Teams(), + new TechulusPush(), new Telegram(), new Webhook(), - new Bark(), - new SerwerSMS(), - new Stackfield(), new WeCom(), - new GoogleChat(), - new PagerDuty(), - new Gorush(), - new Alerta(), - new OneBot(), - new PushDeer(), ]; for (let item of list) { diff --git a/src/components/notifications/AlertNow.vue b/src/components/notifications/AlertNow.vue new file mode 100644 index 000000000..93acc9590 --- /dev/null +++ b/src/components/notifications/AlertNow.vue @@ -0,0 +1,13 @@ + diff --git a/src/components/notifications/index.js b/src/components/notifications/index.js index 18c316a53..e5cbe8ce3 100644 --- a/src/components/notifications/index.js +++ b/src/components/notifications/index.js @@ -1,38 +1,39 @@ -import STMP from "./SMTP.vue"; -import Telegram from "./Telegram.vue"; +import Alerta from "./Alerta.vue"; +import AlertNow from "./AlertNow.vue"; +import AliyunSMS from "./AliyunSms.vue"; +import Apprise from "./Apprise.vue"; +import Bark from "./Bark.vue"; +import ClickSendSMS from "./ClickSendSMS.vue"; +import DingDing from "./DingDing.vue"; import Discord from "./Discord.vue"; -import Webhook from "./Webhook.vue"; -import Signal from "./Signal.vue"; +import Feishu from "./Feishu.vue"; +import GoogleChat from "./GoogleChat.vue"; +import Gorush from "./Gorush.vue"; import Gotify from "./Gotify.vue"; +import Line from "./Line.vue"; +import LunaSea from "./LunaSea.vue"; +import Matrix from "./Matrix.vue"; +import Mattermost from "./Mattermost.vue"; import Ntfy from "./Ntfy.vue"; -import Slack from "./Slack.vue"; -import RocketChat from "./RocketChat.vue"; -import Teams from "./Teams.vue"; +import Octopush from "./Octopush.vue"; +import OneBot from "./OneBot.vue"; +import PagerDuty from "./PagerDuty.vue"; +import PromoSMS from "./PromoSMS.vue"; +import Pushbullet from "./Pushbullet.vue"; +import PushDeer from "./PushDeer.vue"; import Pushover from "./Pushover.vue"; import Pushy from "./Pushy.vue"; -import TechulusPush from "./TechulusPush.vue"; -import Octopush from "./Octopush.vue"; -import PromoSMS from "./PromoSMS.vue"; -import ClickSendSMS from "./ClickSendSMS.vue"; -import LunaSea from "./LunaSea.vue"; -import Feishu from "./Feishu.vue"; -import Apprise from "./Apprise.vue"; -import Pushbullet from "./Pushbullet.vue"; -import Line from "./Line.vue"; -import Mattermost from "./Mattermost.vue"; -import Matrix from "./Matrix.vue"; -import AliyunSMS from "./AliyunSms.vue"; -import DingDing from "./DingDing.vue"; -import Bark from "./Bark.vue"; +import RocketChat from "./RocketChat.vue"; import SerwerSMS from "./SerwerSMS.vue"; +import Signal from "./Signal.vue"; +import Slack from "./Slack.vue"; import Stackfield from "./Stackfield.vue"; +import STMP from "./SMTP.vue"; +import Teams from "./Teams.vue"; +import TechulusPush from "./TechulusPush.vue"; +import Telegram from "./Telegram.vue"; +import Webhook from "./Webhook.vue"; import WeCom from "./WeCom.vue"; -import GoogleChat from "./GoogleChat.vue"; -import PagerDuty from "./PagerDuty.vue"; -import Gorush from "./Gorush.vue"; -import Alerta from "./Alerta.vue"; -import OneBot from "./OneBot.vue"; -import PushDeer from "./PushDeer.vue"; /** * Manage all notification form. @@ -40,41 +41,42 @@ import PushDeer from "./PushDeer.vue"; * @type { Record } */ const NotificationFormList = { - "telegram": Telegram, - "webhook": Webhook, - "smtp": STMP, - "discord": Discord, - "teams": Teams, - "signal": Signal, - "gotify": Gotify, - "ntfy": Ntfy, - "slack": Slack, - "rocket.chat": RocketChat, - "pushover": Pushover, - "pushy": Pushy, - "PushByTechulus": TechulusPush, - "octopush": Octopush, - "promosms": PromoSMS, - "clicksendsms": ClickSendSMS, - "lunasea": LunaSea, - "Feishu": Feishu, + "alerta": Alerta, + "AlertNow": AlertNow, "AliyunSMS": AliyunSMS, "apprise": Apprise, - "pushbullet": Pushbullet, - "line": Line, - "mattermost": Mattermost, - "matrix": Matrix, - "DingDing": DingDing, "Bark": Bark, - "serwersms": SerwerSMS, - "stackfield": Stackfield, - "WeCom": WeCom, + "clicksendsms": ClickSendSMS, + "DingDing": DingDing, + "discord": Discord, + "Feishu": Feishu, "GoogleChat": GoogleChat, - "PagerDuty": PagerDuty, "gorush": Gorush, - "alerta": Alerta, + "gotify": Gotify, + "line": Line, + "lunasea": LunaSea, + "matrix": Matrix, + "mattermost": Mattermost, + "ntfy": Ntfy, + "octopush": Octopush, "OneBot": OneBot, + "PagerDuty": PagerDuty, + "promosms": PromoSMS, + "pushbullet": Pushbullet, + "PushByTechulus": TechulusPush, "PushDeer": PushDeer, + "pushover": Pushover, + "pushy": Pushy, + "rocket.chat": RocketChat, + "serwersms": SerwerSMS, + "signal": Signal, + "slack": Slack, + "smtp": STMP, + "stackfield": Stackfield, + "teams": Teams, + "telegram": Telegram, + "webhook": Webhook, + "WeCom": WeCom, }; export default NotificationFormList; From 42848bcd2efdb9ed7f31556738f2eddab1e171b3 Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Wed, 15 Jun 2022 09:00:47 -0500 Subject: [PATCH 03/51] updated translations --- src/languages/bg-BG.js | 1 + src/languages/de-DE.js | 1 + src/languages/en.js | 1 + src/languages/ko-KR.js | 1 + src/languages/pl.js | 1 + src/languages/ru-RU.js | 3 ++- src/languages/uk-UA.js | 3 ++- src/languages/zh-CN.js | 1 + src/languages/zh-TW.js | 1 + src/pages/EditMonitor.vue | 6 +++--- 10 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/languages/bg-BG.js b/src/languages/bg-BG.js index 68297dc28..a6697fa74 100644 --- a/src/languages/bg-BG.js +++ b/src/languages/bg-BG.js @@ -421,6 +421,7 @@ export default { Next: "Следващ", "The slug is already taken. Please choose another slug.": "Този слъг вече се използва. Моля изберете друг.", "No Proxy": "Без прокси", + Authentication: "Удостоверяване", "HTTP Basic Auth": "HTTP основно удостоверяване", "New Status Page": "Нова статус страница", "Page Not Found": "Страницата не е открита", diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js index 77d3962d7..561337524 100644 --- a/src/languages/de-DE.js +++ b/src/languages/de-DE.js @@ -421,6 +421,7 @@ export default { Next: "Weiter", "The slug is already taken. Please choose another slug.": "Der Slug ist bereits in Verwendung. Bitte wähle einen anderen.", "No Proxy": "Kein Proxy", + Authentication: "Authentifizierung", "HTTP Basic Auth": "HTTP Basisauthentifizierung", "New Status Page": "Neue Status-Seite", "Page Not Found": "Seite nicht gefunden", diff --git a/src/languages/en.js b/src/languages/en.js index a8965c114..cbe530f3f 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -438,6 +438,7 @@ export default { Next: "Next", "The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.", "No Proxy": "No Proxy", + Authentication: "Authentication", "HTTP Basic Auth": "HTTP Basic Auth", "New Status Page": "New Status Page", "Page Not Found": "Page Not Found", diff --git a/src/languages/ko-KR.js b/src/languages/ko-KR.js index dd6ed9844..8cf612f94 100644 --- a/src/languages/ko-KR.js +++ b/src/languages/ko-KR.js @@ -438,6 +438,7 @@ export default { Next: "다음", "The slug is already taken. Please choose another slug.": "이미 존재하는 주소에요. 다른 주소를 사용해 주세요.", "No Proxy": "프록시 없음", + Authentication: "인증", "HTTP Basic Auth": "HTTP 인증", "New Status Page": "새로운 상태 페이지", "Page Not Found": "페이지를 찾을 수 없어요", diff --git a/src/languages/pl.js b/src/languages/pl.js index 32b291622..c317d0f94 100644 --- a/src/languages/pl.js +++ b/src/languages/pl.js @@ -428,6 +428,7 @@ export default { Next: "Dalej", "The slug is already taken. Please choose another slug.": "Ten symbol jest już zajęty. Proszę, wybierz inny.", "No Proxy": "Bez proxy", + Authentication: "Uwierzytelnianie", "HTTP Basic Auth": "Podstawowa autoryzacja HTTP", "New Status Page": "Nowa strona statusu", "Page Not Found": "Strona nie została znaleziona", diff --git a/src/languages/ru-RU.js b/src/languages/ru-RU.js index 3becb5901..7001160cd 100644 --- a/src/languages/ru-RU.js +++ b/src/languages/ru-RU.js @@ -351,7 +351,8 @@ export default { "Start or end with a-z 0-9 only": "Начало и окончание имени только на символы: a-z 0-9", "No consecutive dashes --": "Запрещено использовать тире --", "HTTP Options": "HTTP Опции", - "Basic Auth": "HTTP Авторизация", + Authentication: "Аутентификация", + "HTTP Basic Auth": "HTTP Авторизация", PushByTechulus: "Push by Techulus", clicksendsms: "ClickSend SMS", GoogleChat: "Google Chat (только Google Workspace)", diff --git a/src/languages/uk-UA.js b/src/languages/uk-UA.js index 2016ed3a9..75e330295 100644 --- a/src/languages/uk-UA.js +++ b/src/languages/uk-UA.js @@ -350,7 +350,8 @@ export default { "Start or end with a-z 0-9 only": "Початок та закінчення імені лише на символи: a-z 0-9", "No consecutive dashes --": "Заборонено використовувати тире --", "HTTP Options": "HTTP Опції", - "Basic Auth": "HTTP Авторизація", + Authentication: "Аутентифікація", + "HTTP Basic Auth": "HTTP Авторизація", PushByTechulus: "Push by Techulus", clicksendsms: "ClickSend SMS", GoogleChat: "Google Chat (тільки Google Workspace)", diff --git a/src/languages/zh-CN.js b/src/languages/zh-CN.js index 2ea2dfb5d..80e09fc4f 100644 --- a/src/languages/zh-CN.js +++ b/src/languages/zh-CN.js @@ -436,6 +436,7 @@ export default { Next: "下一步", "The slug is already taken. Please choose another slug.": "该路径已被使用。请选择其他路径。", "No Proxy": "无代理", + Authentication: "验证", "HTTP Basic Auth": "HTTP 基础身份验证", "New Status Page": "新的状态页", "Page Not Found": "未找到该页面", diff --git a/src/languages/zh-TW.js b/src/languages/zh-TW.js index 1307b40bf..f7b1abc12 100644 --- a/src/languages/zh-TW.js +++ b/src/languages/zh-TW.js @@ -428,6 +428,7 @@ export default { Next: "下一步", "The slug is already taken. Please choose another slug.": "此 slug 已被使用。請選擇其他 slug。", "No Proxy": "無 Proxy", + Authentication: "驗證", "HTTP Basic Auth": "HTTP 基本驗證", "New Status Page": "新狀態頁", "Page Not Found": "找不到頁面", diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 83ffcfd86..4d39dc9fc 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -369,17 +369,17 @@
-

{{ $t("HTTP Authentication") }}

+

{{ $t("Authentication") }}