mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into maintenance
# Conflicts: # server/server.js # src/components/settings/General.vue
This commit is contained in:
		
							
								
								
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -9,7 +9,7 @@
 | 
			
		||||
            "version": "1.18.5",
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@louislam/sqlite3": "~15.0.6",
 | 
			
		||||
                "@louislam/sqlite3": "15.1.2",
 | 
			
		||||
                "args-parser": "~1.3.0",
 | 
			
		||||
                "axios": "~0.27.0",
 | 
			
		||||
                "axios-ntlm": "~1.3.0",
 | 
			
		||||
@@ -3116,9 +3116,9 @@
 | 
			
		||||
            "integrity": "sha512-iHHyIRLEfXLqBN+BkyH8u8imMYr4ihRbFDEk8toqTwUECETVQFCTh2U59Sw2oMoRVaS3XRIb7pyCulltq2jFVA=="
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@louislam/sqlite3": {
 | 
			
		||||
            "version": "15.0.6",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.6.tgz",
 | 
			
		||||
            "integrity": "sha512-+HF/4OEy+yakYzJlSPJbLDtf499t0s0eaglXC9y3Oa9OBZ+dKAaTW5+Ft1RCvfUJLFw/oyYjHtMsg9V+7NT05g==",
 | 
			
		||||
            "version": "15.1.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.1.2.tgz",
 | 
			
		||||
            "integrity": "sha512-VRquWrCKKwfOnzwVh6hOud8lHPvv2R7Jic3gyZCL5kiZpNfmJ71DLCV9SNgLaMDloU+mVWymLev8vehlf7xf5g==",
 | 
			
		||||
            "hasInstallScript": true,
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@mapbox/node-pre-gyp": "^1.0.0",
 | 
			
		||||
