From f4611aa570f1e94ff7af55f30f0edfe4c5f03c55 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Sun, 15 Jun 2025 17:43:46 +0800 Subject: [PATCH 1/3] wip --- package-lock.json | 15 ++++++++++++--- package.json | 2 +- .../monitor-types/real-browser-monitor-type.js | 18 +++++++++--------- server/notification.js | 9 ++++----- server/server.js | 2 +- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index ccb72dee3..8c4683e81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "uptime-kuma", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "uptime-kuma", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "license": "MIT", "dependencies": { "@grpc/grpc-js": "~1.8.22", @@ -21,7 +21,7 @@ "check-password-strength": "^2.0.5", "cheerio": "~1.0.0-rc.12", "chroma-js": "~2.4.2", - "command-exists": "~1.2.9", + "command-exists-promise": "~2.0.2", "compare-versions": "~3.6.0", "compression": "~1.7.4", "country-flag-emoji-polyfill": "^0.1.8", @@ -6892,6 +6892,15 @@ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", "license": "MIT" }, + "node_modules/command-exists-promise": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/command-exists-promise/-/command-exists-promise-2.0.2.tgz", + "integrity": "sha512-T6PB6vdFrwnHXg/I0kivM3DqaCGZLjjYSOe0a5WgFKcz1sOnmOeIjnhQPXVXX3QjVbLyTJ85lJkX6lUpukTzaA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", diff --git a/package.json b/package.json index 16837fa8a..46686ef37 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "check-password-strength": "^2.0.5", "cheerio": "~1.0.0-rc.12", "chroma-js": "~2.4.2", - "command-exists": "~1.2.9", + "command-exists-promise": "~2.0.2", "compare-versions": "~3.6.0", "compression": "~1.7.4", "country-flag-emoji-polyfill": "^0.1.8", diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js index 2a2871d2c..8226d9dd0 100644 --- a/server/monitor-types/real-browser-monitor-type.js +++ b/server/monitor-types/real-browser-monitor-type.js @@ -2,7 +2,7 @@ const { MonitorType } = require("./monitor-type"); const { chromium } = require("playwright-core"); const { UP, log } = require("../../src/util"); const { Settings } = require("../settings"); -const commandExistsSync = require("command-exists").sync; +const commandExists = require("command-exists-promise"); const childProcess = require("child_process"); const path = require("path"); const Database = require("../database"); @@ -122,7 +122,7 @@ async function prepareChromeExecutable(executablePath) { executablePath = "/usr/bin/chromium"; // Install chromium in container via apt install - if ( !commandExistsSync(executablePath)) { + if (! await commandExists(executablePath)) { await new Promise((resolve, reject) => { log.info("Chromium", "Installing Chromium..."); let child = childProcess.exec("apt update && apt --yes --no-install-recommends install chromium fonts-indic fonts-noto fonts-noto-cjk"); @@ -146,7 +146,7 @@ async function prepareChromeExecutable(executablePath) { } } else { - executablePath = findChrome(allowedList); + executablePath = await findChrome(allowedList); } } else { // User specified a path @@ -160,20 +160,20 @@ async function prepareChromeExecutable(executablePath) { /** * Find the chrome executable - * @param {any[]} executables Executables to search through - * @returns {any} Executable - * @throws Could not find executable + * @param {string[]} executables Executables to search through + * @returns {Promise} Executable + * @throws Error Could not find executable */ -function findChrome(executables) { +async function findChrome(executables) { // Use the last working executable, so we don't have to search for it again if (lastAutoDetectChromeExecutable) { - if (commandExistsSync(lastAutoDetectChromeExecutable)) { + if (await commandExists(lastAutoDetectChromeExecutable)) { return lastAutoDetectChromeExecutable; } } for (let executable of executables) { - if (commandExistsSync(executable)) { + if (await commandExists(executable)) { lastAutoDetectChromeExecutable = executable; return executable; } diff --git a/server/notification.js b/server/notification.js index fd8c23d67..d80140d76 100644 --- a/server/notification.js +++ b/server/notification.js @@ -259,12 +259,11 @@ class Notification { /** * Check if apprise exists - * @returns {boolean} Does the command apprise exist? + * @returns {Promise} Does the command apprise exist? */ - static checkApprise() { - let commandExistsSync = require("command-exists").sync; - let exists = commandExistsSync("apprise"); - return exists; + static async checkApprise() { + const commandExists = require("command-exists-promise"); + return await commandExists("apprise"); } } diff --git a/server/server.js b/server/server.js index e328ff470..a4d28bb78 100644 --- a/server/server.js +++ b/server/server.js @@ -1490,7 +1490,7 @@ let needSetup = false; socket.on("checkApprise", async (callback) => { try { checkLogin(socket); - callback(Notification.checkApprise()); + callback(await Notification.checkApprise()); } catch (e) { callback(false); } From 1f4622f5f3d7adfb10793b8af1ee35fb5f3ce80c Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Sun, 15 Jun 2025 19:01:55 +0800 Subject: [PATCH 2/3] Rollback "command-exists-promise" as it is not working --- package-lock.json | 11 +---------- package.json | 2 +- .../monitor-types/real-browser-monitor-type.js | 2 +- server/notification.js | 2 +- server/util-server.js | 16 ++++++++++++++++ 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c4683e81..2225d11e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "check-password-strength": "^2.0.5", "cheerio": "~1.0.0-rc.12", "chroma-js": "~2.4.2", - "command-exists-promise": "~2.0.2", + "command-exists": "~1.2.9", "compare-versions": "~3.6.0", "compression": "~1.7.4", "country-flag-emoji-polyfill": "^0.1.8", @@ -6892,15 +6892,6 @@ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", "license": "MIT" }, - "node_modules/command-exists-promise": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/command-exists-promise/-/command-exists-promise-2.0.2.tgz", - "integrity": "sha512-T6PB6vdFrwnHXg/I0kivM3DqaCGZLjjYSOe0a5WgFKcz1sOnmOeIjnhQPXVXX3QjVbLyTJ85lJkX6lUpukTzaA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", diff --git a/package.json b/package.json index 46686ef37..16837fa8a 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "check-password-strength": "^2.0.5", "cheerio": "~1.0.0-rc.12", "chroma-js": "~2.4.2", - "command-exists-promise": "~2.0.2", + "command-exists": "~1.2.9", "compare-versions": "~3.6.0", "compression": "~1.7.4", "country-flag-emoji-polyfill": "^0.1.8", diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js index 8226d9dd0..1491d6c00 100644 --- a/server/monitor-types/real-browser-monitor-type.js +++ b/server/monitor-types/real-browser-monitor-type.js @@ -2,13 +2,13 @@ const { MonitorType } = require("./monitor-type"); const { chromium } = require("playwright-core"); const { UP, log } = require("../../src/util"); const { Settings } = require("../settings"); -const commandExists = require("command-exists-promise"); const childProcess = require("child_process"); const path = require("path"); const Database = require("../database"); const jwt = require("jsonwebtoken"); const config = require("../config"); const { RemoteBrowser } = require("../remote-browser"); +const { commandExists } = require("../util-server"); /** * Cached instance of a browser diff --git a/server/notification.js b/server/notification.js index d80140d76..4e9c9c4db 100644 --- a/server/notification.js +++ b/server/notification.js @@ -77,6 +77,7 @@ const SendGrid = require("./notification-providers/send-grid"); const YZJ = require("./notification-providers/yzj"); const SMSPlanet = require("./notification-providers/sms-planet"); const SpugPush = require("./notification-providers/spugpush"); +const { commandExists } = require("./util-server"); class Notification { @@ -262,7 +263,6 @@ class Notification { * @returns {Promise} Does the command apprise exist? */ static async checkApprise() { - const commandExists = require("command-exists-promise"); return await commandExists("apprise"); } diff --git a/server/util-server.js b/server/util-server.js index 08df728ed..e54a01d63 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1096,3 +1096,19 @@ module.exports.axiosAbortSignal = (timeoutMs) => { } } }; + +/** + * By default, command-exists will throw a null error if the command does not exist, which is ugly. The function makes it better. + * Read more: https://github.com/mathisonian/command-exists/issues/22 + * @param {string} command Command to check + * @returns {Promise} True if command exists, false otherwise + */ +async function commandExists(command) { + try { + await require("command-exists")(command); + return true; + } catch (e) { + return false; + } +} +module.exports.commandExists = commandExists; From 69a6112d8d8d8b010032d03d082e192f9ce8b619 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Sun, 15 Jun 2025 19:09:27 +0800 Subject: [PATCH 3/3] Minor --- server/monitor-types/real-browser-monitor-type.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js index 1491d6c00..07b6c8aac 100644 --- a/server/monitor-types/real-browser-monitor-type.js +++ b/server/monitor-types/real-browser-monitor-type.js @@ -162,7 +162,7 @@ async function prepareChromeExecutable(executablePath) { * Find the chrome executable * @param {string[]} executables Executables to search through * @returns {Promise} Executable - * @throws Error Could not find executable + * @throws {Error} Could not find executable */ async function findChrome(executables) { // Use the last working executable, so we don't have to search for it again