Merge pull request #864 from ivanbratovic/http-basicauth

Implement explicit HTTP "basic" authentication support
This commit is contained in:
Louis Lam 2021-11-23 22:48:54 +08:00 committed by GitHub
commit 92a5f18bf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 0 deletions

View File

@ -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;

View File

@ -52,6 +52,7 @@ class Database {
"patch-http-monitor-method-body-and-headers.sql": true, "patch-http-monitor-method-body-and-headers.sql": true,
"patch-2fa-invalidate-used-token.sql": true, "patch-2fa-invalidate-used-token.sql": true,
"patch-notification_sent_history.sql": true, "patch-notification_sent_history.sql": true,
"patch-monitor-basic-auth.sql": true,
} }
/** /**

View File

@ -58,6 +58,8 @@ class Monitor extends BeanModel {
method: this.method, method: this.method,
body: this.body, body: this.body,
headers: this.headers, headers: this.headers,
basic_auth_user: this.basic_auth_user,
basic_auth_pass: this.basic_auth_pass,
hostname: this.hostname, hostname: this.hostname,
port: this.port, port: this.port,
maxretries: this.maxretries, 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 * Parse to boolean
* @returns {boolean} * @returns {boolean}
@ -141,7 +152,16 @@ class Monitor extends BeanModel {
// Do not do any queries/high loading things before the "bean.ping" // Do not do any queries/high loading things before the "bean.ping"
let startTime = dayjs().valueOf(); 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`); debug(`[${this.name}] Prepare Options for axios`);
const options = { const options = {
url: this.url, url: this.url,
method: (this.method || "get").toLowerCase(), method: (this.method || "get").toLowerCase(),
@ -151,6 +171,7 @@ class Monitor extends BeanModel {
"Accept": "*/*", "Accept": "*/*",
"User-Agent": "Uptime-Kuma/" + version, "User-Agent": "Uptime-Kuma/" + version,
...(this.headers ? JSON.parse(this.headers) : {}), ...(this.headers ? JSON.parse(this.headers) : {}),
...(basicAuthHeader),
}, },
httpsAgent: new https.Agent({ httpsAgent: new https.Agent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)

View File

@ -573,6 +573,8 @@ exports.entryPage = "dashboard";
bean.method = monitor.method; bean.method = monitor.method;
bean.body = monitor.body; bean.body = monitor.body;
bean.headers = monitor.headers; 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.interval = monitor.interval;
bean.retryInterval = monitor.retryInterval; bean.retryInterval = monitor.retryInterval;
bean.hostname = monitor.hostname; bean.hostname = monitor.hostname;
@ -1137,6 +1139,8 @@ exports.entryPage = "dashboard";
method: monitorListData[i].method || "GET", method: monitorListData[i].method || "GET",
body: monitorListData[i].body, body: monitorListData[i].body,
headers: monitorListData[i].headers, headers: monitorListData[i].headers,
basic_auth_user: monitorListData[i].basic_auth_user,
basic_auth_pass: monitorListData[i].basic_auth_pass,
interval: monitorListData[i].interval, interval: monitorListData[i].interval,
retryInterval: retryInterval, retryInterval: retryInterval,
hostname: monitorListData[i].hostname, hostname: monitorListData[i].hostname,

View File

@ -265,6 +265,19 @@
<label for="headers" class="form-label">{{ $t("Headers") }}</label> <label for="headers" class="form-label">{{ $t("Headers") }}</label>
<textarea id="headers" v-model="monitor.headers" class="form-control" :placeholder="headersPlaceholder"></textarea> <textarea id="headers" v-model="monitor.headers" class="form-control" :placeholder="headersPlaceholder"></textarea>
</div> </div>
<!-- HTTP Basic Auth -->
<h4 class="mt-5 mb-2">{{ $t("HTTP Basic Auth") }}</h4>
<div class="my-3">
<label for="basicauth" class="form-label">{{ $t("Username") }}</label>
<input id="basicauth-user" v-model="monitor.basic_auth_user" type="text" class="form-control" :placeholder="$t('Username')">
</div>
<div class="my-3">
<label for="basicauth" class="form-label">{{ $t("Password") }}</label>
<input id="basicauth-pass" v-model="monitor.basic_auth_pass" type="password" class="form-control" :placeholder="$t('Password')">
</div>
</template> </template>
</div> </div>
</div> </div>