diff --git a/server/docker.js b/server/docker.js index a96324a9fa..5812151270 100644 --- a/server/docker.js +++ b/server/docker.js @@ -1,6 +1,5 @@ const axios = require("axios"); const { R } = require("redbean-node"); -const version = require("../package.json").version; const https = require("https"); const fs = require("fs"); const path = require("path"); diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js index 4003c68eba..ab0b2b9f50 100644 --- a/server/monitor-types/real-browser-monitor-type.js +++ b/server/monitor-types/real-browser-monitor-type.js @@ -33,7 +33,6 @@ if (process.platform === "win32") { allowedList.push(drive + ":\\Program Files\\Google\\Chrome\\Application\\chrome.exe"); allowedList.push(drive + ":\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"); } - } else if (process.platform === "linux") { allowedList = [ "chromium", @@ -233,8 +232,76 @@ class RealBrowserMonitorType extends MonitorType { } } +class RealBrowserKeywordMonitorType extends MonitorType { + name = "real-browser-keyword"; + + /** + * @inheritdoc + */ + async check(monitor, heartbeat, server) { + const browser = await getBrowser(); + const context = await browser.newContext(); + const page = await context.newPage(); + + const res = await page.goto(monitor.url, { + waitUntil: "networkidle", + timeout: monitor.interval * 1000 * 0.8, + }); + + let content = await page.content(); + + //Add iFrame Support + const pageFrames = await page.frames(); + for (let index = 0; index < pageFrames.length; index++) { + const element = pageFrames[index]; + content += await element.content(); + } + + //LATER - Make screenshot an option. + let filename = jwt.sign(monitor.id, server.jwtSecret) + ".png"; + + await page.screenshot({ + path: path.join(Database.screenshotDir, filename), + }); + + await context.close(); + + if (res.status() >= 200 && res.status() < 400) { + let status = UP; + let msg = res.status(); + let keywordFound = content.includes(monitor.keyword); + if (keywordFound === !Boolean(monitor.invertKeyword)) { + msg += ", keyword " + (keywordFound ? "is" : "not") + " found"; + status = UP; + } else { + content = content.replace(/<[^>]*>?|[\n\r]|\s+/gm, " ").trim(); + if (content.length > 50) { + content = content.substring(0, 47) + "..."; + } + throw new Error( + msg + + ", but keyword is " + + (keywordFound ? "present" : "not") + + " in [" + + content + + "]" + ); + } + + heartbeat.status = status; + heartbeat.msg = msg; + + const timing = res.request().timing(); + heartbeat.ping = timing.responseEnd; + } else { + throw new Error(res.status() + ""); + } + } +} + module.exports = { RealBrowserMonitorType, + RealBrowserKeywordMonitorType, testChrome, resetChrome, }; diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js index 1673a60128..6c955faeec 100644 --- a/server/uptime-kuma-server.js +++ b/server/uptime-kuma-server.js @@ -52,9 +52,7 @@ class UptimeKumaServer { /** * @type {{}} */ - static monitorTypeList = { - - }; + static monitorTypeList = {}; /** * Use for decode the auth object @@ -118,6 +116,7 @@ class UptimeKumaServer { // Set Monitor Types UptimeKumaServer.monitorTypeList["real-browser"] = new RealBrowserMonitorType(); + UptimeKumaServer.monitorTypeList["real-browser-keyword"] = new RealBrowserKeywordMonitorType(); UptimeKumaServer.monitorTypeList["tailscale-ping"] = new TailscalePing(); UptimeKumaServer.monitorTypeList["dns"] = new DnsMonitorType(); @@ -462,6 +461,7 @@ class UptimeKumaServer { /** * Check if monitors are running properly + * @returns {Promise} */ async checkMonitors() { log.debug("monitor_checker", "Checking monitors"); @@ -498,7 +498,6 @@ class UptimeKumaServer { } else { //log.debug("monitor_checker", "Monitor " + monitorID + " is not started yet, skipp"); } - } log.debug("monitor_checker", "Checking monitors end"); @@ -518,6 +517,6 @@ module.exports = { }; // Must be at the end to avoid circular dependencies -const { RealBrowserMonitorType } = require("./monitor-types/real-browser-monitor-type"); +const { RealBrowserMonitorType, RealBrowserKeywordMonitorType } = require("./monitor-types/real-browser-monitor-type"); const { TailscalePing } = require("./monitor-types/tailscale-ping"); const { DnsMonitorType } = require("./monitor-types/dns"); diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 4b82bdf67c..c39683686f 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -43,6 +43,11 @@ + @@ -100,7 +105,7 @@ -
+
@@ -125,7 +130,7 @@
-
+
@@ -134,7 +139,7 @@
-
+