@@ -18867,9 +18867,9 @@
 | 
			
		||||
            "integrity": "sha512-iHHyIRLEfXLqBN+BkyH8u8imMYr4ihRbFDEk8toqTwUECETVQFCTh2U59Sw2oMoRVaS3XRIb7pyCulltq2jFVA=="
 | 
			
		||||
        },
 | 
			
		||||
        "@louislam/sqlite3": {
 | 
			
		||||
            "version": "15.0.6",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.6.tgz",
 | 
			
		||||
            "integrity": "sha512-+HF/4OEy+yakYzJlSPJbLDtf499t0s0eaglXC9y3Oa9OBZ+dKAaTW5+Ft1RCvfUJLFw/oyYjHtMsg9V+7NT05g==",
 | 
			
		||||
            "version": "15.1.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.1.2.tgz",
 | 
			
		||||
            "integrity": "sha512-VRquWrCKKwfOnzwVh6hOud8lHPvv2R7Jic3gyZCL5kiZpNfmJ71DLCV9SNgLaMDloU+mVWymLev8vehlf7xf5g==",
 | 
			
		||||
            "requires": {
 | 
			
		||||
                "@mapbox/node-pre-gyp": "^1.0.0",
 | 
			
		||||
                "node-addon-api": "^4.2.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@
 | 
			
		||||
        "cypress-open": "concurrently -k -r \"node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/\" \"cypress open --config-file ./config/cypress.config.js\""
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@louislam/sqlite3": "~15.0.6",
 | 
			
		||||
        "@louislam/sqlite3": "15.1.2",
 | 
			
		||||
        "args-parser": "~1.3.0",
 | 
			
		||||
        "axios": "~0.27.0",
 | 
			
		||||
        "axios-ntlm": "~1.3.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -537,6 +537,17 @@ class Monitor extends BeanModel {
 | 
			
		||||
                    bean.ping = dayjs().valueOf() - startTime;
 | 
			
		||||
                } else if (this.type === "radius") {
 | 
			
		||||
                    let startTime = dayjs().valueOf();
 | 
			
		||||
 | 
			
		||||
                    // Handle monitors that were created before the
 | 
			
		||||
                    // update and as such don't have a value for
 | 
			
		||||
                    // this.port.
 | 
			
		||||
                    let port;
 | 
			
		||||
                    if (this.port == null) {
 | 
			
		||||
                        port = 1812;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        port = this.port;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        const resp = await radius(
 | 
			
		||||
                            this.hostname,
 | 
			
		||||
@@ -544,7 +555,8 @@ class Monitor extends BeanModel {
 | 
			
		||||
                            this.radiusPassword,
 | 
			
		||||
                            this.radiusCalledStationId,
 | 
			
		||||
                            this.radiusCallingStationId,
 | 
			
		||||
                            this.radiusSecret
 | 
			
		||||
                            this.radiusSecret,
 | 
			
		||||
                            port
 | 
			
		||||
                        );
 | 
			
		||||
                        if (resp.code) {
 | 
			
		||||
                            bean.msg = resp.code;
 | 
			
		||||
 
 | 
			
		||||
@@ -135,6 +135,7 @@ const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudfl
 | 
			
		||||
const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler");
 | 
			
		||||
const { dockerSocketHandler } = require("./socket-handlers/docker-socket-handler");
 | 
			
		||||
const { maintenanceSocketHandler } = require("./socket-handlers/maintenance-socket-handler");
 | 
			
		||||
const { Settings } = require("./settings");
 | 
			
		||||
 | 
			
		||||
app.use(express.json());
 | 
			
		||||
 | 
			
		||||
@@ -164,7 +165,7 @@ let needSetup = false;
 | 
			
		||||
    await initDatabase(testMode);
 | 
			
		||||
    await server.initAfterDatabaseReady();
 | 
			
		||||
 | 
			
		||||
    exports.entryPage = await setting("entryPage");
 | 
			
		||||
    server.entryPage = await Settings.get("entryPage");
 | 
			
		||||
    await StatusPage.loadDomainMappingList();
 | 
			
		||||
 | 
			
		||||
    log.info("server", "Adding route");
 | 
			
		||||
@@ -185,14 +186,15 @@ let needSetup = false;
 | 
			
		||||
 | 
			
		||||
        log.debug("entry", `Request Domain: ${hostname}`);
 | 
			
		||||
 | 
			
		||||
        const uptimeKumaEntryPage = server.entryPage;
 | 
			
		||||
        if (hostname in StatusPage.domainMappingList) {
 | 
			
		||||
            log.debug("entry", "This is a status page domain");
 | 
			
		||||
 | 
			
		||||
            let slug = StatusPage.domainMappingList[hostname];
 | 
			
		||||
            await StatusPage.handleStatusPageResponse(response, server.indexHTML, slug);
 | 
			
		||||
 | 
			
		||||
        } else if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) {
 | 
			
		||||
            response.redirect("/status/" + exports.entryPage.replace("statusPage-", ""));
 | 
			
		||||
        } else if (uptimeKumaEntryPage && uptimeKumaEntryPage.startsWith("statusPage-")) {
 | 
			
		||||
            response.redirect("/status/" + uptimeKumaEntryPage.replace("statusPage-", ""));
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            response.redirect("/dashboard");
 | 
			
		||||
@@ -209,7 +211,7 @@ let needSetup = false;
 | 
			
		||||
    // Robots.txt
 | 
			
		||||
    app.get("/robots.txt", async (_request, response) => {
 | 
			
		||||
        let txt = "User-agent: *\nDisallow:";
 | 
			
		||||
        if (! await setting("searchEngineIndex")) {
 | 
			
		||||
        if (!await setting("searchEngineIndex")) {
 | 
			
		||||
            txt += " /";
 | 
			
		||||
        }
 | 
			
		||||
        response.setHeader("Content-Type", "text/plain");
 | 
			
		||||
@@ -1098,7 +1100,7 @@ let needSetup = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await setSettings("general", data);
 | 
			
		||||
                exports.entryPage = data.entryPage;
 | 
			
		||||
                server.entryPage = data.entryPage;
 | 
			
		||||
 | 
			
		||||
                // Also need to apply timezone globally
 | 
			
		||||
                if (data.serverTimezone) {
 | 
			
		||||
 
 | 
			
		||||
@@ -292,6 +292,17 @@ exports.postgresQuery = function (connectionString, query) {
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Query radius server
 | 
			
		||||
 * @param {string} hostname Hostname of radius server
 | 
			
		||||
 * @param {string} username Username to use
 | 
			
		||||
 * @param {string} password Password to use
 | 
			
		||||
 * @param {string} calledStationId ID of called station
 | 
			
		||||
 * @param {string} callingStationId ID of calling station
 | 
			
		||||
 * @param {string} secret Secret to use
 | 
			
		||||
 * @param {number} [port=1812] Port to contact radius server on
 | 
			
		||||
 * @returns {Promise<any>}
 | 
			
		||||
 */
 | 
			
		||||
exports.radius = function (
 | 
			
		||||
    hostname,
 | 
			
		||||
    username,
 | 
			
		||||
@@ -299,9 +310,11 @@ exports.radius = function (
 | 
			
		||||
    calledStationId,
 | 
			
		||||
    callingStationId,
 | 
			
		||||
    secret,
 | 
			
		||||
    port = 1812,
 | 
			
		||||
) {
 | 
			
		||||
    const client = new radiusClient({
 | 
			
		||||
        host: hostname,
 | 
			
		||||
        hostPort: port,
 | 
			
		||||
        dictionaries: [ file ],
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ export default {
 | 
			
		||||
        /** Should the field auto complete */
 | 
			
		||||
        autocomplete: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: undefined,
 | 
			
		||||
            default: "new-password",
 | 
			
		||||
        },
 | 
			
		||||
        /** Is the input required? */
 | 
			
		||||
        required: {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
        </i18n-t>
 | 
			
		||||
        <input id="clicksendsms-login" v-model="$parent.notification.clicksendsmsLogin" type="text" class="form-control" required>
 | 
			
		||||
        <label for="clicksendsms-key" class="form-label">{{ $t("API Key") }}</label>
 | 
			
		||||
        <HiddenInput id="clicksendsms-key" v-model="$parent.notification.clicksendsmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="clicksendsms-key" v-model="$parent.notification.clicksendsmsPassword" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <div class="form-text">
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="goalert-token" class="form-label">{{ $t("Token") }}</label>
 | 
			
		||||
        <HiddenInput id="goalert-token" v-model="$parent.notification.goAlertToken" autocomplete="one-time-code" :required="true"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="goalert-token" v-model="$parent.notification.goAlertToken" autocomplete="new-password" :required="true"></HiddenInput>
 | 
			
		||||
 | 
			
		||||
        <div class="form-text">
 | 
			
		||||
            {{ $t("goAlertIntegrationKeyInfo") }}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="gotify-application-token" class="form-label">{{ $t("Application Token") }}</label>
 | 
			
		||||
        <HiddenInput id="gotify-application-token" v-model="$parent.notification.gotifyapplicationToken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="gotify-application-token" v-model="$parent.notification.gotifyapplicationToken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="gotify-server-url" class="form-label">{{ $t("Server URL") }}</label>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="line-channel-access-token" class="form-label">{{ $t("Channel access token") }}</label>
 | 
			
		||||
        <HiddenInput id="line-channel-access-token" v-model="$parent.notification.lineChannelAccessToken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="line-channel-access-token" v-model="$parent.notification.lineChannelAccessToken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
    <i18n-t tag="div" keypath="lineDevConsoleTo" class="form-text">
 | 
			
		||||
        <b>{{ $t("Basic Settings") }}</b>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="access-token" class="form-label">{{ $t("Access Token") }}</label><span style="color: red;"><sup>*</sup></span>
 | 
			
		||||
        <HiddenInput id="access-token" v-model="$parent.notification.accessToken" :required="true" autocomplete="one-time-code" :maxlength="500"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="access-token" v-model="$parent.notification.accessToken" :required="true" autocomplete="new-password" :maxlength="500"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="form-text">
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="octopush-key" class="form-label">{{ $t("octopushAPIKey") }}</label>
 | 
			
		||||
        <HiddenInput id="octopush-key" v-model="$parent.notification.octopushAPIKey" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="octopush-key" v-model="$parent.notification.octopushAPIKey" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        <label for="octopush-login" class="form-label">{{ $t("octopushLogin") }}</label>
 | 
			
		||||
        <input id="octopush-login" v-model="$parent.notification.octopushLogin" type="text" class="form-control" required>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
        <label for="promosms-login" class="form-label">{{ $t("promosmsLogin") }}</label>
 | 
			
		||||
        <input id="promosms-login" v-model="$parent.notification.promosmsLogin" type="text" class="form-control" required>
 | 
			
		||||
        <label for="promosms-key" class="form-label">{{ $t("promosmsPassword") }}</label>
 | 
			
		||||
        <HiddenInput id="promosms-key" v-model="$parent.notification.promosmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="promosms-key" v-model="$parent.notification.promosmsPassword" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="promosms-type-sms" class="form-label">{{ $t("SMS Type") }}</label>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="pushdeer-key" class="form-label">{{ $t("PushDeer Key") }}</label>
 | 
			
		||||
        <HiddenInput id="pushdeer-key" v-model="$parent.notification.pushdeerKey" :required="true" autocomplete="one-time-code" placeholder="PDUxxxx"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="pushdeer-key" v-model="$parent.notification.pushdeerKey" :required="true" autocomplete="new-password" placeholder="PDUxxxx"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="pushbullet-access-token" class="form-label">{{ $t("Access Token") }}</label>
 | 
			
		||||
        <HiddenInput id="pushbullet-access-token" v-model="$parent.notification.pushbulletAccessToken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="pushbullet-access-token" v-model="$parent.notification.pushbulletAccessToken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="pushover-user" class="form-label">{{ $t("User Key") }}<span style="color: red;"><sup>*</sup></span></label>
 | 
			
		||||
        <HiddenInput id="pushover-user" v-model="$parent.notification.pushoveruserkey" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="pushover-user" v-model="$parent.notification.pushoveruserkey" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        <label for="pushover-app-token" class="form-label">{{ $t("Application Token") }}<span style="color: red;"><sup>*</sup></span></label>
 | 
			
		||||
        <HiddenInput id="pushover-app-token" v-model="$parent.notification.pushoverapptoken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="pushover-app-token" v-model="$parent.notification.pushoverapptoken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        <label for="pushover-device" class="form-label">{{ $t("Device") }}</label>
 | 
			
		||||
        <input id="pushover-device" v-model="$parent.notification.pushoverdevice" type="text" class="form-control">
 | 
			
		||||
        <label for="pushover-device" class="form-label">{{ $t("Message Title") }}</label>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="pushy-app-token" class="form-label">{{ $t("pushyAPIKey") }}</label>
 | 
			
		||||
        <HiddenInput id="pushy-app-token" v-model="$parent.notification.pushyAPIKey" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="pushy-app-token" v-model="$parent.notification.pushyAPIKey" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="pushy-user-key" class="form-label">{{ $t("pushyToken") }}</label>
 | 
			
		||||
        <div class="input-group mb-3">
 | 
			
		||||
            <HiddenInput id="pushy-user-key" v-model="$parent.notification.pushyToken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
            <HiddenInput id="pushy-user-key" v-model="$parent.notification.pushyToken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
 | 
			
		||||
        <div class="mb-3">
 | 
			
		||||
            <label for="password" class="form-label">{{ $t("Password") }}</label>
 | 
			
		||||
            <HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="false" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
            <HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="false" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="mb-3">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="serverchan-sendkey" class="form-label">{{ $t("SendKey") }}</label>
 | 
			
		||||
        <HiddenInput id="serverchan-sendkey" v-model="$parent.notification.serverChanSendKey" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="serverchan-sendkey" v-model="$parent.notification.serverChanSendKey" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="serwersms-key" class="form-label">{{ $t('serwersmsAPIPassword') }}</label>
 | 
			
		||||
        <HiddenInput id="serwersms-key" v-model="$parent.notification.serwersmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="serwersms-key" v-model="$parent.notification.serwersmsPassword" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="serwersms-phone-number" class="form-label">{{ $t("serwersmsPhoneNumber") }}</label>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="push-api-key" class="form-label">{{ $t("API Key") }}</label>
 | 
			
		||||
        <HiddenInput id="push-api-key" v-model="$parent.notification.pushAPIKey" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="push-api-key" v-model="$parent.notification.pushAPIKey" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="mb-3">
 | 
			
		||||
        <label for="telegram-bot-token" class="form-label">{{ $t("Bot Token") }}</label>
 | 
			
		||||
        <HiddenInput id="telegram-bot-token" v-model="$parent.notification.telegramBotToken" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
			
		||||
        <HiddenInput id="telegram-bot-token" v-model="$parent.notification.telegramBotToken" :required="true" autocomplete="new-password"></HiddenInput>
 | 
			
		||||
        <i18n-t tag="div" keypath="wayToGetTelegramToken" class="form-text">
 | 
			
		||||
            <a href="https://t.me/BotFather" target="_blank">https://t.me/BotFather</a>
 | 
			
		||||
        </i18n-t>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div>
 | 
			
		||||
        <form class="my-4" @submit.prevent="saveGeneral">
 | 
			
		||||
        <form class="my-4" autocomplete="off" @submit.prevent="saveGeneral">
 | 
			
		||||
            <!-- Client side Timezone -->
 | 
			
		||||
            <div class="mb-4">
 | 
			
		||||
                <label for="timezone" class="form-label">
 | 
			
		||||
@@ -122,6 +122,7 @@
 | 
			
		||||
                        name="primaryBaseURL"
 | 
			
		||||
                        placeholder="https://"
 | 
			
		||||
                        pattern="https?://.+"
 | 
			
		||||
                        autocomplete="new-password"
 | 
			
		||||
                    />
 | 
			
		||||
                    <button class="btn btn-outline-primary" type="button" @click="autoGetPrimaryBaseURL">
 | 
			
		||||
                        {{ $t("Auto Get") }}
 | 
			
		||||
@@ -139,7 +140,7 @@
 | 
			
		||||
                <HiddenInput
 | 
			
		||||
                    id="steamAPIKey"
 | 
			
		||||
                    v-model="settings.steamAPIKey"
 | 
			
		||||
                    autocomplete="one-time-code"
 | 
			
		||||
                    autocomplete="new-password"
 | 
			
		||||
                />
 | 
			
		||||
                <div class="form-text">
 | 
			
		||||
                    {{ $t("steamApiKeyDescription") }}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
                <HiddenInput
 | 
			
		||||
                    id="cloudflareTunnelToken"
 | 
			
		||||
                    v-model="cloudflareTunnelToken"
 | 
			
		||||
                    autocomplete="one-time-code"
 | 
			
		||||
                    autocomplete="new-password"
 | 
			
		||||
                    :readonly="running"
 | 
			
		||||
                />
 | 
			
		||||
                <div class="form-text">
 | 
			
		||||
 
 | 
			
		||||
@@ -393,6 +393,12 @@ export default {
 | 
			
		||||
    alertaAlertState: "Состояние алерта",
 | 
			
		||||
    alertaRecoverState: "Состояние восстановления",
 | 
			
		||||
    Proxies: "Прокси",
 | 
			
		||||
    "Setup Proxy": "Настройка Прокси",
 | 
			
		||||
    "Proxy Protocol": "Протокол Прокси",
 | 
			
		||||
    "Proxy Server": "Прокси",
 | 
			
		||||
    "Proxy server has authentication": "Прокси имеет аутентификацию",
 | 
			
		||||
    "Reverse Proxy": "Обратный прокси",
 | 
			
		||||
    "No Proxy": "Без прокси",
 | 
			
		||||
    default: "По умолчанию",
 | 
			
		||||
    enabled: "Включено",
 | 
			
		||||
    setAsDefault: "Установлено по умолчанию",
 | 
			
		||||
@@ -400,4 +406,176 @@ export default {
 | 
			
		||||
    proxyDescription: "Прокси должны быть привязаны к монитору, чтобы работать.",
 | 
			
		||||
    enableProxyDescription: "Этот прокси не будет влиять на запросы монитора, пока не будет активирован. Вы можете контролировать временное отключение прокси для всех мониторов через статус активации.",
 | 
			
		||||
    setAsDefaultProxyDescription: "Этот прокси будет по умолчанию включен для новых мониторов. Вы всё ещё можете отдельно отключать прокси в каждом мониторе.",
 | 
			
		||||
    Invalid: "Недействительный",
 | 
			
		||||
    AccessKeyId: "AccessKey ID",
 | 
			
		||||
    SecretAccessKey: "AccessKey Secret",
 | 
			
		||||
    PhoneNumbers: "PhoneNumbers",
 | 
			
		||||
    TemplateCode: "TemplateCode",
 | 
			
		||||
    SignName: "SignName",
 | 
			
		||||
    "Sms template must contain parameters: ": "Шаблон СМС должен содержать параметры: ",
 | 
			
		||||
    "Bark Endpoint": "Bark Endpoint",
 | 
			
		||||
    "Bark Group": "Bark Group",
 | 
			
		||||
    "Bark Sound": "Bark Sound",
 | 
			
		||||
    WebHookUrl: "WebHookUrl",
 | 
			
		||||
    SecretKey: "SecretKey",
 | 
			
		||||
    "For safety, must use secret key": "В целях безопасности необходимо использовать секретный ключ",
 | 
			
		||||
    "Device Token": "Токен устройства",
 | 
			
		||||
    Platform: "Платформа",
 | 
			
		||||
    iOS: "iOS",
 | 
			
		||||
    Android: "Android",
 | 
			
		||||
    Huawei: "Huawei",
 | 
			
		||||
    High: "High",
 | 
			
		||||
    Retry: "Повторить",
 | 
			
		||||
    Topic: "Тема",
 | 
			
		||||
    "WeCom Bot Key": "WeCom Bot Key",
 | 
			
		||||
    User: "Пользователь",
 | 
			
		||||
    Installed: "Установлено",
 | 
			
		||||
    "Not installed": "Не установлено",
 | 
			
		||||
    Running: "Запускается",
 | 
			
		||||
    "Not running": "Не запускается",
 | 
			
		||||
    "Remove Token": "Удалить токен",
 | 
			
		||||
    Start: "Запустить",
 | 
			
		||||
    Stop: "Остановить",
 | 
			
		||||
    "Uptime Kuma": "Uptime Kuma",
 | 
			
		||||
    Slug: "Slug",
 | 
			
		||||
    "Accept characters:": "Принимаемые символы:",
 | 
			
		||||
    startOrEndWithOnly: "Начинается или кончается только {0}",
 | 
			
		||||
    "No consecutive dashes": "Без последовательных тире",
 | 
			
		||||
    "The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.",
 | 
			
		||||
    "Page Not Found": "Страница не найдена",
 | 
			
		||||
    wayToGetCloudflaredURL: "(Скачать cloudflared с {0})",
 | 
			
		||||
    cloudflareWebsite: "Cloudflare Website",
 | 
			
		||||
    "Message:": "Сообщение:",
 | 
			
		||||
    "Don't know how to get the token? Please read the guide:": "Don't know how to get the token? Please read the guide:",
 | 
			
		||||
    "The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.",
 | 
			
		||||
    "HTTP Headers": "HTTP заголовки",
 | 
			
		||||
    "Trust Proxy": "Доверять прокси",
 | 
			
		||||
    "Other Software": "Другое программное обеспечение",
 | 
			
		||||
    "For example: nginx, Apache and Traefik.": "К примеру: nginx, Apache и Traefik.",
 | 
			
		||||
    "Please read": "Пожалуйста, прочитайте",
 | 
			
		||||
    "Subject:": "Тема:",
 | 
			
		||||
    "Valid To:": "Действителен до:",
 | 
			
		||||
    "Days Remaining:": "Дней осталось:",
 | 
			
		||||
    "Issuer:": "Издатель:",
 | 
			
		||||
    "Fingerprint:": "Отпечаток:",
 | 
			
		||||
    "No status pages": "Нет статусных страниц",
 | 
			
		||||
    "Domain Name Expiry Notification": "Уведомление об истечении срока действия доменного имени",
 | 
			
		||||
    Proxy: "Прокси",
 | 
			
		||||
    "Date Created": "Дата создания",
 | 
			
		||||
    HomeAssistant: "Home Assistant",
 | 
			
		||||
    onebotHttpAddress: "OneBot HTTP Address",
 | 
			
		||||
    onebotMessageType: "OneBot Message Type",
 | 
			
		||||
    onebotGroupMessage: "Группа",
 | 
			
		||||
    onebotPrivateMessage: "Private",
 | 
			
		||||
    onebotUserOrGroupId: "Группа/ID пользователя",
 | 
			
		||||
    onebotSafetyTips: "В целях безопасности необходимо установить токен доступа",
 | 
			
		||||
    "PushDeer Key": "PushDeer Key",
 | 
			
		||||
    "Footer Text": "Текст нижнего колонтитула",
 | 
			
		||||
    "Show Powered By": "Показывать на чем создано",
 | 
			
		||||
    "Domain Names": "Доменные имена",
 | 
			
		||||
    signedInDisp: "Вы вошли как {0}",
 | 
			
		||||
    signedInDispDisabled: "Аутентификация отключена.",
 | 
			
		||||
    RadiusSecret: "Секрет Radius",
 | 
			
		||||
    RadiusSecretDescription: "Общий секрет между клиентом и сервером",
 | 
			
		||||
    RadiusCalledStationId: "Идентификатор вызываемой станции",
 | 
			
		||||
    RadiusCalledStationIdDescription: "Идентификатор вызываемого устройства",
 | 
			
		||||
    RadiusCallingStationId: "Идентификатор вызывающей станции",
 | 
			
		||||
    RadiusCallingStationIdDescription: "Идентификатор вызывающего устройства",
 | 
			
		||||
    "Certificate Expiry Notification": "Уведомление об истечении срока действия сертификата",
 | 
			
		||||
    "API Username": "Имя пользователя API",
 | 
			
		||||
    "API Key": "API ключ",
 | 
			
		||||
    "Recipient Number": "Номер получателя",
 | 
			
		||||
    "From Name/Number": "Имя/номер отправителя",
 | 
			
		||||
    "Leave blank to use a shared sender number.": "Оставьте пустым, чтобы использовать общий номер отправителя.",
 | 
			
		||||
    "Octopush API Version": "Версия API Octopush",
 | 
			
		||||
    "Legacy Octopush-DM": "Legacy Octopush-DM",
 | 
			
		||||
    endpoint: "endpoint",
 | 
			
		||||
    octopushAPIKey: "\"API key\" из учетных данных HTTP API в панели управления",
 | 
			
		||||
    octopushLogin: "\"Login\" из учетных данных HTTP API в панели управления",
 | 
			
		||||
    promosmsLogin: "Логин API",
 | 
			
		||||
    promosmsPassword: "Пароль API",
 | 
			
		||||
    "pushoversounds pushover": "Pushover (default)",
 | 
			
		||||
    "pushoversounds bike": "Bike",
 | 
			
		||||
    "pushoversounds bugle": "Bugle",
 | 
			
		||||
    "pushoversounds cashregister": "Cash Register",
 | 
			
		||||
    "pushoversounds classical": "Classical",
 | 
			
		||||
    "pushoversounds cosmic": "Cosmic",
 | 
			
		||||
    "pushoversounds falling": "Falling",
 | 
			
		||||
    "pushoversounds gamelan": "Gamelan",
 | 
			
		||||
    "pushoversounds incoming": "Incoming",
 | 
			
		||||
    "pushoversounds intermission": "Intermission",
 | 
			
		||||
    "pushoversounds magic": "Magic",
 | 
			
		||||
    "pushoversounds mechanical": "Mechanical",
 | 
			
		||||
    "pushoversounds pianobar": "Piano Bar",
 | 
			
		||||
    "pushoversounds siren": "Siren",
 | 
			
		||||
    "pushoversounds spacealarm": "Space Alarm",
 | 
			
		||||
    "pushoversounds tugboat": "Tug Boat",
 | 
			
		||||
    "pushoversounds alien": "Alien Alarm (long)",
 | 
			
		||||
    "pushoversounds climb": "Climb (long)",
 | 
			
		||||
    "pushoversounds persistent": "Persistent (long)",
 | 
			
		||||
    "pushoversounds echo": "Pushover Echo (long)",
 | 
			
		||||
    "pushoversounds updown": "Up Down (long)",
 | 
			
		||||
    "pushoversounds vibrate": "Vibrate Only",
 | 
			
		||||
    "pushoversounds none": "None (silent)",
 | 
			
		||||
    pushyAPIKey: "Secret API Key",
 | 
			
		||||
    pushyToken: "Токен устройства",
 | 
			
		||||
    "Using a Reverse Proxy?": "Используете обратный прокси?",
 | 
			
		||||
    "Check how to config it for WebSocket": "Проверьте, как настроить его для WebSocket",
 | 
			
		||||
    "Steam Game Server": "Steam Game Server",
 | 
			
		||||
    "Most likely causes:": "Наиболее вероятные причины:",
 | 
			
		||||
    "The resource is no longer available.": "Ресурс больше не доступен.",
 | 
			
		||||
    "There might be a typing error in the address.": "В адресе может быть опечатка.",
 | 
			
		||||
    "What you can try:": "Что вы можете попробовать:",
 | 
			
		||||
    "Retype the address.": "Повторите адрес.",
 | 
			
		||||
    "Go back to the previous page.": "Вернуться на предыдущую страницу.",
 | 
			
		||||
    "Coming Soon": "Скоро",
 | 
			
		||||
    wayToGetClickSendSMSToken: "Вы можете получить имя пользователя API и ключ API из {0} .",
 | 
			
		||||
    "Connection String": "Строка подключения",
 | 
			
		||||
    Query: "Запрос",
 | 
			
		||||
    settingsCertificateExpiry: "Истекание TLS сертификата",
 | 
			
		||||
    certificationExpiryDescription: "HTTPS Мониторы инициируют уведомление, когда срок действия сертификата TLS истечет:",
 | 
			
		||||
    "Setup Docker Host": "Настроить Docker Host",
 | 
			
		||||
    "Connection Type": "Тип соединения",
 | 
			
		||||
    "Docker Daemon": "Docker Daemon",
 | 
			
		||||
    deleteDockerHostMsg: "Are you sure want to delete this docker host for all monitors?",
 | 
			
		||||
    socket: "Socket",
 | 
			
		||||
    tcp: "TCP / HTTP",
 | 
			
		||||
    "Docker Container": "Docker контейнер",
 | 
			
		||||
    "Container Name / ID": "Название контейнера / ID",
 | 
			
		||||
    "Docker Host": "Docker Host",
 | 
			
		||||
    "Docker Hosts": "Docker Hosts",
 | 
			
		||||
    "ntfy Topic": "ntfy Topic",
 | 
			
		||||
    Domain: "Домен",
 | 
			
		||||
    Workstation: "Workstation",
 | 
			
		||||
    disableCloudflaredNoAuthMsg: "Вы находитесь в режиме без авторизации, пароль не требуется.",
 | 
			
		||||
    trustProxyDescription: "Доверять заголовкам 'X-Forwarded-*'. Если вы хотите получить правильный IP-адрес клиента, а ваш Uptime Kuma находится под Nginx или Apache, вам следует включить этот параметр.",
 | 
			
		||||
    wayToGetLineNotifyToken: "Вы можете получить токен доступа в {0}",
 | 
			
		||||
    Examples: "Примеры",
 | 
			
		||||
    "Home Assistant URL": "Home Assistant URL",
 | 
			
		||||
    "Long-Lived Access Token": "Токен доступа с длительным сроком службы",
 | 
			
		||||
    "Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ",
 | 
			
		||||
    "Notification Service": "Служба уведомлений",
 | 
			
		||||
    "default: notify all devices": "по стандарту: уведомлять все устройства",
 | 
			
		||||
    "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.",
 | 
			
		||||
    "Automations can optionally be triggered in Home Assistant:": "При желании автоматизацию можно активировать в Home Assistant.:",
 | 
			
		||||
    "Trigger type:": "Тип триггера:",
 | 
			
		||||
    "Event type:": "Тип события:",
 | 
			
		||||
    "Event data:": "Данные события:",
 | 
			
		||||
    "Then choose an action, for example switch the scene to where an RGB light is red.": "Затем выберите действие, например, переключите сцену на красный индикатор RGB..",
 | 
			
		||||
    "Frontend Version": "Версия интерфейса",
 | 
			
		||||
    "Frontend Version do not match backend version!": "Версия интерфейса не соответствует версии серверной части!",
 | 
			
		||||
    "Base URL": "Базовый URL",
 | 
			
		||||
    goAlertInfo: "GoAlert is a An open source application for on-call scheduling, automated escalations and notifications (like SMS or voice calls). Automatically engage the right person, the right way, and at the right time! {0}",
 | 
			
		||||
    goAlertIntegrationKeyInfo: "Получить общий ключ интеграции API для сервиса в этом формате \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" обычно значение параметра токена скопированного URL.",
 | 
			
		||||
    goAlert: "GoAlert",
 | 
			
		||||
    backupOutdatedWarning: "Устарело: поскольку добавлено множество функций, а эта функция резервного копирования немного не поддерживается, она не может создать или восстановить полную резервную копию.",
 | 
			
		||||
    backupRecommend: "Сделайте резервную копию тома или папки с данными (./data/) напрямую.",
 | 
			
		||||
    "Optional": "Необязательно",
 | 
			
		||||
    squadcast: "Squadcast",
 | 
			
		||||
    SendKey: "SendKey",
 | 
			
		||||
    "SMSManager API Docs": "Документация к API SMSManager ",
 | 
			
		||||
    "Gateway Type": "Тип шлюза",
 | 
			
		||||
    SMSManager: "SMSManager",
 | 
			
		||||
    "You can divide numbers with": "Вы можете делить числа с",
 | 
			
		||||
    "or": "или",
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -97,8 +97,8 @@
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <!-- Port -->
 | 
			
		||||
                            <!-- For TCP Port / Steam / MQTT Type -->
 | 
			
		||||
                            <div v-if="monitor.type === 'port' || monitor.type === 'steam' || monitor.type === 'mqtt'" class="my-3">
 | 
			
		||||
                            <!-- For TCP Port / Steam / MQTT / Radius Type -->
 | 
			
		||||
                            <div v-if="monitor.type === 'port' || monitor.type === 'steam' || monitor.type === 'mqtt' || monitor.type === 'radius'" class="my-3">
 | 
			
		||||
                                <label for="port" class="form-label">{{ $t("Port") }}</label>
 | 
			
		||||
                                <input id="port" v-model="monitor.port" type="number" class="form-control" required min="0" max="65535" step="1">
 | 
			
		||||
                            </div>
 | 
			
		||||
@@ -616,9 +616,11 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Set default port for DNS if not already defined
 | 
			
		||||
            if (! this.monitor.port || this.monitor.port === "53") {
 | 
			
		||||
            if (! this.monitor.port || this.monitor.port === "53" || this.monitor.port === "1812") {
 | 
			
		||||
                if (this.monitor.type === "dns") {
 | 
			
		||||
                    this.monitor.port = "53";
 | 
			
		||||
                } else if (this.monitor.type === "radius") {
 | 
			
		||||
                    this.monitor.port = "1812";
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.monitor.port = undefined;
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user