diff --git a/db/patch-monitor-basic-auth.sql b/db/patch-monitor-basic-auth.sql new file mode 100644 index 000000000..de4bdefd9 --- /dev/null +++ b/db/patch-monitor-basic-auth.sql @@ -0,0 +1,10 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE monitor + ADD basic_auth_user TEXT default null; + +ALTER TABLE monitor + ADD basic_auth_pass TEXT default null; + +COMMIT; diff --git a/server/database.js b/server/database.js index fbef40bb1..afcace705 100644 --- a/server/database.js +++ b/server/database.js @@ -52,6 +52,7 @@ class Database { "patch-http-monitor-method-body-and-headers.sql": true, "patch-2fa-invalidate-used-token.sql": true, "patch-notification_sent_history.sql": true, + "patch-monitor-basic-auth.sql": true, } /** diff --git a/server/model/monitor.js b/server/model/monitor.js index 980e0ac69..ab0c1d409 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -58,6 +58,8 @@ class Monitor extends BeanModel { method: this.method, body: this.body, headers: this.headers, + basic_auth_user: this.basic_auth_user, + basic_auth_pass: this.basic_auth_pass, hostname: this.hostname, port: this.port, maxretries: this.maxretries, @@ -80,6 +82,15 @@ class Monitor extends BeanModel { }; } + /** + * Encode user and password to Base64 encoding + * for HTTP "basic" auth, as per RFC-7617 + * @returns {string} + */ + encodeBase64(user, pass) { + return Buffer.from(user + ":" + pass).toString("base64"); + } + /** * Parse to boolean * @returns {boolean} @@ -141,7 +152,16 @@ class Monitor extends BeanModel { // Do not do any queries/high loading things before the "bean.ping" let startTime = dayjs().valueOf(); + // HTTP basic auth + let basicAuthHeader = {}; + if (this.basic_auth_user) { + basicAuthHeader = { + "Authorization": "Basic " + this.encodeBase64(this.basic_auth_user, this.basic_auth_pass), + }; + } + debug(`[${this.name}] Prepare Options for axios`); + const options = { url: this.url, method: (this.method || "get").toLowerCase(), @@ -151,6 +171,7 @@ class Monitor extends BeanModel { "Accept": "*/*", "User-Agent": "Uptime-Kuma/" + version, ...(this.headers ? JSON.parse(this.headers) : {}), + ...(basicAuthHeader), }, httpsAgent: new https.Agent({ maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) diff --git a/server/server.js b/server/server.js index 07249fb44..868bbd5ef 100644 --- a/server/server.js +++ b/server/server.js @@ -573,6 +573,8 @@ exports.entryPage = "dashboard"; bean.method = monitor.method; bean.body = monitor.body; bean.headers = monitor.headers; + bean.basic_auth_user = monitor.basic_auth_user; + bean.basic_auth_pass = monitor.basic_auth_pass; bean.interval = monitor.interval; bean.retryInterval = monitor.retryInterval; bean.hostname = monitor.hostname; @@ -1137,6 +1139,8 @@ exports.entryPage = "dashboard"; method: monitorListData[i].method || "GET", body: monitorListData[i].body, headers: monitorListData[i].headers, + basic_auth_user: monitorListData[i].basic_auth_user, + basic_auth_pass: monitorListData[i].basic_auth_pass, interval: monitorListData[i].interval, retryInterval: retryInterval, hostname: monitorListData[i].hostname, diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 11be3ed5b..399641e9b 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -265,6 +265,19 @@ + + +

{{ $t("HTTP Basic Auth") }}

+ +
+ + +
+ +
+ + +