mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Merge pull request from GHSA-88j4-pcx8-q4q3
* WIP, still need to handle npm run reset-password * Implement it for "npm run reset-password" Bug fixes and change along with this commit - Move `ssl`, `hostname`, `port` to ./server/config.js, so `reset-password` is able to read it - Fix: FBSD is missing, no idea who dropped it. - Fix: Frontend code should not require any backend code (./server/config.js), moved "badgeConstants" to the common util (./src/util.ts) and drop vite-common.js * Minor
This commit is contained in:
		@@ -3,7 +3,6 @@ import vue from "@vitejs/plugin-vue";
 | 
			
		||||
import { defineConfig } from "vite";
 | 
			
		||||
import visualizer from "rollup-plugin-visualizer";
 | 
			
		||||
import viteCompression from "vite-plugin-compression";
 | 
			
		||||
import commonjs from "vite-plugin-commonjs";
 | 
			
		||||
 | 
			
		||||
const postCssScss = require("postcss-scss");
 | 
			
		||||
const postcssRTLCSS = require("postcss-rtlcss");
 | 
			
		||||
@@ -22,7 +21,6 @@ export default defineConfig({
 | 
			
		||||
        "CODESPACE_NAME": JSON.stringify(process.env.CODESPACE_NAME),
 | 
			
		||||
    },
 | 
			
		||||
    plugins: [
 | 
			
		||||
        commonjs(),
 | 
			
		||||
        vue(),
 | 
			
		||||
        legacy({
 | 
			
		||||
            targets: [ "since 2015" ],
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 * ⚠️ Deprecated: Changed to healthcheck.go, it will be deleted in the future.
 | 
			
		||||
 * This script should be run after a period of time (180s), because the server may need some time to prepare.
 | 
			
		||||
 */
 | 
			
		||||
const { FBSD } = require("../server/util-server");
 | 
			
		||||
const FBSD = /^freebsd/.test(process.platform);
 | 
			
		||||
 | 
			
		||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@ const { R } = require("redbean-node");
 | 
			
		||||
const readline = require("readline");
 | 
			
		||||
const { initJWTSecret } = require("../server/util-server");
 | 
			
		||||
const User = require("../server/model/user");
 | 
			
		||||
const { io } = require("socket.io-client");
 | 
			
		||||
const { localWebSocketURL } = require("../server/config");
 | 
			
		||||
const args = require("args-parser")(process.argv);
 | 
			
		||||
const rl = readline.createInterface({
 | 
			
		||||
    input: process.stdin,
 | 
			
		||||
@@ -36,12 +38,16 @@ const main = async () => {
 | 
			
		||||
                    // Reset all sessions by reset jwt secret
 | 
			
		||||
                    await initJWTSecret();
 | 
			
		||||
 | 
			
		||||
                    // Disconnect all other socket clients of the user
 | 
			
		||||
                    await disconnectAllSocketClients(user.username, password);
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                } else {
 | 
			
		||||
                    console.log("Passwords do not match, please try again.");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            console.log("Password reset successfully.");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        console.error("Error: " + e.message);
 | 
			
		||||
@@ -66,6 +72,45 @@ function question(question) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function disconnectAllSocketClients(username, password) {
 | 
			
		||||
    return new Promise((resolve) => {
 | 
			
		||||
        console.log("Connecting to " + localWebSocketURL + " to disconnect all other socket clients");
 | 
			
		||||
 | 
			
		||||
        // Disconnect all socket connections
 | 
			
		||||
        const socket = io(localWebSocketURL, {
 | 
			
		||||
            transports: [ "websocket" ],
 | 
			
		||||
            reconnection: false,
 | 
			
		||||
            timeout: 5000,
 | 
			
		||||
        });
 | 
			
		||||
        socket.on("connect", () => {
 | 
			
		||||
            socket.emit("login", {
 | 
			
		||||
                username,
 | 
			
		||||
                password,
 | 
			
		||||
            }, (res) => {
 | 
			
		||||
                if (res.ok) {
 | 
			
		||||
                    console.log("Logged in.");
 | 
			
		||||
                    socket.emit("disconnectOtherSocketClients");
 | 
			
		||||
                } else {
 | 
			
		||||
                    console.warn("Login failed.");
 | 
			
		||||
                    console.warn("Please restart the server to disconnect all sessions.");
 | 
			
		||||
                }
 | 
			
		||||
                socket.close();
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        socket.on("connect_error", function () {
 | 
			
		||||
            // The localWebSocketURL is not guaranteed to be working for some complicated Uptime Kuma setup
 | 
			
		||||
            // Ask the user to restart the server manually
 | 
			
		||||
            console.warn("Failed to connect to " + localWebSocketURL);
 | 
			
		||||
            console.warn("Please restart the server to disconnect all sessions manually.");
 | 
			
		||||
            resolve();
 | 
			
		||||
        });
 | 
			
		||||
        socket.on("disconnect", () => {
 | 
			
		||||
            resolve();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!process.env.TEST_BACKEND) {
 | 
			
		||||
    main();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -192,7 +192,6 @@
 | 
			
		||||
        "typescript": "~4.4.4",
 | 
			
		||||
        "v-pagination-3": "~0.1.7",
 | 
			
		||||
        "vite": "~4.4.1",
 | 
			
		||||
        "vite-plugin-commonjs": "^0.8.0",
 | 
			
		||||
        "vite-plugin-compression": "^0.5.1",
 | 
			
		||||
        "vue": "~3.3.4",
 | 
			
		||||
        "vue-chartjs": "~5.2.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,42 @@
 | 
			
		||||
const isFreeBSD = /^freebsd/.test(process.platform);
 | 
			
		||||
 | 
			
		||||
// Interop with browser
 | 
			
		||||
const args = (typeof process !== "undefined") ? require("args-parser")(process.argv) : {};
 | 
			
		||||
const demoMode = args["demo"] || false;
 | 
			
		||||
 | 
			
		||||
const badgeConstants = {
 | 
			
		||||
    naColor: "#999",
 | 
			
		||||
    defaultUpColor: "#66c20a",
 | 
			
		||||
    defaultWarnColor: "#eed202",
 | 
			
		||||
    defaultDownColor: "#c2290a",
 | 
			
		||||
    defaultPendingColor: "#f8a306",
 | 
			
		||||
    defaultMaintenanceColor: "#1747f5",
 | 
			
		||||
    defaultPingColor: "blue",  // as defined by badge-maker / shields.io
 | 
			
		||||
    defaultStyle: "flat",
 | 
			
		||||
    defaultPingValueSuffix: "ms",
 | 
			
		||||
    defaultPingLabelSuffix: "h",
 | 
			
		||||
    defaultUptimeValueSuffix: "%",
 | 
			
		||||
    defaultUptimeLabelSuffix: "h",
 | 
			
		||||
    defaultCertExpValueSuffix: " days",
 | 
			
		||||
    defaultCertExpLabelSuffix: "h",
 | 
			
		||||
    // Values Come From Default Notification Times
 | 
			
		||||
    defaultCertExpireWarnDays: "14",
 | 
			
		||||
    defaultCertExpireDownDays: "7"
 | 
			
		||||
};
 | 
			
		||||
// If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available and the unspecified IPv4 address (0.0.0.0) otherwise.
 | 
			
		||||
// Dual-stack support for (::)
 | 
			
		||||
// Also read HOST if not FreeBSD, as HOST is a system environment variable in FreeBSD
 | 
			
		||||
let hostEnv = isFreeBSD ? null : process.env.HOST;
 | 
			
		||||
const hostname = args.host || process.env.UPTIME_KUMA_HOST || hostEnv;
 | 
			
		||||
 | 
			
		||||
const port = [ args.port, process.env.UPTIME_KUMA_PORT, process.env.PORT, 3001 ]
 | 
			
		||||
    .map(portValue => parseInt(portValue))
 | 
			
		||||
    .find(portValue => !isNaN(portValue));
 | 
			
		||||
 | 
			
		||||
const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined;
 | 
			
		||||
const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined;
 | 
			
		||||
const sslKeyPassphrase = args["ssl-key-passphrase"] || process.env.UPTIME_KUMA_SSL_KEY_PASSPHRASE || process.env.SSL_KEY_PASSPHRASE || undefined;
 | 
			
		||||
 | 
			
		||||
const isSSL = sslKey && sslCert;
 | 
			
		||||
 | 
			
		||||
function getLocalWebSocketURL() {
 | 
			
		||||
    const protocol = isSSL ? "wss" : "ws";
 | 
			
		||||
    const host = hostname || "localhost";
 | 
			
		||||
    return `${protocol}://${host}:${port}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const localWebSocketURL = getLocalWebSocketURL();
 | 
			
		||||
 | 
			
		||||
const demoMode = args["demo"] || false;
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    args,
 | 
			
		||||
    hostname,
 | 
			
		||||
    port,
 | 
			
		||||
    sslKey,
 | 
			
		||||
    sslCert,
 | 
			
		||||
    sslKeyPassphrase,
 | 
			
		||||
    isSSL,
 | 
			
		||||
    localWebSocketURL,
 | 
			
		||||
    demoMode,
 | 
			
		||||
    badgeConstants,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,11 @@ const { R } = require("redbean-node");
 | 
			
		||||
const apicache = require("../modules/apicache");
 | 
			
		||||
const Monitor = require("../model/monitor");
 | 
			
		||||
const dayjs = require("dayjs");
 | 
			
		||||
const { UP, MAINTENANCE, DOWN, PENDING, flipStatus, log } = require("../../src/util");
 | 
			
		||||
const { UP, MAINTENANCE, DOWN, PENDING, flipStatus, log, badgeConstants } = require("../../src/util");
 | 
			
		||||
const StatusPage = require("../model/status_page");
 | 
			
		||||
const { UptimeKumaServer } = require("../uptime-kuma-server");
 | 
			
		||||
const { UptimeCacheList } = require("../uptime-cache-list");
 | 
			
		||||
const { makeBadge } = require("badge-maker");
 | 
			
		||||
const { badgeConstants } = require("../config");
 | 
			
		||||
const { Prometheus } = require("../prometheus");
 | 
			
		||||
 | 
			
		||||
let router = express.Router();
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ const StatusPage = require("../model/status_page");
 | 
			
		||||
const { allowDevAllOrigin, sendHttpError } = require("../util-server");
 | 
			
		||||
const { R } = require("redbean-node");
 | 
			
		||||
const Monitor = require("../model/monitor");
 | 
			
		||||
const { badgeConstants } = require("../config");
 | 
			
		||||
const { badgeConstants } = require("../../src/util");
 | 
			
		||||
const { makeBadge } = require("badge-maker");
 | 
			
		||||
 | 
			
		||||
let router = express.Router();
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ const notp = require("notp");
 | 
			
		||||
const base32 = require("thirty-two");
 | 
			
		||||
 | 
			
		||||
const { UptimeKumaServer } = require("./uptime-kuma-server");
 | 
			
		||||
const server = UptimeKumaServer.getInstance(args);
 | 
			
		||||
const server = UptimeKumaServer.getInstance();
 | 
			
		||||
const io = module.exports.io = server.io;
 | 
			
		||||
const app = server.app;
 | 
			
		||||
 | 
			
		||||
@@ -91,7 +91,7 @@ const Monitor = require("./model/monitor");
 | 
			
		||||
const User = require("./model/user");
 | 
			
		||||
 | 
			
		||||
log.debug("server", "Importing Settings");
 | 
			
		||||
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests, shake256, SHAKE256_LENGTH
 | 
			
		||||
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, doubleCheckPassword, startE2eTests, shake256, SHAKE256_LENGTH
 | 
			
		||||
} = require("./util-server");
 | 
			
		||||
 | 
			
		||||
log.debug("server", "Importing Notification");
 | 
			
		||||
@@ -115,19 +115,13 @@ const passwordHash = require("./password-hash");
 | 
			
		||||
const checkVersion = require("./check-version");
 | 
			
		||||
log.info("server", "Version: " + checkVersion.version);
 | 
			
		||||
 | 
			
		||||
// If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available and the unspecified IPv4 address (0.0.0.0) otherwise.
 | 
			
		||||
// Dual-stack support for (::)
 | 
			
		||||
// Also read HOST if not FreeBSD, as HOST is a system environment variable in FreeBSD
 | 
			
		||||
let hostEnv = FBSD ? null : process.env.HOST;
 | 
			
		||||
let hostname = args.host || process.env.UPTIME_KUMA_HOST || hostEnv;
 | 
			
		||||
const hostname = config.hostname;
 | 
			
		||||
 | 
			
		||||
if (hostname) {
 | 
			
		||||
    log.info("server", "Custom hostname: " + hostname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const port = [ args.port, process.env.UPTIME_KUMA_PORT, process.env.PORT, 3001 ]
 | 
			
		||||
    .map(portValue => parseInt(portValue))
 | 
			
		||||
    .find(portValue => !isNaN(portValue));
 | 
			
		||||
const port = config.port;
 | 
			
		||||
 | 
			
		||||
const disableFrameSameOrigin = !!process.env.UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN || args["disable-frame-sameorigin"] || false;
 | 
			
		||||
const cloudflaredToken = args["cloudflared-token"] || process.env.UPTIME_KUMA_CLOUDFLARED_TOKEN || undefined;
 | 
			
		||||
@@ -1157,6 +1151,8 @@ let needSetup = false;
 | 
			
		||||
                let user = await doubleCheckPassword(socket, password.currentPassword);
 | 
			
		||||
                await user.resetPassword(password.newPassword);
 | 
			
		||||
 | 
			
		||||
                server.disconnectAllSocketClient(user.id, socket.id);
 | 
			
		||||
 | 
			
		||||
                callback({
 | 
			
		||||
                    ok: true,
 | 
			
		||||
                    msg: "Password has been updated successfully.",
 | 
			
		||||
 
 | 
			
		||||
@@ -78,4 +78,14 @@ module.exports.generalSocketHandler = (socket, server) => {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Disconnect all other socket clients of the user
 | 
			
		||||
    socket.on("disconnectOtherSocketClients", async () => {
 | 
			
		||||
        try {
 | 
			
		||||
            checkLogin(socket);
 | 
			
		||||
            server.disconnectAllSocketClients(socket.userID, socket.id);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            log.warn("disconnectAllSocketClients", e.message);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ const { Settings } = require("./settings");
 | 
			
		||||
const dayjs = require("dayjs");
 | 
			
		||||
const childProcessAsync = require("promisify-child-process");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const { isSSL, sslKey, sslCert, sslKeyPassphrase } = require("./config");
 | 
			
		||||
// DO NOT IMPORT HERE IF THE MODULES USED `UptimeKumaServer.getInstance()`, put at the bottom of this file instead.
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -62,22 +63,17 @@ class UptimeKumaServer {
 | 
			
		||||
     */
 | 
			
		||||
    jwtSecret = null;
 | 
			
		||||
 | 
			
		||||
    static getInstance(args) {
 | 
			
		||||
    static getInstance() {
 | 
			
		||||
        if (UptimeKumaServer.instance == null) {
 | 
			
		||||
            UptimeKumaServer.instance = new UptimeKumaServer(args);
 | 
			
		||||
            UptimeKumaServer.instance = new UptimeKumaServer();
 | 
			
		||||
        }
 | 
			
		||||
        return UptimeKumaServer.instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(args) {
 | 
			
		||||
        // SSL
 | 
			
		||||
        const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined;
 | 
			
		||||
        const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined;
 | 
			
		||||
        const sslKeyPassphrase = args["ssl-key-passphrase"] || process.env.UPTIME_KUMA_SSL_KEY_PASSPHRASE || process.env.SSL_KEY_PASSPHRASE || undefined;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        log.info("server", "Creating express and socket.io instance");
 | 
			
		||||
        this.app = express();
 | 
			
		||||
        if (sslKey && sslCert) {
 | 
			
		||||
        if (isSSL) {
 | 
			
		||||
            log.info("server", "Server Type: HTTPS");
 | 
			
		||||
            this.httpServer = https.createServer({
 | 
			
		||||
                key: fs.readFileSync(sslKey),
 | 
			
		||||
@@ -422,6 +418,25 @@ class UptimeKumaServer {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Force connected sockets of a user to refresh and disconnect.
 | 
			
		||||
     * Used for resetting password.
 | 
			
		||||
     * @param {string} userID
 | 
			
		||||
     * @param {string?} currentSocketID
 | 
			
		||||
     */
 | 
			
		||||
    disconnectAllSocketClients(userID, currentSocketID = undefined) {
 | 
			
		||||
        for (const socket of this.io.sockets.sockets.values()) {
 | 
			
		||||
            if (socket.userID === userID && socket.id !== currentSocketID) {
 | 
			
		||||
                try {
 | 
			
		||||
                    socket.emit("refresh");
 | 
			
		||||
                    socket.disconnect();
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
const tcpp = require("tcp-ping");
 | 
			
		||||
const ping = require("@louislam/ping");
 | 
			
		||||
const { R } = require("redbean-node");
 | 
			
		||||
const { log, genSecret } = require("../src/util");
 | 
			
		||||
const { log, genSecret, badgeConstants } = require("../src/util");
 | 
			
		||||
const passwordHash = require("./password-hash");
 | 
			
		||||
const { Resolver } = require("dns");
 | 
			
		||||
const childProcess = require("child_process");
 | 
			
		||||
@@ -9,7 +9,6 @@ const iconv = require("iconv-lite");
 | 
			
		||||
const chardet = require("chardet");
 | 
			
		||||
const mqtt = require("mqtt");
 | 
			
		||||
const chroma = require("chroma-js");
 | 
			
		||||
const { badgeConstants } = require("./config");
 | 
			
		||||
const mssql = require("mssql");
 | 
			
		||||
const { Client } = require("pg");
 | 
			
		||||
const postgresConParse = require("pg-connection-string").parse;
 | 
			
		||||
 
 | 
			
		||||
@@ -135,7 +135,7 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { Modal } from "bootstrap";
 | 
			
		||||
import CopyableInput from "./CopyableInput.vue";
 | 
			
		||||
import { default as serverConfig } from "../../server/config.js";
 | 
			
		||||
import { badgeConstants } from "../util.ts";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
@@ -230,7 +230,7 @@ export default {
 | 
			
		||||
                    "labelColor",
 | 
			
		||||
                ],
 | 
			
		||||
            },
 | 
			
		||||
            badgeConstants: serverConfig.badgeConstants,
 | 
			
		||||
            badgeConstants,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -288,6 +288,10 @@ export default {
 | 
			
		||||
            socket.on("initServerTimezone", () => {
 | 
			
		||||
                socket.emit("initServerTimezone", dayjs.tz.guess());
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            socket.on("refresh", () => {
 | 
			
		||||
                location.reload();
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
 
 | 
			
		||||
@@ -848,9 +848,8 @@ import NotificationDialog from "../components/NotificationDialog.vue";
 | 
			
		||||
import DockerHostDialog from "../components/DockerHostDialog.vue";
 | 
			
		||||
import ProxyDialog from "../components/ProxyDialog.vue";
 | 
			
		||||
import TagsManager from "../components/TagsManager.vue";
 | 
			
		||||
import { genSecret, isDev, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND } from "../util.ts";
 | 
			
		||||
import { genSecret, isDev, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND, sleep } from "../util.ts";
 | 
			
		||||
import { hostNameRegexPattern } from "../util-frontend";
 | 
			
		||||
import { sleep } from "../util";
 | 
			
		||||
import HiddenInput from "../components/HiddenInput.vue";
 | 
			
		||||
 | 
			
		||||
const toast = useToast();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								src/util.js
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/util.js
									
									
									
									
									
								
							@@ -7,7 +7,7 @@
 | 
			
		||||
// Backend uses the compiled file util.js
 | 
			
		||||
// Frontend uses util.ts
 | 
			
		||||
Object.defineProperty(exports, "__esModule", { value: true });
 | 
			
		||||
exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMaintenanceRelativeURL = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0;
 | 
			
		||||
exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMaintenanceRelativeURL = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.badgeConstants = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0;
 | 
			
		||||
const dayjs = require("dayjs");
 | 
			
		||||
exports.isDev = process.env.NODE_ENV === "development";
 | 
			
		||||
exports.appName = "Uptime Kuma";
 | 
			
		||||
@@ -24,6 +24,25 @@ exports.SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
 | 
			
		||||
exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
 | 
			
		||||
exports.MAX_INTERVAL_SECOND = 2073600; // 24 days
 | 
			
		||||
exports.MIN_INTERVAL_SECOND = 20; // 20 seconds
 | 
			
		||||
exports.badgeConstants = {
 | 
			
		||||
    naColor: "#999",
 | 
			
		||||
    defaultUpColor: "#66c20a",
 | 
			
		||||
    defaultWarnColor: "#eed202",
 | 
			
		||||
    defaultDownColor: "#c2290a",
 | 
			
		||||
    defaultPendingColor: "#f8a306",
 | 
			
		||||
    defaultMaintenanceColor: "#1747f5",
 | 
			
		||||
    defaultPingColor: "blue",
 | 
			
		||||
    defaultStyle: "flat",
 | 
			
		||||
    defaultPingValueSuffix: "ms",
 | 
			
		||||
    defaultPingLabelSuffix: "h",
 | 
			
		||||
    defaultUptimeValueSuffix: "%",
 | 
			
		||||
    defaultUptimeLabelSuffix: "h",
 | 
			
		||||
    defaultCertExpValueSuffix: " days",
 | 
			
		||||
    defaultCertExpLabelSuffix: "h",
 | 
			
		||||
    // Values Come From Default Notification Times
 | 
			
		||||
    defaultCertExpireWarnDays: "14",
 | 
			
		||||
    defaultCertExpireDownDays: "7"
 | 
			
		||||
};
 | 
			
		||||
/** Flip the status of s */
 | 
			
		||||
function flipStatus(s) {
 | 
			
		||||
    if (s === exports.UP) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								src/util.ts
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/util.ts
									
									
									
									
									
								
							@@ -29,6 +29,26 @@ export const SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
 | 
			
		||||
export const MAX_INTERVAL_SECOND = 2073600; // 24 days
 | 
			
		||||
export const MIN_INTERVAL_SECOND = 20; // 20 seconds
 | 
			
		||||
 | 
			
		||||
export const badgeConstants = {
 | 
			
		||||
    naColor: "#999",
 | 
			
		||||
    defaultUpColor: "#66c20a",
 | 
			
		||||
    defaultWarnColor: "#eed202",
 | 
			
		||||
    defaultDownColor: "#c2290a",
 | 
			
		||||
    defaultPendingColor: "#f8a306",
 | 
			
		||||
    defaultMaintenanceColor: "#1747f5",
 | 
			
		||||
    defaultPingColor: "blue",  // as defined by badge-maker / shields.io
 | 
			
		||||
    defaultStyle: "flat",
 | 
			
		||||
    defaultPingValueSuffix: "ms",
 | 
			
		||||
    defaultPingLabelSuffix: "h",
 | 
			
		||||
    defaultUptimeValueSuffix: "%",
 | 
			
		||||
    defaultUptimeLabelSuffix: "h",
 | 
			
		||||
    defaultCertExpValueSuffix: " days",
 | 
			
		||||
    defaultCertExpLabelSuffix: "h",
 | 
			
		||||
    // Values Come From Default Notification Times
 | 
			
		||||
    defaultCertExpireWarnDays: "14",
 | 
			
		||||
    defaultCertExpireDownDays: "7"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Flip the status of s */
 | 
			
		||||
export function flipStatus(s: number) {
 | 
			
		||||
    if (s === UP) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user