diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 69f98c0e4..2e10be48c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
# Project Info
-First of all, I want to thank everyone who have wrote issues or shared pull requests for Uptime Kuma.
+First of all, I want to thank everyone who has submitted issues or shared pull requests for Uptime Kuma.
I never thought the GitHub community would be so nice!
Because of this, I also never thought that other people would actually read and edit my code.
Parts of the code are not very well-structured or commented, sorry about that.
@@ -9,7 +9,7 @@ The project was created with `vite.js` and is written in `vue3`.
Our backend lives in the `server`-directory and mostly communicates via websockets.
Both frontend and backend share the same `package.json`.
-For production, the frontend is build into `dist`-directory and the server (`express.js`) exposes the `dist` directory as the root of the endpoint.
+For production, the frontend is built into the `dist`-directory and the server (`express.js`) exposes the `dist` directory as the root of the endpoint.
For development, we run vite in development mode on another port.
## Directories
@@ -28,7 +28,7 @@ For development, we run vite in development mode on another port.
## Can I create a pull request for Uptime Kuma?
Yes or no, it depends on what you will try to do.
-Both your and our maintainers time is precious, and we don't want to waste both time.
+Both yours and our maintainers' time is precious, and we don't want to waste either.
If you have any questions about any process/.. is not clear, you are likely not alone => please ask them ^^
@@ -49,11 +49,11 @@ Different guidelines exist for different types of pull requests (PRs):
If you come across a bug and think you can solve, we appreciate your work.
- Please make sure that you follow by these rules:
+ Please make sure that you follow these rules:
- keep the PR as small as possible, fix only one thing at a time => keeping it reviewable
- - test that your code does what you came it does.
+ - test that your code does what you claim it does.
- Because maintainer time is precious junior maintainers may merge uncontroversial PRs in this area.
+ Because maintainer time is precious, junior maintainers may merge uncontroversial PRs in this area.
- translations / internationalisation (i18n)
@@ -68,7 +68,7 @@ Different guidelines exist for different types of pull requests (PRs):
- language keys need to be **added to `en.json`** to be visible in weblate. If this has not happened, a PR is appreciated.
- **Adding a new language** requires a new file see [these instructions](https://github.com/louislam/uptime-kuma/blob/master/src/lang/README.md)
- Because maintainer time is precious junior maintainers may merge uncontroversial PRs in this area.
+ Because maintainer time is precious, junior maintainers may merge uncontroversial PRs in this area.
- new notification providers
@@ -102,7 +102,7 @@ Different guidelines exist for different types of pull requests (PRs):
Therefore, making sure that they work is also really important.
Because testing notification providers is quite time intensive, we mostly offload this onto the person contributing a notification provider.
- To make shure you have tested the notification provider, please include screenshots of the following events in the pull-request description:
+ To make sure you have tested the notification provider, please include screenshots of the following events in the pull-request description:
- `UP`/`DOWN`
- Certificate Expiry via https://expired.badssl.com/
- Testing (the test button on the notification provider setup page)
@@ -117,7 +117,7 @@ Different guidelines exist for different types of pull requests (PRs):
| Testing | paste-image-here | paste-image-here |
```
- Because maintainer time is precious junior maintainers may merge uncontroversial PRs in this area.
+ Because maintainer time is precious, junior maintainers may merge uncontroversial PRs in this area.
- new monitoring types
@@ -138,14 +138,14 @@ Different guidelines exist for different types of pull requests (PRs):
-
- Because maintainer time is precious junior maintainers may merge uncontroversial PRs in this area.
+ Because maintainer time is precious, junior maintainers may merge uncontroversial PRs in this area.
- new features/ major changes / breaking bugfixes
be sure to **create an empty draft pull request or open an issue, so we can have a discussion first**.
- This is especially important for a large pull request or you don't know if it will be merged or not.
+ This is especially important for a large pull request or when you don't know if it will be merged or not.
Because of the large impact of this work, only senior maintainers may merge PRs in this area.
@@ -201,7 +201,7 @@ The rationale behind this is that we can align the direction and scope of the fe
## Project Styles
-I personally do not like something that requires so many configurations before you can finally start the app.
+I personally do not like something that requires a lot of configuration before you can finally start the app.
The goal is to make the Uptime Kuma installation as easy as installing a mobile app.
- Easy to install for non-Docker users
@@ -260,7 +260,7 @@ Port `3000` and port `3001` will be used.
npm run dev
```
-But sometimes, you would like to restart the server, but not the frontend, you can run these commands in two terminals:
+But sometimes you may want to restart the server without restarting the frontend. In that case, you can run these commands in two terminals:
```bash
npm run start-frontend-dev
@@ -409,7 +409,7 @@ https://github.com/louislam/uptime-kuma/issues?q=sort%3Aupdated-desc
### What is a maintainer and what are their roles?
-This project has multiple maintainers which specialise in different areas.
+This project has multiple maintainers who specialise in different areas.
Currently, there are 3 maintainers:
| Person | Role | Main Area |
diff --git a/server/auth.js b/server/auth.js
index 36316241c..597cf3d75 100644
--- a/server/auth.js
+++ b/server/auth.js
@@ -1,6 +1,7 @@
const basicAuth = require("express-basic-auth");
const passwordHash = require("./password-hash");
const { R } = require("redbean-node");
+const { setting } = require("./util-server");
const { log } = require("../src/util");
const { loginRateLimiter, apiRateLimiter } = require("./rate-limiter");
const { Settings } = require("./settings");
@@ -138,7 +139,7 @@ exports.basicAuth = async function (req, res, next) {
challenge: true,
});
- const disabledAuth = await Settings.get("disableAuth");
+ const disabledAuth = await setting("disableAuth");
if (!disabledAuth) {
middleware(req, res, next);
diff --git a/server/check-version.js b/server/check-version.js
index 154ebe373..c6d5cfb92 100644
--- a/server/check-version.js
+++ b/server/check-version.js
@@ -1,7 +1,7 @@
+const { setSetting, setting } = require("./util-server");
const axios = require("axios");
const compareVersions = require("compare-versions");
const { log } = require("../src/util");
-const { Settings } = require("./settings");
exports.version = require("../package.json").version;
exports.latestVersion = null;
@@ -14,7 +14,7 @@ let interval;
exports.startInterval = () => {
let check = async () => {
- if (await Settings.get("checkUpdate") === false) {
+ if (await setting("checkUpdate") === false) {
return;
}
@@ -28,7 +28,7 @@ exports.startInterval = () => {
res.data.slow = "1000.0.0";
}
- let checkBeta = await Settings.get("checkBeta");
+ let checkBeta = await setting("checkBeta");
if (checkBeta && res.data.beta) {
if (compareVersions.compare(res.data.beta, res.data.slow, ">")) {
@@ -57,7 +57,7 @@ exports.startInterval = () => {
* @returns {Promise}
*/
exports.enableCheckUpdate = async (value) => {
- await Settings.set("checkUpdate", value);
+ await setSetting("checkUpdate", value);
clearInterval(interval);
diff --git a/server/client.js b/server/client.js
index 6929f81aa..72f0a4e8e 100644
--- a/server/client.js
+++ b/server/client.js
@@ -6,8 +6,8 @@ const { R } = require("redbean-node");
const { UptimeKumaServer } = require("./uptime-kuma-server");
const server = UptimeKumaServer.getInstance();
const io = server.io;
+const { setting } = require("./util-server");
const checkVersion = require("./check-version");
-const { Settings } = require("./settings");
const Database = require("./database");
/**
@@ -158,8 +158,8 @@ async function sendInfo(socket, hideVersion = false) {
version,
latestVersion,
isContainer,
- primaryBaseURL: await Settings.get("primaryBaseURL"),
dbType,
+ primaryBaseURL: await setting("primaryBaseURL"),
serverTimezone: await server.getTimezone(),
serverTimezoneOffset: server.getTimezoneOffset(),
});
diff --git a/server/database.js b/server/database.js
index 46e6ecaf3..3374aff9e 100644
--- a/server/database.js
+++ b/server/database.js
@@ -1,11 +1,11 @@
const fs = require("fs");
const { R } = require("redbean-node");
+const { setSetting, setting } = require("./util-server");
const { log, sleep } = require("../src/util");
const knex = require("knex");
const path = require("path");
const { EmbeddedMariaDB } = require("./embedded-mariadb");
const mysql = require("mysql2/promise");
-const { Settings } = require("./settings");
/**
* Database & App Data Folder
@@ -420,7 +420,7 @@ class Database {
* @deprecated
*/
static async patchSqlite() {
- let version = parseInt(await Settings.get("database_version"));
+ let version = parseInt(await setting("database_version"));
if (! version) {
version = 0;
@@ -445,7 +445,7 @@ class Database {
log.info("db", `Patching ${sqlFile}`);
await Database.importSQLFile(sqlFile);
log.info("db", `Patched ${sqlFile}`);
- await Settings.set("database_version", i);
+ await setSetting("database_version", i);
}
} catch (ex) {
await Database.close();
@@ -471,7 +471,7 @@ class Database {
*/
static async patchSqlite2() {
log.debug("db", "Database Patch 2.0 Process");
- let databasePatchedFiles = await Settings.get("databasePatchedFiles");
+ let databasePatchedFiles = await setting("databasePatchedFiles");
if (! databasePatchedFiles) {
databasePatchedFiles = {};
@@ -499,7 +499,7 @@ class Database {
process.exit(1);
}
- await Settings.set("databasePatchedFiles", databasePatchedFiles);
+ await setSetting("databasePatchedFiles", databasePatchedFiles);
}
/**
@@ -512,27 +512,27 @@ class Database {
// Fix 1.13.0 empty slug bug
await R.exec("UPDATE status_page SET slug = 'empty-slug-recover' WHERE TRIM(slug) = ''");
- let title = await Settings.get("title");
+ let title = await setting("title");
if (title) {
- log.info("database", "Migrating Status Page");
+ console.log("Migrating Status Page");
let statusPageCheck = await R.findOne("status_page", " slug = 'default' ");
if (statusPageCheck !== null) {
- log.info("database", "Migrating Status Page - Skip, default slug record is already existing");
+ console.log("Migrating Status Page - Skip, default slug record is already existing");
return;
}
let statusPage = R.dispense("status_page");
statusPage.slug = "default";
statusPage.title = title;
- statusPage.description = await Settings.get("description");
- statusPage.icon = await Settings.get("icon");
- statusPage.theme = await Settings.get("statusPageTheme");
- statusPage.published = !!await Settings.get("statusPagePublished");
- statusPage.search_engine_index = !!await Settings.get("searchEngineIndex");
- statusPage.show_tags = !!await Settings.get("statusPageTags");
+ statusPage.description = await setting("description");
+ statusPage.icon = await setting("icon");
+ statusPage.theme = await setting("statusPageTheme");
+ statusPage.published = !!await setting("statusPagePublished");
+ statusPage.search_engine_index = !!await setting("searchEngineIndex");
+ statusPage.show_tags = !!await setting("statusPageTags");
statusPage.password = null;
if (!statusPage.title) {
@@ -560,13 +560,13 @@ class Database {
await R.exec("DELETE FROM setting WHERE type = 'statusPage'");
// Migrate Entry Page if it is status page
- let entryPage = await Settings.get("entryPage");
+ let entryPage = await setting("entryPage");
if (entryPage === "statusPage") {
- await Settings.set("entryPage", "statusPage-default", "general");
+ await setSetting("entryPage", "statusPage-default", "general");
}
- log.info("database", "Migrating Status Page - Done");
+ console.log("Migrating Status Page - Done");
}
}
diff --git a/server/jobs/clear-old-data.js b/server/jobs/clear-old-data.js
index b3a1676dc..248a4d409 100644
--- a/server/jobs/clear-old-data.js
+++ b/server/jobs/clear-old-data.js
@@ -1,7 +1,7 @@
const { R } = require("redbean-node");
const { log } = require("../../src/util");
+const { setSetting, setting } = require("../util-server");
const Database = require("../database");
-const { Settings } = require("../settings");
const DEFAULT_KEEP_PERIOD = 180;
@@ -11,11 +11,11 @@ const DEFAULT_KEEP_PERIOD = 180;
*/
const clearOldData = async () => {
- let period = await Settings.get("keepDataPeriodDays");
+ let period = await setting("keepDataPeriodDays");
// Set Default Period
if (period == null) {
- await Settings.set("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general");
+ await setSetting("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general");
period = DEFAULT_KEEP_PERIOD;
}
@@ -25,7 +25,7 @@ const clearOldData = async () => {
parsedPeriod = parseInt(period);
} catch (_) {
log.warn("clearOldData", "Failed to parse setting, resetting to default..");
- await Settings.set("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general");
+ await setSetting("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general");
parsedPeriod = DEFAULT_KEEP_PERIOD;
}
diff --git a/server/model/monitor.js b/server/model/monitor.js
index 78485c4c5..5b7e5871a 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -4,7 +4,7 @@ const { Prometheus } = require("../prometheus");
const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND,
SQL_DATETIME_FORMAT, evaluateJsonQuery
} = require("../../src/util");
-const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, mssqlQuery, postgresQuery, mysqlQuery, httpNtlm, radius, grpcQuery,
+const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, setSetting, httpNtlm, radius, grpcQuery,
redisPingAsync, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal
} = require("../util-server");
const { R } = require("redbean-node");
@@ -24,7 +24,6 @@ const { CookieJar } = require("tough-cookie");
const { HttpsCookieAgent } = require("http-cookie-agent/http");
const https = require("https");
const http = require("http");
-const { Settings } = require("../settings");
const rootCertificates = rootCertificatesFingerprints();
@@ -326,7 +325,7 @@ class Monitor extends BeanModel {
let previousBeat = null;
let retries = 0;
- this.prometheus = await Prometheus.createAndInitMetrics(this);
+ this.prometheus = new Prometheus(this);
const beat = async () => {
@@ -652,7 +651,7 @@ class Monitor extends BeanModel {
} else if (this.type === "steam") {
const steamApiUrl = "https://api.steampowered.com/IGameServersService/GetServerList/v1/";
- const steamAPIKey = await Settings.get("steamAPIKey");
+ const steamAPIKey = await setting("steamAPIKey");
const filter = `addr\\${this.hostname}:${this.port}`;
if (!steamAPIKey) {
@@ -978,7 +977,7 @@ class Monitor extends BeanModel {
await R.store(bean);
log.debug("monitor", `[${this.name}] prometheus.update`);
- await this.prometheus?.update(bean, tlsInfo);
+ this.prometheus?.update(bean, tlsInfo);
previousBeat = bean;
@@ -1374,12 +1373,11 @@ class Monitor extends BeanModel {
return;
}
- let notifyDays = await Settings.get("tlsExpiryNotifyDays");
+ let notifyDays = await setting("tlsExpiryNotifyDays");
if (notifyDays == null || !Array.isArray(notifyDays)) {
// Reset Default
- await Settings.set("tlsExpiryNotifyDays", [ 7, 14, 21 ], "general");
+ await setSetting("tlsExpiryNotifyDays", [ 7, 14, 21 ], "general");
notifyDays = [ 7, 14, 21 ];
- await Settings.set("tlsExpiryNotifyDays", notifyDays, "general");
}
if (Array.isArray(notifyDays)) {
diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js
index 804fa93ed..41930b24d 100644
--- a/server/modules/apicache/apicache.js
+++ b/server/modules/apicache/apicache.js
@@ -1,6 +1,5 @@
let url = require("url");
let MemoryCache = require("./memory-cache");
-const { log } = require("../../../src/util");
let t = {
ms: 1,
@@ -91,6 +90,24 @@ function ApiCache() {
instances.push(this);
this.id = instances.length;
+ /**
+ * Logs a message to the console if the `DEBUG` environment variable is set.
+ * @param {string} a The first argument to log.
+ * @param {string} b The second argument to log.
+ * @param {string} c The third argument to log.
+ * @param {string} d The fourth argument to log, and so on... (optional)
+ *
+ * Generated by Trelent
+ */
+ function debug(a, b, c, d) {
+ let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) {
+ return arg !== undefined;
+ });
+ let debugEnv = process.env.DEBUG && process.env.DEBUG.split(",").indexOf("apicache") !== -1;
+
+ return (globalOptions.debug || debugEnv) && console.log.apply(null, arr);
+ }
+
/**
* Returns true if the given request and response should be logged.
* @param {Object} request The HTTP request object.
@@ -129,7 +146,7 @@ function ApiCache() {
let groupName = req.apicacheGroup;
if (groupName) {
- log.debug("apicache", `group detected "${groupName}"`);
+ debug("group detected \"" + groupName + "\"");
let group = (index.groups[groupName] = index.groups[groupName] || []);
group.unshift(key);
}
@@ -195,7 +212,7 @@ function ApiCache() {
redis.hset(key, "duration", duration);
redis.expire(key, duration / 1000, expireCallback || function () {});
} catch (err) {
- log.debug("apicache", `error in redis.hset(): ${err}`);
+ debug("[apicache] error in redis.hset()");
}
} else {
memCache.add(key, value, duration, expireCallback);
@@ -303,10 +320,10 @@ function ApiCache() {
// display log entry
let elapsed = new Date() - req.apicacheTimer;
- log.debug("apicache", `adding cache entry for "${key}" @ ${strDuration} ${logDuration(elapsed)}`);
- log.debug("apicache", `_apicache.headers: ${JSON.stringify(res._apicache.headers)}`);
- log.debug("apicache", `res.getHeaders(): ${JSON.stringify(getSafeHeaders(res))}`);
- log.debug("apicache", `cacheObject: ${JSON.stringify(cacheObject)}`);
+ debug("adding cache entry for \"" + key + "\" @ " + strDuration, logDuration(elapsed));
+ debug("_apicache.headers: ", res._apicache.headers);
+ debug("res.getHeaders(): ", getSafeHeaders(res));
+ debug("cacheObject: ", cacheObject);
}
}
@@ -385,10 +402,10 @@ function ApiCache() {
let redis = globalOptions.redisClient;
if (group) {
- log.debug("apicache", `clearing group "${target}"`);
+ debug("clearing group \"" + target + "\"");
group.forEach(function (key) {
- log.debug("apicache", `clearing cached entry for "${key}"`);
+ debug("clearing cached entry for \"" + key + "\"");
clearTimeout(timers[key]);
delete timers[key];
if (!globalOptions.redisClient) {
@@ -397,7 +414,7 @@ function ApiCache() {
try {
redis.del(key);
} catch (err) {
- log.info("apicache", "error in redis.del(\"" + key + "\")");
+ console.log("[apicache] error in redis.del(\"" + key + "\")");
}
}
index.all = index.all.filter(doesntMatch(key));
@@ -405,7 +422,7 @@ function ApiCache() {
delete index.groups[target];
} else if (target) {
- log.debug("apicache", `clearing ${isAutomatic ? "expired" : "cached"} entry for "${target}"`);
+ debug("clearing " + (isAutomatic ? "expired" : "cached") + " entry for \"" + target + "\"");
clearTimeout(timers[target]);
delete timers[target];
// clear actual cached entry
@@ -415,7 +432,7 @@ function ApiCache() {
try {
redis.del(target);
} catch (err) {
- log.error("apicache", "error in redis.del(\"" + target + "\")");
+ console.log("[apicache] error in redis.del(\"" + target + "\")");
}
}
@@ -432,7 +449,7 @@ function ApiCache() {
}
});
} else {
- log.debug("apicache", "clearing entire index");
+ debug("clearing entire index");
if (!redis) {
memCache.clear();
@@ -444,7 +461,7 @@ function ApiCache() {
try {
redis.del(key);
} catch (err) {
- log.error("apicache", `error in redis.del("${key}"): ${err}`);
+ console.log("[apicache] error in redis.del(\"" + key + "\")");
}
});
}
@@ -511,7 +528,7 @@ function ApiCache() {
/**
* Get index of a group
- * @param {string} group
+ * @param {string} group
* @returns {number}
*/
this.getIndex = function (group) {
@@ -526,9 +543,9 @@ function ApiCache() {
* Express middleware
* @param {(string|number)} strDuration Duration to cache responses
* for.
- * @param {function(Object, Object):boolean} middlewareToggle
+ * @param {function(Object, Object):boolean} middlewareToggle
* @param {Object} localOptions Options for APICache
- * @returns
+ * @returns
*/
this.middleware = function cache(strDuration, middlewareToggle, localOptions) {
let duration = instance.getDuration(strDuration);
@@ -735,7 +752,7 @@ function ApiCache() {
*/
let cache = function (req, res, next) {
function bypass() {
- log.debug("apicache", "bypass detected, skipping cache.");
+ debug("bypass detected, skipping cache.");
return next();
}
@@ -788,7 +805,7 @@ function ApiCache() {
// send if cache hit from memory-cache
if (cached) {
let elapsed = new Date() - req.apicacheTimer;
- log.debug("apicache", `sending cached (memory-cache) version of ${key} ${logDuration(elapsed)}`);
+ debug("sending cached (memory-cache) version of", key, logDuration(elapsed));
perf.hit(key);
return sendCachedResponse(req, res, cached, middlewareToggle, next, duration);
@@ -800,7 +817,7 @@ function ApiCache() {
redis.hgetall(key, function (err, obj) {
if (!err && obj && obj.response) {
let elapsed = new Date() - req.apicacheTimer;
- log.debug("apicache", "sending cached (redis) version of "+ key+" "+ logDuration(elapsed));
+ debug("sending cached (redis) version of", key, logDuration(elapsed));
perf.hit(key);
return sendCachedResponse(
@@ -842,7 +859,7 @@ function ApiCache() {
/**
* Process options
- * @param {Object} options
+ * @param {Object} options
* @returns {Object}
*/
this.options = function (options) {
@@ -856,7 +873,7 @@ function ApiCache() {
}
if (globalOptions.trackPerformance) {
- log.debug("apicache", "WARNING: using trackPerformance flag can cause high memory usage!");
+ debug("WARNING: using trackPerformance flag can cause high memory usage!");
}
return this;
diff --git a/server/monitor-types/real-browser-monitor-type.js b/server/monitor-types/real-browser-monitor-type.js
index ce3abcb2d..f1219af18 100644
--- a/server/monitor-types/real-browser-monitor-type.js
+++ b/server/monitor-types/real-browser-monitor-type.js
@@ -63,7 +63,7 @@ if (process.platform === "win32") {
* @returns {Promise} The executable is allowed?
*/
async function isAllowedChromeExecutable(executablePath) {
- log.info("Chromium", config.args);
+ console.log(config.args);
if (config.args["allow-all-chrome-exec"] || process.env.UPTIME_KUMA_ALLOW_ALL_CHROME_EXEC === "1") {
return true;
}
@@ -102,8 +102,7 @@ async function getBrowser() {
*/
async function getRemoteBrowser(remoteBrowserID, userId) {
let remoteBrowser = await RemoteBrowser.get(remoteBrowserID, userId);
- log.debug("Chromium", `Using remote browser: ${remoteBrowser.name} (${remoteBrowser.id})`);
- browser = chromium.connect(remoteBrowser.url);
+ log.debug("MONITOR", `Using remote browser: ${remoteBrowser.name} (${remoteBrowser.id})`);
browser = await chromium.connect(remoteBrowser.url);
return browser;
}
diff --git a/server/notification-providers/alertnow.js b/server/notification-providers/alertnow.js
index ecc03e84b..4257ca9cd 100644
--- a/server/notification-providers/alertnow.js
+++ b/server/notification-providers/alertnow.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
+const { setting } = require("../util-server");
const { getMonitorRelativeURL, UP, DOWN } = require("../../src/util");
-const { Settings } = require("../settings");
class AlertNow extends NotificationProvider {
name = "AlertNow";
@@ -29,7 +29,7 @@ class AlertNow extends NotificationProvider {
textMsg += ` - ${msg}`;
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorJSON) {
textMsg += ` >> ${baseURL + getMonitorRelativeURL(monitorJSON.id)}`;
}
diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js
index 5d8cb8948..c66f270a7 100644
--- a/server/notification-providers/dingding.js
+++ b/server/notification-providers/dingding.js
@@ -87,7 +87,6 @@ class DingDing extends NotificationProvider {
* @returns {string} Status
*/
statusToString(status) {
- // TODO: Move to notification-provider.js to avoid repetition in classes
switch (status) {
case DOWN:
return "DOWN";
diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js
index ccb80bf40..6a52f8f3e 100644
--- a/server/notification-providers/discord.js
+++ b/server/notification-providers/discord.js
@@ -48,7 +48,7 @@ class Discord extends NotificationProvider {
},
{
name: monitorJSON["type"] === "push" ? "Service Type" : "Service URL",
- value: this.extractAdress(monitorJSON),
+ value: this.extractAddress(monitorJSON),
},
{
name: `Time (${heartbeatJSON["timezone"]})`,
@@ -85,7 +85,7 @@ class Discord extends NotificationProvider {
},
{
name: monitorJSON["type"] === "push" ? "Service Type" : "Service URL",
- value: this.extractAdress(monitorJSON),
+ value: this.extractAddress(monitorJSON),
},
{
name: `Time (${heartbeatJSON["timezone"]})`,
diff --git a/server/notification-providers/flashduty.js b/server/notification-providers/flashduty.js
index 09ee8913a..c340ed06f 100644
--- a/server/notification-providers/flashduty.js
+++ b/server/notification-providers/flashduty.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN, getMonitorRelativeURL } = require("../../src/util");
-const { Settings } = require("../settings");
+const { setting } = require("../util-server");
const successMessage = "Sent Successfully.";
class FlashDuty extends NotificationProvider {
@@ -84,7 +84,7 @@ class FlashDuty extends NotificationProvider {
}
};
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorInfo) {
options.client = "Uptime Kuma";
options.client_url = baseURL + getMonitorRelativeURL(monitorInfo.id);
diff --git a/server/notification-providers/google-chat.js b/server/notification-providers/google-chat.js
index e683a2070..0b72fea95 100644
--- a/server/notification-providers/google-chat.js
+++ b/server/notification-providers/google-chat.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
+const { setting } = require("../util-server");
const { getMonitorRelativeURL, UP } = require("../../src/util");
-const { Settings } = require("../settings");
class GoogleChat extends NotificationProvider {
name = "GoogleChat";
@@ -45,7 +45,7 @@ class GoogleChat extends NotificationProvider {
}
// add button for monitor link if available
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL) {
const urlPath = monitorJSON ? getMonitorRelativeURL(monitorJSON.id) : "/";
sectionWidgets.push({
diff --git a/server/notification-providers/notification-provider.js b/server/notification-providers/notification-provider.js
index d26b791f6..b9fb3d863 100644
--- a/server/notification-providers/notification-provider.js
+++ b/server/notification-providers/notification-provider.js
@@ -24,7 +24,7 @@ class NotificationProvider {
* @param {?object} monitorJSON Monitor details (For Up/Down only)
* @returns {string} The extracted address based on the monitor type.
*/
- extractAdress(monitorJSON) {
+ extractAddress(monitorJSON) {
if (!monitorJSON) {
return "";
}
diff --git a/server/notification-providers/pagerduty.js b/server/notification-providers/pagerduty.js
index 7aa19bb4b..c60d782e7 100644
--- a/server/notification-providers/pagerduty.js
+++ b/server/notification-providers/pagerduty.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN, getMonitorRelativeURL } = require("../../src/util");
-const { Settings } = require("../settings");
+const { setting } = require("../util-server");
let successMessage = "Sent Successfully.";
class PagerDuty extends NotificationProvider {
@@ -95,7 +95,7 @@ class PagerDuty extends NotificationProvider {
}
};
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorInfo) {
options.client = "Uptime Kuma";
options.client_url = baseURL + getMonitorRelativeURL(monitorInfo.id);
diff --git a/server/notification-providers/pagertree.js b/server/notification-providers/pagertree.js
index 62f229ace..c7a5338d1 100644
--- a/server/notification-providers/pagertree.js
+++ b/server/notification-providers/pagertree.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN, getMonitorRelativeURL } = require("../../src/util");
-const { Settings } = require("../settings");
+const { setting } = require("../util-server");
let successMessage = "Sent Successfully.";
class PagerTree extends NotificationProvider {
@@ -74,7 +74,7 @@ class PagerTree extends NotificationProvider {
}
};
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorJSON) {
options.client = "Uptime Kuma";
options.client_url = baseURL + getMonitorRelativeURL(monitorJSON.id);
diff --git a/server/notification-providers/rocket-chat.js b/server/notification-providers/rocket-chat.js
index 174a94950..690e33a86 100644
--- a/server/notification-providers/rocket-chat.js
+++ b/server/notification-providers/rocket-chat.js
@@ -1,8 +1,8 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const Slack = require("./slack");
+const { setting } = require("../util-server");
const { getMonitorRelativeURL, DOWN } = require("../../src/util");
-const { Settings } = require("../settings");
class RocketChat extends NotificationProvider {
name = "rocket.chat";
@@ -49,7 +49,7 @@ class RocketChat extends NotificationProvider {
await Slack.deprecateURL(notification.rocketbutton);
}
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL) {
data.attachments[0].title_link = baseURL + getMonitorRelativeURL(monitorJSON.id);
diff --git a/server/notification-providers/sevenio.js b/server/notification-providers/sevenio.js
index 9d805d7e6..eac38a26e 100644
--- a/server/notification-providers/sevenio.js
+++ b/server/notification-providers/sevenio.js
@@ -32,7 +32,7 @@ class SevenIO extends NotificationProvider {
return okMsg;
}
- let address = this.extractAdress(monitorJSON);
+ let address = this.extractAddress(monitorJSON);
if (address !== "") {
address = `(${address}) `;
}
diff --git a/server/notification-providers/signl4.js b/server/notification-providers/signl4.js
index e48983f59..8261a73f3 100644
--- a/server/notification-providers/signl4.js
+++ b/server/notification-providers/signl4.js
@@ -18,7 +18,7 @@ class SIGNL4 extends NotificationProvider {
msg,
// Source system
"X-S4-SourceSystem": "UptimeKuma",
- monitorUrl: this.extractAdress(monitorJSON),
+ monitorUrl: this.extractAddress(monitorJSON),
};
const config = {
diff --git a/server/notification-providers/slack.js b/server/notification-providers/slack.js
index 98ed1a908..f28a643e0 100644
--- a/server/notification-providers/slack.js
+++ b/server/notification-providers/slack.js
@@ -1,8 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
+const { setSettings, setting } = require("../util-server");
const { getMonitorRelativeURL, UP } = require("../../src/util");
-const { Settings } = require("../settings");
-const { log } = require("../../src/util");
class Slack extends NotificationProvider {
name = "slack";
@@ -15,13 +14,15 @@ class Slack extends NotificationProvider {
* @returns {Promise}
*/
static async deprecateURL(url) {
- let currentPrimaryBaseURL = await Settings.get("primaryBaseURL");
+ let currentPrimaryBaseURL = await setting("primaryBaseURL");
if (!currentPrimaryBaseURL) {
- log.error("notification", "Move the url to be the primary base URL");
- await Settings.set("primaryBaseURL", url, "general");
+ console.log("Move the url to be the primary base URL");
+ await setSettings("general", {
+ primaryBaseURL: url,
+ });
} else {
- log.debug("notification", "Already there, no need to move the primary base URL");
+ console.log("Already there, no need to move the primary base URL");
}
}
@@ -47,7 +48,7 @@ class Slack extends NotificationProvider {
}
- const address = this.extractAdress(monitorJSON);
+ const address = this.extractAddress(monitorJSON);
if (address) {
actions.push({
"type": "button",
@@ -135,21 +136,26 @@ class Slack extends NotificationProvider {
return okMsg;
}
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
const title = "Uptime Kuma Alert";
let data = {
- "text": `${title}\n${msg}`,
"channel": notification.slackchannel,
"username": notification.slackusername,
"icon_emoji": notification.slackiconemo,
- "attachments": [
+ "attachments": [],
+ };
+
+ if (notification.slackrichmessage) {
+ data.attachments.push(
{
"color": (heartbeatJSON["status"] === UP) ? "#2eb886" : "#e01e5a",
"blocks": Slack.buildBlocks(baseURL, monitorJSON, heartbeatJSON, title, msg),
}
- ]
- };
+ );
+ } else {
+ data.text = `${title}\n${msg}`;
+ }
if (notification.slackbutton) {
await Slack.deprecateURL(notification.slackbutton);
diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js
index 801e0e69d..9f3defa5e 100644
--- a/server/notification-providers/smtp.js
+++ b/server/notification-providers/smtp.js
@@ -93,7 +93,7 @@ class SMTP extends NotificationProvider {
if (monitorJSON !== null) {
monitorName = monitorJSON["name"];
- monitorHostnameOrURL = this.extractAdress(monitorJSON);
+ monitorHostnameOrURL = this.extractAddress(monitorJSON);
}
let serviceStatus = "⚠️ Test";
diff --git a/server/notification-providers/splunk.js b/server/notification-providers/splunk.js
index ad4dc6b39..e07c51039 100644
--- a/server/notification-providers/splunk.js
+++ b/server/notification-providers/splunk.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN, getMonitorRelativeURL } = require("../../src/util");
-const { Settings } = require("../settings");
+const { setting } = require("../util-server");
let successMessage = "Sent Successfully.";
class Splunk extends NotificationProvider {
@@ -95,7 +95,7 @@ class Splunk extends NotificationProvider {
}
};
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorInfo) {
options.client = "Uptime Kuma";
options.client_url = baseURL + getMonitorRelativeURL(monitorInfo.id);
diff --git a/server/notification-providers/squadcast.js b/server/notification-providers/squadcast.js
index 9074e9b76..5713783c0 100644
--- a/server/notification-providers/squadcast.js
+++ b/server/notification-providers/squadcast.js
@@ -34,7 +34,7 @@ class Squadcast extends NotificationProvider {
data.status = "resolve";
}
- data.tags["AlertAddress"] = this.extractAdress(monitorJSON);
+ data.tags["AlertAddress"] = this.extractAddress(monitorJSON);
monitorJSON["tags"].forEach(tag => {
data.tags[tag["name"]] = {
diff --git a/server/notification-providers/stackfield.js b/server/notification-providers/stackfield.js
index e4e31a9ab..65a92459a 100644
--- a/server/notification-providers/stackfield.js
+++ b/server/notification-providers/stackfield.js
@@ -1,7 +1,7 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
+const { setting } = require("../util-server");
const { getMonitorRelativeURL } = require("../../src/util");
-const { Settings } = require("../settings");
class Stackfield extends NotificationProvider {
name = "stackfield";
@@ -23,7 +23,7 @@ class Stackfield extends NotificationProvider {
textMsg += `\n${msg}`;
- const baseURL = await Settings.get("primaryBaseURL");
+ const baseURL = await setting("primaryBaseURL");
if (baseURL) {
textMsg += `\n${baseURL + getMonitorRelativeURL(monitorJSON.id)}`;
}
diff --git a/server/notification-providers/teams.js b/server/notification-providers/teams.js
index 2fcea7077..2793604cc 100644
--- a/server/notification-providers/teams.js
+++ b/server/notification-providers/teams.js
@@ -225,7 +225,7 @@ class Teams extends NotificationProvider {
const payload = this._notificationPayloadFactory({
heartbeatJSON: heartbeatJSON,
monitorName: monitorJSON.name,
- monitorUrl: this.extractAdress(monitorJSON),
+ monitorUrl: this.extractAddress(monitorJSON),
dashboardUrl: dashboardUrl,
});
diff --git a/server/notification-providers/techulus-push.js b/server/notification-providers/techulus-push.js
index 230897f3c..bf688b194 100644
--- a/server/notification-providers/techulus-push.js
+++ b/server/notification-providers/techulus-push.js
@@ -10,11 +10,22 @@ class TechulusPush extends NotificationProvider {
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully.";
+ let data = {
+ "title": notification?.pushTitle?.length ? notification.pushTitle : "Uptime-Kuma",
+ "body": msg,
+ "timeSensitive": notification.pushTimeSensitive ?? true,
+ };
+
+ if (notification.pushChannel) {
+ data.channel = notification.pushChannel;
+ }
+
+ if (notification.pushSound) {
+ data.sound = notification.pushSound;
+ }
+
try {
- await axios.post(`https://push.techulus.com/api/v1/notify/${notification.pushAPIKey}`, {
- "title": "Uptime-Kuma",
- "body": msg,
- });
+ await axios.post(`https://push.techulus.com/api/v1/notify/${notification.pushAPIKey}`, data);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
diff --git a/server/notification-providers/wecom.js b/server/notification-providers/wecom.js
index 03fa7c186..1eb069095 100644
--- a/server/notification-providers/wecom.js
+++ b/server/notification-providers/wecom.js
@@ -32,20 +32,17 @@ class WeCom extends NotificationProvider {
* @returns {object} Message
*/
composeMessage(heartbeatJSON, msg) {
- let title;
+ let title = "UptimeKuma Message";
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) {
title = "UptimeKuma Monitor Up";
}
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
title = "UptimeKuma Monitor Down";
}
- if (msg != null) {
- title = "UptimeKuma Message";
- }
return {
msgtype: "text",
text: {
- content: title + msg
+ content: title + "\n" + msg
}
};
}
diff --git a/server/notification-providers/zoho-cliq.js b/server/notification-providers/zoho-cliq.js
index 44681b7df..3a504de8c 100644
--- a/server/notification-providers/zoho-cliq.js
+++ b/server/notification-providers/zoho-cliq.js
@@ -85,7 +85,7 @@ class ZohoCliq extends NotificationProvider {
const payload = this._notificationPayloadFactory({
monitorMessage: heartbeatJSON.msg,
monitorName: monitorJSON.name,
- monitorUrl: this.extractAdress(monitorJSON),
+ monitorUrl: this.extractAddress(monitorJSON),
status: heartbeatJSON.status
});
diff --git a/server/prometheus.js b/server/prometheus.js
index 05a028397..f26125d2c 100644
--- a/server/prometheus.js
+++ b/server/prometheus.js
@@ -1,4 +1,3 @@
-const { R } = require("redbean-node");
const PrometheusClient = require("prom-client");
const { log } = require("../src/util");
@@ -10,102 +9,36 @@ const commonLabels = [
"monitor_port",
];
-class Prometheus {
-
- /**
- * Metric: monitor_cert_days_remaining
- * @type {PrometheusClient.Gauge | null}
- */
- static monitorCertDaysRemaining = null;
-
- /**
- * Metric: monitor_cert_is_valid
- * @type {PrometheusClient.Gauge | null}
- */
- static monitorCertIsValid = null;
-
- /**
- * Metric: monitor_response_time
- * @type {PrometheusClient.Gauge | null}
- */
- static monitorResponseTime = null;
-
- /**
- * Metric: monitor_status
- * @type {PrometheusClient.Gauge | null}
- */
- static monitorStatus = null;
-
- /**
- * All registered metric labels.
- * @type {string[] | null}
- */
- static monitorLabelNames = null;
-
- /**
- * Monitor labels/values combination.
- * @type {{}}
- */
- monitorLabelValues;
+const monitorCertDaysRemaining = new PrometheusClient.Gauge({
+ name: "monitor_cert_days_remaining",
+ help: "The number of days remaining until the certificate expires",
+ labelNames: commonLabels
+});
+
+const monitorCertIsValid = new PrometheusClient.Gauge({
+ name: "monitor_cert_is_valid",
+ help: "Is the certificate still valid? (1 = Yes, 0= No)",
+ labelNames: commonLabels
+});
+const monitorResponseTime = new PrometheusClient.Gauge({
+ name: "monitor_response_time",
+ help: "Monitor Response Time (ms)",
+ labelNames: commonLabels
+});
+
+const monitorStatus = new PrometheusClient.Gauge({
+ name: "monitor_status",
+ help: "Monitor Status (1 = UP, 0= DOWN, 2= PENDING, 3= MAINTENANCE)",
+ labelNames: commonLabels
+});
- /**
- * Initialize metrics and get all label names the first time called.
- * @returns {void}
- */
- static async initMetrics() {
- if (!this.monitorLabelNames) {
- let labelNames = await R.getCol("SELECT name FROM tag");
- this.monitorLabelNames = [ ...commonLabels, ...labelNames ];
- }
- if (!this.monitorCertDaysRemaining) {
- this.monitorCertDaysRemaining = new PrometheusClient.Gauge({
- name: "monitor_cert_days_remaining",
- help: "The number of days remaining until the certificate expires",
- labelNames: this.monitorLabelNames
- });
- }
- if (!this.monitorCertIsValid) {
- this.monitorCertIsValid = new PrometheusClient.Gauge({
- name: "monitor_cert_is_valid",
- help: "Is the certificate still valid? (1 = Yes, 0 = No)",
- labelNames: this.monitorLabelNames
- });
- }
- if (!this.monitorResponseTime) {
- this.monitorResponseTime = new PrometheusClient.Gauge({
- name: "monitor_response_time",
- help: "Monitor Response Time (ms)",
- labelNames: this.monitorLabelNames
- });
- }
- if (!this.monitorStatus) {
- this.monitorStatus = new PrometheusClient.Gauge({
- name: "monitor_status",
- help: "Monitor Status (1 = UP, 0 = DOWN, 2 = PENDING, 3 = MAINTENANCE)",
- labelNames: this.monitorLabelNames
- });
- }
- }
-
- /**
- * Wrapper to create a `Prometheus` instance and ensure metrics are initialized.
- * @param {Monitor} monitor Monitor object to monitor
- * @returns {Promise} `Prometheus` instance
- */
- static async createAndInitMetrics(monitor) {
- await Prometheus.initMetrics();
- let tags = await monitor.getTags();
- return new Prometheus(monitor, tags);
- }
+class Prometheus {
+ monitorLabelValues = {};
/**
- * Creates a prometheus metric instance.
- *
- * Note: Make sure to call `Prometheus.initMetrics()` once prior creating Prometheus instances.
- * @param {Monitor} monitor Monitor object to monitor
- * @param {Promise[]>} tags Tags of the monitor
+ * @param {object} monitor Monitor object to monitor
*/
- constructor(monitor, tags) {
+ constructor(monitor) {
this.monitorLabelValues = {
monitor_name: monitor.name,
monitor_type: monitor.type,
@@ -113,12 +46,6 @@ class Prometheus {
monitor_hostname: monitor.hostname,
monitor_port: monitor.port
};
- Object.values(tags)
- // only label names that were known at first metric creation.
- .filter(tag => Prometheus.monitorLabelNames.includes(tag.name))
- .forEach(tag => {
- this.monitorLabelValues[tag.name] = tag.value;
- });
}
/**
@@ -128,6 +55,7 @@ class Prometheus {
* @returns {void}
*/
update(heartbeat, tlsInfo) {
+
if (typeof tlsInfo !== "undefined") {
try {
let isValid;
@@ -136,7 +64,7 @@ class Prometheus {
} else {
isValid = 0;
}
- Prometheus.monitorCertIsValid.set(this.monitorLabelValues, isValid);
+ monitorCertIsValid.set(this.monitorLabelValues, isValid);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
@@ -144,7 +72,7 @@ class Prometheus {
try {
if (tlsInfo.certInfo != null) {
- Prometheus.monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining);
+ monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining);
}
} catch (e) {
log.error("prometheus", "Caught error");
@@ -154,7 +82,7 @@ class Prometheus {
if (heartbeat) {
try {
- Prometheus.monitorStatus.set(this.monitorLabelValues, heartbeat.status);
+ monitorStatus.set(this.monitorLabelValues, heartbeat.status);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
@@ -162,10 +90,10 @@ class Prometheus {
try {
if (typeof heartbeat.ping === "number") {
- Prometheus.monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
+ monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
} else {
// Is it good?
- Prometheus.monitorResponseTime.set(this.monitorLabelValues, -1);
+ monitorResponseTime.set(this.monitorLabelValues, -1);
}
} catch (e) {
log.error("prometheus", "Caught error");
@@ -180,10 +108,10 @@ class Prometheus {
*/
remove() {
try {
- Prometheus.monitorCertDaysRemaining?.remove(this.monitorLabelValues);
- Prometheus.monitorCertIsValid?.remove(this.monitorLabelValues);
- Prometheus.monitorResponseTime?.remove(this.monitorLabelValues);
- Prometheus.monitorStatus?.remove(this.monitorLabelValues);
+ monitorCertDaysRemaining.remove(this.monitorLabelValues);
+ monitorCertIsValid.remove(this.monitorLabelValues);
+ monitorResponseTime.remove(this.monitorLabelValues);
+ monitorStatus.remove(this.monitorLabelValues);
} catch (e) {
console.error(e);
}
diff --git a/server/proxy.js b/server/proxy.js
index 3f1215b25..3f3771ab9 100644
--- a/server/proxy.js
+++ b/server/proxy.js
@@ -2,7 +2,7 @@ const { R } = require("redbean-node");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");
const SocksProxyAgent = require("socks-proxy-agent");
-const { log } = require("../src/util");
+const { debug } = require("../src/util");
const { UptimeKumaServer } = require("./uptime-kuma-server");
const { CookieJar } = require("tough-cookie");
const { createCookieAgent } = require("http-cookie-agent/http");
@@ -110,9 +110,9 @@ class Proxy {
proxyOptions.auth = `${proxy.username}:${proxy.password}`;
}
- log.debug("update-proxy", `Proxy Options: ${JSON.stringify(proxyOptions)}`);
- log.debug("update-proxy", `HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`);
- log.debug("update-proxy", `HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`);
+ debug(`Proxy Options: ${JSON.stringify(proxyOptions)}`);
+ debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`);
+ debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`);
switch (proxy.protocol) {
case "http":
diff --git a/server/routers/api-router.js b/server/routers/api-router.js
index 9e7c9348c..ed6db2cd1 100644
--- a/server/routers/api-router.js
+++ b/server/routers/api-router.js
@@ -1,5 +1,6 @@
let express = require("express");
const {
+ setting,
allowDevAllOrigin,
allowAllOrigin,
percentageToColor,
@@ -17,7 +18,6 @@ const { makeBadge } = require("badge-maker");
const { Prometheus } = require("../prometheus");
const Database = require("../database");
const { UptimeCalculator } = require("../uptime-calculator");
-const { Settings } = require("../settings");
let router = express.Router();
@@ -30,7 +30,7 @@ router.get("/api/entry-page", async (request, response) => {
let result = { };
let hostname = request.hostname;
- if ((await Settings.get("trustProxy")) && request.headers["x-forwarded-host"]) {
+ if ((await setting("trustProxy")) && request.headers["x-forwarded-host"]) {
hostname = request.headers["x-forwarded-host"];
}
diff --git a/server/server.js b/server/server.js
index 3579df5d2..db58ae829 100644
--- a/server/server.js
+++ b/server/server.js
@@ -90,7 +90,8 @@ const Monitor = require("./model/monitor");
const User = require("./model/user");
log.debug("server", "Importing Settings");
-const { initJWTSecret, checkLogin, doubleCheckPassword, shake256, SHAKE256_LENGTH, allowDevAllOrigin } = require("./util-server");
+const { getSettings, setSettings, setting, initJWTSecret, checkLogin, doubleCheckPassword, shake256, SHAKE256_LENGTH, allowDevAllOrigin,
+} = require("./util-server");
log.debug("server", "Importing Notification");
const { Notification } = require("./notification");
@@ -200,7 +201,7 @@ let needSetup = false;
// Entry Page
app.get("/", async (request, response) => {
let hostname = request.hostname;
- if (await Settings.get("trustProxy")) {
+ if (await setting("trustProxy")) {
const proxy = request.headers["x-forwarded-host"];
if (proxy) {
hostname = proxy;
@@ -280,7 +281,7 @@ let needSetup = false;
// Robots.txt
app.get("/robots.txt", async (_request, response) => {
let txt = "User-agent: *\nDisallow:";
- if (!await Settings.get("searchEngineIndex")) {
+ if (!await setting("searchEngineIndex")) {
txt += " /";
}
response.setHeader("Content-Type", "text/plain");
@@ -1326,7 +1327,7 @@ let needSetup = false;
socket.on("getSettings", async (callback) => {
try {
checkLogin(socket);
- const data = await Settings.getSettings("general");
+ const data = await getSettings("general");
if (!data.serverTimezone) {
data.serverTimezone = await server.getTimezone();
@@ -1354,7 +1355,7 @@ let needSetup = false;
// Disabled Auth + Want to Enable Auth => No Check
// Enabled Auth + Want to Disable Auth => Check!!
// Enabled Auth + Want to Enable Auth => No Check
- const currentDisabledAuth = await Settings.get("disableAuth");
+ const currentDisabledAuth = await setting("disableAuth");
if (!currentDisabledAuth && data.disableAuth) {
await doubleCheckPassword(socket, currentPassword);
}
@@ -1368,7 +1369,7 @@ let needSetup = false;
const previousChromeExecutable = await Settings.get("chromeExecutable");
const previousNSCDStatus = await Settings.get("nscd");
- await Settings.setSettings("general", data);
+ await setSettings("general", data);
server.entryPage = data.entryPage;
// Also need to apply timezone globally
@@ -1464,7 +1465,7 @@ let needSetup = false;
});
} catch (e) {
- log.error("server", e);
+ console.error(e);
callback({
ok: false,
@@ -1577,7 +1578,7 @@ let needSetup = false;
// ***************************
log.debug("auth", "check auto login");
- if (await Settings.get("disableAuth")) {
+ if (await setting("disableAuth")) {
log.info("auth", "Disabled Auth: auto login to admin");
await afterLogin(socket, await R.findOne("user"));
socket.emit("autoLogin");
diff --git a/server/socket-handlers/api-key-socket-handler.js b/server/socket-handlers/api-key-socket-handler.js
index 1394f8044..f76b90991 100644
--- a/server/socket-handlers/api-key-socket-handler.js
+++ b/server/socket-handlers/api-key-socket-handler.js
@@ -60,7 +60,7 @@ module.exports.apiKeySocketHandler = (socket) => {
ok: true,
});
} catch (e) {
- log.error("apikeys", e);
+ console.error(e);
callback({
ok: false,
msg: e.message,
diff --git a/server/socket-handlers/cloudflared-socket-handler.js b/server/socket-handlers/cloudflared-socket-handler.js
index 1cd0c53d0..809191fe8 100644
--- a/server/socket-handlers/cloudflared-socket-handler.js
+++ b/server/socket-handlers/cloudflared-socket-handler.js
@@ -1,8 +1,7 @@
-const { checkLogin, doubleCheckPassword } = require("../util-server");
+const { checkLogin, setSetting, setting, doubleCheckPassword } = require("../util-server");
const { CloudflaredTunnel } = require("node-cloudflared-tunnel");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const { log } = require("../../src/util");
-const { Settings } = require("../settings");
const io = UptimeKumaServer.getInstance().io;
const prefix = "cloudflared_";
@@ -41,7 +40,7 @@ module.exports.cloudflaredSocketHandler = (socket) => {
socket.join("cloudflared");
io.to(socket.userID).emit(prefix + "installed", cloudflared.checkInstalled());
io.to(socket.userID).emit(prefix + "running", cloudflared.running);
- io.to(socket.userID).emit(prefix + "token", await Settings.get("cloudflaredTunnelToken"));
+ io.to(socket.userID).emit(prefix + "token", await setting("cloudflaredTunnelToken"));
} catch (error) { }
});
@@ -56,7 +55,7 @@ module.exports.cloudflaredSocketHandler = (socket) => {
try {
checkLogin(socket);
if (token && typeof token === "string") {
- await Settings.set("cloudflaredTunnelToken", token);
+ await setSetting("cloudflaredTunnelToken", token);
cloudflared.token = token;
} else {
cloudflared.token = null;
@@ -68,7 +67,7 @@ module.exports.cloudflaredSocketHandler = (socket) => {
socket.on(prefix + "stop", async (currentPassword, callback) => {
try {
checkLogin(socket);
- const disabledAuth = await Settings.get("disableAuth");
+ const disabledAuth = await setting("disableAuth");
if (!disabledAuth) {
await doubleCheckPassword(socket, currentPassword);
}
@@ -84,7 +83,7 @@ module.exports.cloudflaredSocketHandler = (socket) => {
socket.on(prefix + "removeToken", async () => {
try {
checkLogin(socket);
- await Settings.set("cloudflaredTunnelToken", "");
+ await setSetting("cloudflaredTunnelToken", "");
} catch (error) { }
});
@@ -97,15 +96,15 @@ module.exports.cloudflaredSocketHandler = (socket) => {
*/
module.exports.autoStart = async (token) => {
if (!token) {
- token = await Settings.get("cloudflaredTunnelToken");
+ token = await setting("cloudflaredTunnelToken");
} else {
// Override the current token via args or env var
- await Settings.set("cloudflaredTunnelToken", token);
- log.info("cloudflare", "Use cloudflared token from args or env var");
+ await setSetting("cloudflaredTunnelToken", token);
+ console.log("Use cloudflared token from args or env var");
}
if (token) {
- log.info("cloudflare", "Start cloudflared");
+ console.log("Start cloudflared");
cloudflared.token = token;
cloudflared.start();
}
diff --git a/server/socket-handlers/maintenance-socket-handler.js b/server/socket-handlers/maintenance-socket-handler.js
index 201014c22..7de13fe57 100644
--- a/server/socket-handlers/maintenance-socket-handler.js
+++ b/server/socket-handlers/maintenance-socket-handler.js
@@ -67,7 +67,7 @@ module.exports.maintenanceSocketHandler = (socket) => {
});
} catch (e) {
- log.error("maintenance", e);
+ console.error(e);
callback({
ok: false,
msg: e.message,
@@ -177,7 +177,7 @@ module.exports.maintenanceSocketHandler = (socket) => {
ok: true,
});
} catch (e) {
- log.error("maintenance", e);
+ console.error(e);
callback({
ok: false,
msg: e.message,
@@ -201,7 +201,7 @@ module.exports.maintenanceSocketHandler = (socket) => {
});
} catch (e) {
- log.error("maintenance", e);
+ console.error(e);
callback({
ok: false,
msg: e.message,
@@ -225,7 +225,7 @@ module.exports.maintenanceSocketHandler = (socket) => {
});
} catch (e) {
- log.error("maintenance", e);
+ console.error(e);
callback({
ok: false,
msg: e.message,
diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js
index cf0accc23..0804da15d 100644
--- a/server/socket-handlers/status-page-socket-handler.js
+++ b/server/socket-handlers/status-page-socket-handler.js
@@ -1,5 +1,5 @@
const { R } = require("redbean-node");
-const { checkLogin } = require("../util-server");
+const { checkLogin, setSetting } = require("../util-server");
const dayjs = require("dayjs");
const { log } = require("../../src/util");
const ImageDataURI = require("../image-data-uri");
@@ -7,7 +7,6 @@ const Database = require("../database");
const apicache = require("../modules/apicache");
const StatusPage = require("../model/status_page");
const { UptimeKumaServer } = require("../uptime-kuma-server");
-const { Settings } = require("../settings");
/**
* Socket handlers for status page
@@ -234,7 +233,7 @@ module.exports.statusPageSocketHandler = (socket) => {
// Also change entry page to new slug if it is the default one, and slug is changed.
if (server.entryPage === "statusPage-" + slug && statusPage.slug !== slug) {
server.entryPage = "statusPage-" + statusPage.slug;
- await Settings.set("entryPage", server.entryPage, "general");
+ await setSetting("entryPage", server.entryPage, "general");
}
apicache.clear();
@@ -292,7 +291,7 @@ module.exports.statusPageSocketHandler = (socket) => {
});
} catch (error) {
- log.error("socket", error);
+ console.error(error);
callback({
ok: false,
msg: error.message,
@@ -314,7 +313,7 @@ module.exports.statusPageSocketHandler = (socket) => {
// Reset entry page if it is the default one.
if (server.entryPage === "statusPage-" + slug) {
server.entryPage = "dashboard";
- await Settings.set("entryPage", server.entryPage, "general");
+ await setSetting("entryPage", server.entryPage, "general");
}
// No need to delete records from `status_page_cname`, because it has cascade foreign key.
diff --git a/server/util-server.js b/server/util-server.js
index f4a4a67fe..5ebc62ac5 100644
--- a/server/util-server.js
+++ b/server/util-server.js
@@ -12,6 +12,7 @@ const { Client } = require("pg");
const postgresConParse = require("pg-connection-string").parse;
const mysql = require("mysql2");
const { NtlmClient } = require("./modules/axios-ntlm/lib/ntlmClient.js");
+const { Settings } = require("./settings");
const grpc = require("@grpc/grpc-js");
const protojs = require("protobufjs");
const radiusClient = require("node-radius-client");
@@ -520,6 +521,46 @@ exports.redisPingAsync = function (dsn, rejectUnauthorized) {
});
};
+/**
+ * Retrieve value of setting based on key
+ * @param {string} key Key of setting to retrieve
+ * @returns {Promise} Value
+ * @deprecated Use await Settings.get(key)
+ */
+exports.setting = async function (key) {
+ return await Settings.get(key);
+};
+
+/**
+ * Sets the specified setting to specified value
+ * @param {string} key Key of setting to set
+ * @param {any} value Value to set to
+ * @param {?string} type Type of setting
+ * @returns {Promise}
+ */
+exports.setSetting = async function (key, value, type = null) {
+ await Settings.set(key, value, type);
+};
+
+/**
+ * Get settings based on type
+ * @param {string} type The type of setting
+ * @returns {Promise} Settings of requested type
+ */
+exports.getSettings = async function (type) {
+ return await Settings.getSettings(type);
+};
+
+/**
+ * Set settings based on type
+ * @param {string} type Type of settings to set
+ * @param {object} data Values of settings
+ * @returns {Promise}
+ */
+exports.setSettings = async function (type, data) {
+ await Settings.setSettings(type, data);
+};
+
// ssl-checker by @dyaa
//https://github.com/dyaa/ssl-checker/blob/master/src/index.ts
diff --git a/src/components/notifications/Slack.vue b/src/components/notifications/Slack.vue
index dead709ce..dc07bf373 100644
--- a/src/components/notifications/Slack.vue
+++ b/src/components/notifications/Slack.vue
@@ -9,6 +9,12 @@
+
+