Merge branch 'master' into feature/expand-http-payload-support

pull/1987/head
Justin Tisdale 2 years ago
commit 0814d643c1

@ -1,6 +1,7 @@
/.idea /.idea
/node_modules /node_modules
/data /data
/cypress
/out /out
/test /test
/kubernetes /kubernetes

@ -1,4 +1,8 @@
👉 Delete this line if you have read and agree our pull request rules and guidelines: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma ⚠️⚠️⚠️ Since we do not accept all types of pull requests and do not want to waste your time. Please be sure that you have read pull request rules:
https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma
Tick the checkbox if you understand [x]:
- [ ] I have read and understand the pull request rules.
# Description # Description

@ -50,3 +50,19 @@ jobs:
cache: 'npm' cache: 'npm'
- run: npm install - run: npm install
- run: npm run lint - run: npm run lint
e2e-tests:
needs: [ check-linters ]
runs-on: ubuntu-latest
steps:
- run: git config --global core.autocrlf false # Mainly for Windows
- uses: actions/checkout@v3
- name: Use Node.js 14
uses: actions/setup-node@v3
with:
node-version: 14
cache: 'npm'
- run: npm install
- run: npm run build
- run: npm run cy:test

@ -0,0 +1,24 @@
name: 'Automatically close stale issues and PRs'
on:
workflow_dispatch:
schedule:
- cron: '0 */6 * * *'
#Run every 6 hours
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v5
with:
stale-issue-message: 'We are clearing up our old issues and your ticket has been open for 3 months with no activity. Remove stale label or comment or this will be closed in 2 days.'
stale-pr-message: 'We are clearing up our old Pull Requests and yours has been open for 3 months with no activity. Remove stale label or comment or this will be closed in 2 days.'
close-issue-message: 'This issue was closed because it has been stalled for 2 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for 2 days with no activity.'
days-before-stale: 90
days-before-close: 2
exempt-issue-labels: 'News,Medium,High,discussion,bug,doc,feature-request'
exempt-pr-labels: 'awaiting-approval,work-in-progress,enhancement,feature-request'
exempt-issue-assignees: 'louislam'
exempt-pr-assignees: 'louislam'
operations-per-run: 200

3
.gitignore vendored

@ -13,3 +13,6 @@ dist-ssr
/out /out
/tmp /tmp
.env .env
cypress/videos
cypress/screenshots

@ -27,13 +27,11 @@ The frontend code build into "dist" directory. The server (express.js) exposes t
## Can I create a pull request for Uptime Kuma? ## Can I create a pull request for Uptime Kuma?
Yes, you can. However, since I don't want to waste your time, be sure to **create empty draft pull request, so we can discuss first** if it is a large pull request or you don't know it will be merged or not. Yes or no, it depends on what you will try to do. Since I don't want to waste your time, be sure to **create empty draft pull request or open an issue, so we can discuss first**. Especially for a large pull request or you don't know it will be merged or not.
Also, please don't rush or ask for ETA, because I have to understand the pull request, make sure it is no breaking changes and stick to my vision of this project, especially for large pull requests. Here are some references:
I will mark your pull request in the [milestones](https://github.com/louislam/uptime-kuma/milestones), if I am plan to review and merge it.
✅ Accept: ✅ Usually Accept:
- Bug/Security fix - Bug/Security fix
- Translations - Translations
- Adding notification providers - Adding notification providers
@ -47,8 +45,14 @@ I will mark your pull request in the [milestones](https://github.com/louislam/up
- Any breaking changes - Any breaking changes
- Duplicated pull request - Duplicated pull request
- Buggy - Buggy
- UI/UX is not close to Uptime Kuma
- Existing logic is completely modified or deleted for no reason - Existing logic is completely modified or deleted for no reason
- A function that is completely out of scope - A function that is completely out of scope
- Unnesscary large code changes (Hard to review, casuse code conflicts to other pull requests)
I will mark your pull request in the [milestones](https://github.com/louislam/uptime-kuma/milestones), if I am plan to review and merge it.
Also, please don't rush or ask for ETA, because I have to understand the pull request, make sure it is no breaking changes and stick to my vision of this project, especially for large pull requests.
### Recommended Pull Request Guideline ### Recommended Pull Request Guideline
@ -177,7 +181,18 @@ npm test
By default, the Chromium window will be shown up during the test. Specifying `HEADLESS_TEST=1` for terminal environments. By default, the Chromium window will be shown up during the test. Specifying `HEADLESS_TEST=1` for terminal environments.
## Update Dependencies ## Dependencies
Both frontend and backend share the same package.json. However, the frontend dependencies are eventually not be used in production environment, because it is usually also baked into dist files. So:
- Frontend dependencies = "devDependencies"
- Examples: vue, chart.js
- Backend dependencies = "dependencies"
- Examples: socket.io, sqlite3
- Development dependencies = "devDependencies"
- Examples: eslint, sass
### Update Dependencies
Install `ncu` Install `ncu`
https://github.com/raineorshine/npm-check-updates https://github.com/raineorshine/npm-check-updates

@ -106,7 +106,7 @@ https://github.com/louislam/uptime-kuma/milestones
Project Plan: Project Plan:
https://github.com/louislam/uptime-kuma/projects/1 https://github.com/users/louislam/projects/4/views/1
## ❤️ Sponsors ## ❤️ Sponsors
@ -157,7 +157,14 @@ You can mention me if you ask a question on Reddit.
## Contribute ## Contribute
### Beta Version ### Test Pull Requests
There are a lot of pull requests right now, but I don't have time to test them all.
If you want to help, you can check this:
https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests
### Test Beta Version
Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases
@ -169,5 +176,5 @@ If you want to translate Uptime Kuma into your language, please read: https://gi
Feel free to correct my grammar in this README, source code, or wiki, as my mother language is not English and my grammar is not that great. Feel free to correct my grammar in this README, source code, or wiki, as my mother language is not English and my grammar is not that great.
### Pull Requests ### Create Pull Requests
If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md If you want to modify Uptime Kuma, please read this guide and follow the rules here: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md

@ -11,6 +11,9 @@ const viteCompressionFilter = /\.(js|mjs|json|css|html|svg)$/i;
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
server: {
port: 3000,
},
define: { define: {
"FRONTEND_VERSION": JSON.stringify(process.env.npm_package_version), "FRONTEND_VERSION": JSON.stringify(process.env.npm_package_version),
}, },

@ -0,0 +1,15 @@
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:3002",
defaultCommandTimeout: 10000,
pageLoadTimeout: 60000,
viewportWidth: 1920,
viewportHeight: 1080,
specPattern: ["cypress/e2e/setup.cy.ts", "cypress/e2e/**/*.ts"],
},
env: {
baseUrl: "http://localhost:3002",
},
});

@ -0,0 +1,24 @@
import { actor } from "../support/actors/actor";
import { DEFAULT_USER_DATA } from "../support/const/user-data";
import { DashboardPage } from "../support/pages/dasboard-page";
import { SetupPage } from "../support/pages/setup-page";
describe("user can create a new account on setup page", () => {
before(() => {
cy.visit("/setup");
});
it("user can create new account", () => {
cy.url().should("be.equal", SetupPage.url);
actor.setupTask.fillAndSubmitSetupForm(
DEFAULT_USER_DATA.username,
DEFAULT_USER_DATA.password,
DEFAULT_USER_DATA.password
);
cy.url().should("be.equal", DashboardPage.url);
cy.get('[role="alert"]')
.should("be.visible")
.and("contain.text", "Added Successfully.");
});
});

@ -0,0 +1,8 @@
import { SetupTask } from "../tasks/setup-task";
class Actor {
setupTask: SetupTask = new SetupTask();
}
const actor = new Actor();
export { actor };

@ -0,0 +1,4 @@
export const DEFAULT_USER_DATA = {
username: "testuser",
password: "testuser123",
};

@ -0,0 +1 @@
import "./commands";

@ -0,0 +1,3 @@
export const DashboardPage = {
url: Cypress.env("baseUrl") + "/dashboard",
};

@ -0,0 +1,7 @@
export const SetupPage = {
url: Cypress.env("baseUrl") + "/setup",
usernameInput: '[data-cy="username-input"]',
passWordInput: '[data-cy="password-input"]',
passwordRepeatInput: '[data-cy="password-repeat-input"]',
submitSetupForm: '[data-cy="submit-setup-form"]',
};

@ -0,0 +1,15 @@
import { SetupPage } from "../pages/setup-page";
export class SetupTask {
fillAndSubmitSetupForm(
username: string,
password: string,
passwordRepeat: string
) {
cy.get(SetupPage.usernameInput).type(username);
cy.get(SetupPage.passWordInput).type(password);
cy.get(SetupPage.passwordRepeatInput).type(passwordRepeat);
cy.get(SetupPage.submitSetupForm).click();
}
}

@ -24,6 +24,36 @@ CMD ["node", "server/server.js"]
FROM release AS nightly FROM release AS nightly
RUN npm run mark-as-nightly RUN npm run mark-as-nightly
# Build an image for testing pr
FROM louislam/uptime-kuma:base-debian AS pr-test
WORKDIR /app
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
## Install Git
RUN apt update \
&& apt --yes --no-install-recommends install curl \
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt update \
&& apt --yes --no-install-recommends install git
## Empty the directory, because we have to clone the Git repo.
RUN rm -rf ./* && chown node /app
USER node
RUN git config --global user.email "no-reply@no-reply.com"
RUN git config --global user.name "PR Tester"
RUN git clone https://github.com/louislam/uptime-kuma.git .
RUN npm ci
EXPOSE 3000 3001
VOLUME ["/app/data"]
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js
CMD ["npm", "run", "start-pr-test"]
# Upload the artifact to Github # Upload the artifact to Github
FROM louislam/uptime-kuma:base-debian AS upload-artifact FROM louislam/uptime-kuma:base-debian AS upload-artifact

@ -0,0 +1,33 @@
const childProcess = require("child_process");
if (!process.env.UPTIME_KUMA_GH_REPO) {
console.error("Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)");
process.exit(1);
}
let inputArray = process.env.UPTIME_KUMA_GH_REPO.split(":");
if (inputArray.length !== 2) {
console.error("Invalid format. Please set a repo to the environment variable 'UPTIME_KUMA_GH_REPO' (e.g. mhkarimi1383:goalert-notification)");
}
let name = inputArray[0];
let branch = inputArray[1];
console.log("Checkout pr");
// Checkout the pr
let result = childProcess.spawnSync("git", [ "remote", "add", name, `https://github.com/${name}/uptime-kuma` ]);
console.log(result.stdout.toString());
console.error(result.stderr.toString());
result = childProcess.spawnSync("git", [ "fetch", name, branch ]);
console.log(result.stdout.toString());
console.error(result.stderr.toString());
result = childProcess.spawnSync("git", [ "checkout", `${name}/${branch}`, "--force" ]);
console.log(result.stdout.toString());
console.error(result.stderr.toString());

5451
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -38,6 +38,7 @@
"build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push", "build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push",
"build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push", "build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push",
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain", "build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", "upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"setup": "git checkout 1.18.0 && npm ci --production && npm run download-dist", "setup": "git checkout 1.18.0 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js", "download-dist": "node extra/download-dist.js",
@ -58,12 +59,15 @@
"release-final": "node extra/update-version.js && npm run build-docker && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js", "release-final": "node extra/update-version.js && npm run build-docker && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js",
"release-beta": "node extra/beta/update-version.js && npm run build && node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:beta . --target release --push && node ./extra/press-any-key.js && npm run upload-artifacts", "release-beta": "node extra/beta/update-version.js && npm run build && node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:beta . --target release --push && node ./extra/press-any-key.js && npm run upload-artifacts",
"git-remove-tag": "git tag -d", "git-remove-tag": "git tag -d",
"build-dist-and-restart": "npm run build && npm run start-server-dev" "build-dist-and-restart": "npm run build && npm run start-server-dev",
"start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev",
"cy:test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --e2e",
"cy:run": "npx cypress run --browser chrome --headless"
}, },
"dependencies": { "dependencies": {
"@louislam/sqlite3": "~15.0.6", "@louislam/sqlite3": "~15.0.6",
"args-parser": "~1.3.0", "args-parser": "~1.3.0",
"axios": "~0.26.1", "axios": "~0.27.0",
"axios-ntlm": "^1.3.0", "axios-ntlm": "^1.3.0",
"badge-maker": "^3.3.1", "badge-maker": "^3.3.1",
"bcryptjs": "~2.4.3", "bcryptjs": "~2.4.3",
@ -117,8 +121,8 @@
"@fortawesome/vue-fontawesome": "~3.0.0-5", "@fortawesome/vue-fontawesome": "~3.0.0-5",
"@popperjs/core": "~2.10.2", "@popperjs/core": "~2.10.2",
"@types/bootstrap": "~5.1.9", "@types/bootstrap": "~5.1.9",
"@vitejs/plugin-legacy": "~1.8.2", "@vitejs/plugin-legacy": "~2.1.0",
"@vitejs/plugin-vue": "~2.3.3", "@vitejs/plugin-vue": "~3.1.0",
"@vue/compiler-sfc": "~3.2.36", "@vue/compiler-sfc": "~3.2.36",
"aedes": "^0.46.3", "aedes": "^0.46.3",
"babel-plugin-rewire": "~1.2.0", "babel-plugin-rewire": "~1.2.0",
@ -128,15 +132,17 @@
"concurrently": "^7.1.0", "concurrently": "^7.1.0",
"core-js": "~3.18.3", "core-js": "~3.18.3",
"cross-env": "~7.0.3", "cross-env": "~7.0.3",
"cypress": "^10.1.0",
"delay": "^5.0.0",
"dns2": "~2.0.1", "dns2": "~2.0.1",
"eslint": "~8.14.0", "eslint": "~8.14.0",
"eslint-plugin-vue": "~8.7.1", "eslint-plugin-vue": "~8.7.1",
"favico.js": "^0.3.10", "favico.js": "^0.3.10",
"jest": "~27.2.5", "jest": "~27.2.5",
"jest-puppeteer": "~6.0.3", "jest-puppeteer": "~6.0.3",
"postcss-html": "^1.3.1", "postcss-html": "~1.5.0",
"postcss-rtlcss": "~3.4.1", "postcss-rtlcss": "~3.7.2",
"postcss-scss": "~4.0.3", "postcss-scss": "~4.0.4",
"prismjs": "^1.27.0", "prismjs": "^1.27.0",
"puppeteer": "~13.1.3", "puppeteer": "~13.1.3",
"qrcode": "~1.5.0", "qrcode": "~1.5.0",
@ -144,10 +150,11 @@
"sass": "~1.42.1", "sass": "~1.42.1",
"stylelint": "~14.7.1", "stylelint": "~14.7.1",
"stylelint-config-standard": "~25.0.0", "stylelint-config-standard": "~25.0.0",
"terser": "^5.15.0",
"timezones-list": "~3.0.1", "timezones-list": "~3.0.1",
"typescript": "~4.4.4", "typescript": "~4.4.4",
"v-pagination-3": "~0.1.7", "v-pagination-3": "~0.1.7",
"vite": "~2.9.9", "vite": "~3.1.0",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vue": "next", "vue": "next",
"vue-chart-3": "3.0.9", "vue-chart-3": "3.0.9",

@ -28,17 +28,17 @@ class Bark extends NotificationProvider {
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) {
let title = "UptimeKuma Monitor Up"; let title = "UptimeKuma Monitor Up";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
} }
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
let title = "UptimeKuma Monitor Down"; let title = "UptimeKuma Monitor Down";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
} }
if (msg != null) { if (msg != null) {
let title = "UptimeKuma Message"; let title = "UptimeKuma Message";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
} }
} }
@ -50,7 +50,7 @@ class Bark extends NotificationProvider {
*/ */
appendAdditionalParameters(notification, postUrl) { appendAdditionalParameters(notification, postUrl) {
// set icon to uptime kuma icon, 11kb should be fine // set icon to uptime kuma icon, 11kb should be fine
postUrl += "&icon=" + barkNotificationAvatar; postUrl += "?icon=" + barkNotificationAvatar;
// grouping all our notifications // grouping all our notifications
if (notification.barkGroup != null) { if (notification.barkGroup != null) {
postUrl += "&group=" + notification.barkGroup; postUrl += "&group=" + notification.barkGroup;
@ -89,12 +89,12 @@ class Bark extends NotificationProvider {
* @param {string} endpoint Endpoint to send request to * @param {string} endpoint Endpoint to send request to
* @returns {string} * @returns {string}
*/ */
async postNotification(title, subtitle, endpoint) { async postNotification(notification, title, subtitle, endpoint) {
// url encode title and subtitle // url encode title and subtitle
title = encodeURIComponent(title); title = encodeURIComponent(title);
subtitle = encodeURIComponent(subtitle); subtitle = encodeURIComponent(subtitle);
let postUrl = endpoint + "/" + title + "/" + subtitle; let postUrl = endpoint + "/" + title + "/" + subtitle;
postUrl = this.appendAdditionalParameters(postUrl); postUrl = this.appendAdditionalParameters(notification, postUrl);
let result = await axios.get(postUrl); let result = await axios.get(postUrl);
this.checkResult(result); this.checkResult(result);
if (result.statusText != null) { if (result.statusText != null) {

@ -0,0 +1,35 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP } = require("../../src/util");
class GoAlert extends NotificationProvider {
name = "GoAlert";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let closeAction = "close";
let data = {
summary: msg,
};
if (heartbeatJSON != null && heartbeatJSON["status"] === UP) {
data["action"] = closeAction;
}
let headers = {
"Content-Type": "multipart/form-data",
};
let config = {
headers: headers
};
await axios.post(`${notification.goAlertBaseURL}/api/v2/generic/incoming?token=${notification.goAlertToken}`, data, config);
return okMsg;
} catch (error) {
let msg = (error.response.data) ? error.response.data : "Error without response";
throw new Error(msg);
}
}
}
module.exports = GoAlert;

@ -0,0 +1,36 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { DOWN, UP } = require("../../src/util");
class ServerChan extends NotificationProvider {
name = "ServerChan";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
await axios.post(`https://sctapi.ftqq.com/${notification.serverChanSendKey}.send`, {
"title": this.checkStatus(heartbeatJSON, monitorJSON),
"desp": msg,
});
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
checkStatus(heartbeatJSON, monitorJSON) {
let title = "UptimeKuma Message";
if (heartbeatJSON != null && heartbeatJSON["status"] === UP) {
title = "UptimeKuma Monitor Up " + monitorJSON["name"];
}
if (heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
title = "UptimeKuma Monitor Down " + monitorJSON["name"];
}
return title;
}
}
module.exports = ServerChan;

@ -0,0 +1,25 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class SMSManager extends NotificationProvider {
name = "SMSManager";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
try {
let data = {
apikey: notification.smsmanagerApiKey,
endpoint: "https://http-api.smsmanager.cz/Send",
message: msg.replace(/[^\x00-\x7F]/g, ""),
to: notification.numbers,
messageType: notification.messageType,
};
await axios.get(`${data.endpoint}?apikey=${data.apikey}&message=${data.message}&number=${data.to}&gateway=${data.messageType}`);
return "SMS sent sucessfully.";
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = SMSManager;

@ -38,6 +38,9 @@ const TechulusPush = require("./notification-providers/techulus-push");
const Telegram = require("./notification-providers/telegram"); const Telegram = require("./notification-providers/telegram");
const Webhook = require("./notification-providers/webhook"); const Webhook = require("./notification-providers/webhook");
const WeCom = require("./notification-providers/wecom"); const WeCom = require("./notification-providers/wecom");
const GoAlert = require("./notification-providers/goalert");
const SMSManager = require("./notification-providers/smsmanager");
const ServerChan = require("./notification-providers/serverchan");
class Notification { class Notification {
@ -78,8 +81,10 @@ class Notification {
new Pushover(), new Pushover(),
new Pushy(), new Pushy(),
new RocketChat(), new RocketChat(),
new ServerChan(),
new SerwerSMS(), new SerwerSMS(),
new Signal(), new Signal(),
new SMSManager(),
new Slack(), new Slack(),
new SMTP(), new SMTP(),
new Stackfield(), new Stackfield(),
@ -88,6 +93,7 @@ class Notification {
new Telegram(), new Telegram(),
new Webhook(), new Webhook(),
new WeCom(), new WeCom(),
new GoAlert(),
]; ];
for (let item of list) { for (let item of list) {

@ -61,7 +61,7 @@ log.info("server", "Importing this project modules");
log.debug("server", "Importing Monitor"); log.debug("server", "Importing Monitor");
const Monitor = require("./model/monitor"); const Monitor = require("./model/monitor");
log.debug("server", "Importing Settings"); log.debug("server", "Importing Settings");
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword } = require("./util-server"); const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests } = require("./util-server");
log.debug("server", "Importing Notification"); log.debug("server", "Importing Notification");
const { Notification } = require("./notification"); const { Notification } = require("./notification");
@ -112,6 +112,7 @@ const twoFAVerifyOptions = {
* @type {boolean} * @type {boolean}
*/ */
const testMode = !!args["test"] || false; const testMode = !!args["test"] || false;
const e2eTestMode = !!args["e2e"] || false;
if (config.demoMode) { if (config.demoMode) {
log.info("server", "==== Demo Mode ===="); log.info("server", "==== Demo Mode ====");
@ -1487,6 +1488,10 @@ let needSetup = false;
if (testMode) { if (testMode) {
startUnitTest(); startUnitTest();
} }
if (e2eTestMode) {
startE2eTests();
}
}); });
initBackgroundJobs(args); initBackgroundJobs(args);

@ -573,6 +573,26 @@ exports.startUnitTest = async () => {
}); });
}; };
/** Start end-to-end tests */
exports.startE2eTests = async () => {
console.log("Starting unit test...");
const npm = /^win/.test(process.platform) ? "npm.cmd" : "npm";
const child = childProcess.spawn(npm, [ "run", "cy:run" ]);
child.stdout.on("data", (data) => {
console.log(data.toString());
});
child.stderr.on("data", (data) => {
console.log(data.toString());
});
child.on("close", function (code) {
console.log("Jest exit code: " + code);
process.exit(code);
});
};
/** /**
* Convert unknown string to UTF8 * Convert unknown string to UTF8
* @param {Uint8Array} body Buffer * @param {Uint8Array} body Buffer

@ -403,7 +403,6 @@ optgroup {
.info { .info {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis;
} }
&:hover { &:hover {

@ -54,6 +54,15 @@ export default {
tokenRequired: false, tokenRequired: false,
}; };
}, },
mounted() {
document.title += " - Login";
},
unmounted() {
document.title = document.title.replace(" - Login", "");
},
methods: { methods: {
/** Submit the user details and attempt to log in */ /** Submit the user details and attempt to log in */
submit() { submit() {

@ -44,6 +44,7 @@
:href="monitor.element.url" :href="monitor.element.url"
class="item-name" class="item-name"
target="_blank" target="_blank"
rel="noopener noreferrer"
> >
{{ monitor.element.name }} {{ monitor.element.name }}
</a> </a>

@ -0,0 +1,30 @@
<template>
<div class="mb-3">
<label for="goalert-base-url" class="form-label">{{ $t("Base URL") }}</label>
<div class="input-group mb-3">
<input id="goalert-base-url" v-model="$parent.notification.goAlertBaseURL" type="text" class="form-control" required>
</div>
<i18n-t tag="div" keypath="goAlertInfo" class="form-text">
<a href="https://goalert.me" target="_blank">https://goalert.me</a>
</i18n-t>
</div>
<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>
<div class="form-text">
{{ $t("goAlertIntegrationKeyInfo") }}
</div>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

@ -0,0 +1,31 @@
<template>
<div class="mb-3">
<label for="smsmanager-key" class="form-label">API Key</label>
<div class="form-text">
{{ $t("SMSManager API Docs ") }}
<a href="https://smsmanager.cz/api/http#send" target="_blank">{{ $t("here") }}</a>
</div>
<input id="smsmanager-key" v-model="$parent.notification.smsmanagerApiKey" type="text" class="form-control">
</div>
<div class="mb-3">
<label for="smsmanager-numbers" class="form-label"> {{ $t("Recipients") }}</label>
<div class="form-text">
{{ $t("You can divide numbers with") }} <b>,</b> {{ $t("or") }} <b>;</b>
</div>
<input id="smsmanager-numbers" v-model="$parent.notification.numbers" type="text" class="form-control">
</div>
<div class="mb-3">
<label for="smsmanager-messageType" class="form-label">{{ $t("Gateway Type") }}</label>
<select id="smsmanager-messageType" v-model="$parent.notification.messageType" class="form-select">
<option value="economy">Economy</option>
<option value="lowcost">Lowcost</option>
<option value="high" selected>High</option>
</select>
</div>
<div class="mb-3">
<div class="form-text">
{{ $t("checkPrice", [$t("SMSManager")]) }}
<a href="https://smsmanager.cz/rozesilani-sms/ceny/ceska-republika/" target="_blank">{{ $t("here") }}</a>
</div>
</div>
</template>

@ -0,0 +1,16 @@
<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>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

@ -26,8 +26,10 @@ import PushDeer from "./PushDeer.vue";
import Pushover from "./Pushover.vue"; import Pushover from "./Pushover.vue";
import Pushy from "./Pushy.vue"; import Pushy from "./Pushy.vue";
import RocketChat from "./RocketChat.vue"; import RocketChat from "./RocketChat.vue";
import ServerChan from "./ServerChan.vue";
import SerwerSMS from "./SerwerSMS.vue"; import SerwerSMS from "./SerwerSMS.vue";
import Signal from "./Signal.vue"; import Signal from "./Signal.vue";
import SMSManager from "./SMSManager.vue";
import Slack from "./Slack.vue"; import Slack from "./Slack.vue";
import Stackfield from "./Stackfield.vue"; import Stackfield from "./Stackfield.vue";
import STMP from "./SMTP.vue"; import STMP from "./SMTP.vue";
@ -36,6 +38,7 @@ import TechulusPush from "./TechulusPush.vue";
import Telegram from "./Telegram.vue"; import Telegram from "./Telegram.vue";
import Webhook from "./Webhook.vue"; import Webhook from "./Webhook.vue";
import WeCom from "./WeCom.vue"; import WeCom from "./WeCom.vue";
import GoAlert from "./GoAlert.vue";
/** /**
* Manage all notification form. * Manage all notification form.
@ -74,6 +77,7 @@ const NotificationFormList = {
"rocket.chat": RocketChat, "rocket.chat": RocketChat,
"serwersms": SerwerSMS, "serwersms": SerwerSMS,
"signal": Signal, "signal": Signal,
"SMSManager": SMSManager,
"slack": Slack, "slack": Slack,
"smtp": STMP, "smtp": STMP,
"stackfield": Stackfield, "stackfield": Stackfield,
@ -81,6 +85,8 @@ const NotificationFormList = {
"telegram": Telegram, "telegram": Telegram,
"webhook": Webhook, "webhook": Webhook,
"WeCom": WeCom, "WeCom": WeCom,
"GoAlert": GoAlert,
"ServerChan": ServerChan,
}; };
export default NotificationFormList; export default NotificationFormList;

@ -1,6 +1,12 @@
<template> <template>
<div> <div>
<div class="my-4"> <div class="my-4">
<div class="alert alert-warning" role="alert" style="border-radius: 15px;">
{{ $t("backupOutdatedWarning") }}<br />
<br />
{{ $t("backupRecommend") }}
</div>
<h4 class="mt-4 mb-2">{{ $t("Export Backup") }}</h4> <h4 class="mt-4 mb-2">{{ $t("Export Backup") }}</h4>
<p> <p>

@ -47,10 +47,10 @@ export default {
Down: "Nedostupný", Down: "Nedostupný",
Pending: "Čekám", Pending: "Čekám",
Unknown: "Neznámý", Unknown: "Neznámý",
Pause: "Pozastavit", Pause: "Pozastaveno",
Name: "Název", Name: "Název",
Status: "Stav", Status: "Stav",
DateTime: "DateTime", DateTime: "Časové razítko",
Message: "Zpráva", Message: "Zpráva",
"No important events": "Žádné důležité události", "No important events": "Žádné důležité události",
Resume: "Pokračovat", Resume: "Pokračovat",
@ -77,7 +77,7 @@ export default {
"Resend Notification if Down X times consequently": "Znovu zaslat oznámení, pokud je služba nedostupná Xkrát za sebou", "Resend Notification if Down X times consequently": "Znovu zaslat oznámení, pokud je služba nedostupná Xkrát za sebou",
Advanced: "Rozšířené", Advanced: "Rozšířené",
"Upside Down Mode": "Inverzní režim", "Upside Down Mode": "Inverzní režim",
"Max. Redirects": "Max. Přesměrování", "Max. Redirects": "Max. přesměrování",
"Accepted Status Codes": "Akceptované stavové kódy", "Accepted Status Codes": "Akceptované stavové kódy",
"Push URL": "Push URL", "Push URL": "Push URL",
needPushEvery: "Tuto URL adresu byste měli volat každých {0} sekund.", needPushEvery: "Tuto URL adresu byste měli volat každých {0} sekund.",
@ -107,7 +107,7 @@ export default {
"disableauth.message1": "Opravdu chcete <strong>deaktivovat autentifikaci</strong>?", "disableauth.message1": "Opravdu chcete <strong>deaktivovat autentifikaci</strong>?",
"disableauth.message2": "Tato možnost je určena pro případy, kdy <strong>máte autentifikaci zajištěnou třetí stranou</strong> ještě před přístupem do Uptime Kuma, například prostřednictvím Cloudflare Access.", "disableauth.message2": "Tato možnost je určena pro případy, kdy <strong>máte autentifikaci zajištěnou třetí stranou</strong> ještě před přístupem do Uptime Kuma, například prostřednictvím Cloudflare Access.",
"Please use this option carefully!": "Používejte ji prosím s rozmyslem.", "Please use this option carefully!": "Používejte ji prosím s rozmyslem.",
Logout: "Odhlášení", Logout: "Odhlásit",
Leave: "Odejít", Leave: "Odejít",
"I understand, please disable": "Rozumím, chci ji deaktivovat", "I understand, please disable": "Rozumím, chci ji deaktivovat",
Confirm: "Potvrzení", Confirm: "Potvrzení",
@ -132,7 +132,7 @@ export default {
"Export Backup": "Exportovat zálohu", "Export Backup": "Exportovat zálohu",
Export: "Exportovat", Export: "Exportovat",
Import: "Importovat", Import: "Importovat",
respTime: "Odezva Čas (ms)", respTime: "Doba odezvy (ms)",
notAvailableShort: "N/A", notAvailableShort: "N/A",
"Default enabled": "Standardně povoleno", "Default enabled": "Standardně povoleno",
"Apply on all existing monitors": "Použít pro všechny existující dohledy", "Apply on all existing monitors": "Použít pro všechny existující dohledy",
@ -313,7 +313,7 @@ export default {
PasswordsDoNotMatch: "Hesla se neshodují.", PasswordsDoNotMatch: "Hesla se neshodují.",
records: "záznamů", records: "záznamů",
"One record": "Jeden záznam", "One record": "Jeden záznam",
steamApiKeyDescription: "Pro monitorování Steam Game Servere je nutné zadat Steam Web-API klíč. Svůj API klíč získáte na následující stránce: ", steamApiKeyDescription: "Pro monitorování Steam Game Serveru je nutné zadat Steam Web-API klíč. Svůj API klíč získáte na následující stránce: ",
"Current User": "Aktuálně přihlášený uživatel", "Current User": "Aktuálně přihlášený uživatel",
topic: "Topic", topic: "Topic",
topicExplanation: "MQTT topic, který chcete sledovat", topicExplanation: "MQTT topic, který chcete sledovat",
@ -327,7 +327,7 @@ export default {
"Shrink Database": "Zmenšit databázi", "Shrink Database": "Zmenšit databázi",
"Pick a RR-Type...": "Vyberte typ záznamu o prostředku…", "Pick a RR-Type...": "Vyberte typ záznamu o prostředku…",
"Pick Accepted Status Codes...": "Vyberte stavové kódy, které chcete akceptovat…", "Pick Accepted Status Codes...": "Vyberte stavové kódy, které chcete akceptovat…",
Default: "Standardní", Default: "Výchozí",
"HTTP Options": "Možnosti protokolu HTTP", "HTTP Options": "Možnosti protokolu HTTP",
"Create Incident": "Vytvořit incident", "Create Incident": "Vytvořit incident",
Title: "Předmět", Title: "Předmět",
@ -347,7 +347,7 @@ export default {
"Last Updated": "Poslední aktualizace", "Last Updated": "Poslední aktualizace",
Unpin: "Odepnout", Unpin: "Odepnout",
"Switch to Light Theme": "Přepnout na světlý motiv", "Switch to Light Theme": "Přepnout na světlý motiv",
"Switch to Dark Theme": "Přepnutí na tmavý motiv", "Switch to Dark Theme": "Přepnout na tmavý motiv",
"Show Tags": "Zobrazit štítky", "Show Tags": "Zobrazit štítky",
"Hide Tags": "Skrýt štítky", "Hide Tags": "Skrýt štítky",
Description: "Popis", Description: "Popis",
@ -425,8 +425,8 @@ export default {
Retry: "Opakovat", Retry: "Opakovat",
Topic: "Topic", Topic: "Topic",
"WeCom Bot Key": "WeCom Bot Key", "WeCom Bot Key": "WeCom Bot Key",
"Setup Proxy": "Setup Proxy", "Setup Proxy": "Nastavit proxy",
"Proxy Protocol": "Proxy Protocol", "Proxy Protocol": "Protokol proxy",
"Proxy Server": "Proxy Server", "Proxy Server": "Proxy Server",
"Proxy server has authentication": "Proxy server vyžaduje ověření", "Proxy server has authentication": "Proxy server vyžaduje ověření",
User: "Uživatel", User: "Uživatel",
@ -481,7 +481,7 @@ export default {
onebotSafetyTips: "Z důvodu bezpečnosti je nutné zadat přístupový token", onebotSafetyTips: "Z důvodu bezpečnosti je nutné zadat přístupový token",
"PushDeer Key": "PushDeer klíč", "PushDeer Key": "PushDeer klíč",
"Footer Text": "Text v patičce", "Footer Text": "Text v patičce",
"Show Powered By": "Zobrazit \"Zajišťuje\"", "Show Powered By": "Zobrazit \"Poskytuje\"",
"Domain Names": "Názvy domén", "Domain Names": "Názvy domén",
signedInDisp: "Přihlášen jako {0}", signedInDisp: "Přihlášen jako {0}",
signedInDispDisabled: "Ověření je vypnuté.", signedInDispDisabled: "Ověření je vypnuté.",
@ -529,9 +529,9 @@ export default {
"pushoversounds none": "Žádný (ticho)", "pushoversounds none": "Žádný (ticho)",
pushyAPIKey: "Secret API Key", pushyAPIKey: "Secret API Key",
pushyToken: "Token zařízení", pushyToken: "Token zařízení",
"Show update if available": "Zobrazit aktualizace, pokud jsou k dispozici", "Show update if available": "Upozornit na aktualizace, pokud jsou k dispozici",
"Also check beta release": "Kontrolovat také dostupnost beta verzí", "Also check beta release": "Kontrolovat také dostupnost beta verzí",
"Using a Reverse Proxy?": "Používáte reverzní proxy??", "Using a Reverse Proxy?": "Používáte reverzní proxy?",
"Check how to config it for WebSocket": "Zjistěte, jak ji nakonfigurovat pro WebSockety", "Check how to config it for WebSocket": "Zjistěte, jak ji nakonfigurovat pro WebSockety",
"Steam Game Server": "Steam Game Server", "Steam Game Server": "Steam Game Server",
"Most likely causes:": "Nejčastější důvody:", "Most likely causes:": "Nejčastější důvody:",
@ -545,7 +545,7 @@ export default {
"Connection String": "Connection String", "Connection String": "Connection String",
Query: "Dotaz", Query: "Dotaz",
settingsCertificateExpiry: "Platnost TLS certifikátu", settingsCertificateExpiry: "Platnost TLS certifikátu",
certificationExpiryDescription: "Aktivovat oznámení nad HTTPS dohledy, pokud platnost TSL certifikátu vyprší za:", certificationExpiryDescription: "Aktivovat oznámení nad HTTPS dohledy, pokud platnost TLS certifikátu vyprší za:",
"Setup Docker Host": "Nastavit Docker hostitele", "Setup Docker Host": "Nastavit Docker hostitele",
"Connection Type": "Typ připojení", "Connection Type": "Typ připojení",
"Docker Daemon": "Docker Daemon", "Docker Daemon": "Docker Daemon",
@ -576,4 +576,10 @@ export default {
"Then choose an action, for example switch the scene to where an RGB light is red.": "Následně vyberte akci, například přepnutí scény z RGB světla na červenou.", "Then choose an action, for example switch the scene to where an RGB light is red.": "Následně vyberte akci, například přepnutí scény z RGB světla na červenou.",
"Frontend Version": "Verze frontendu", "Frontend Version": "Verze frontendu",
"Frontend Version do not match backend version!": "Verze frontendu neodpovídá verzi backendu!", "Frontend Version do not match backend version!": "Verze frontendu neodpovídá verzi backendu!",
"Base URL": "Primární URL adresa",
goAlertInfo: "GoAlert je aplikace s otevřeným zdrojovým kódem pro plánování hovorů, automatické eskalace a upozornění (jako jsou SMS nebo hlasové hovory). Automaticky zapojte správnou osobu, správným způsobem a ve správný čas! {0}",
goAlertIntegrationKeyInfo: "Obecný API integrační klíč pro danou službu ve formátu \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" se obvykle nachází ve zkopírované URL jako hodnota parametru token.",
goAlert: "GoAlert",
backupOutdatedWarning: "Zastaralé: V poslední době byla funkčnost aplikace značně rozšířena, nicméně součást pro zálohování nepokrývá všechny možnosti. Z tohoto důvodu není možné vygenerovat úplnou zálohu a zajistit obnovení všech dat.",
backupRecommend: "Prosím, zálohujte si ručně celý svazek nebo datovou složku (./data/).",
}; };

@ -458,4 +458,122 @@ export default {
"Domain Names": "Domainnamen", "Domain Names": "Domainnamen",
signedInDisp: "Angemeldet als {0}", signedInDisp: "Angemeldet als {0}",
signedInDispDisabled: "Authentifizierung deaktiviert.", signedInDispDisabled: "Authentifizierung deaktiviert.",
dnsPortDescription: "DNS server port. Standard ist 53. Der Port kann jederzeit geändert werden.",
topic: "Thema",
topicExplanation: "MQTT Thema für den monitor",
successMessage: "Erfolgsnachricht",
successMessageExplanation: "MQTT Nachricht, die als Erfolg angesehen wird",
error: "Fehler",
critical: "kritisch",
wayToGetPagerDutyKey: "Dieser kann unter Service -> Service Directory -> (Select a service) -> Integrations -> Add integration gefunden werden. Hier muss nach \"Events API V2\" gesucht werden. Mehr informationen {0}",
"Integration Key": "Schlüssel der Integration",
"Integration URL": "URL der Integration",
"Auto resolve or acknowledged": "Automatisch lösen oder bestätigen",
"do nothing": "nichts tun",
"auto acknowledged": "automatisch bestätigen",
"auto resolve": "automatisch lösen",
"Bark Group": "Bark Gruppe",
"Bark Sound": "Bark Klang",
"HTTP Headers": "HTTP Kopfzeilen",
"Trust Proxy": "Vertrauenswürdiger Proxy",
Proxy: "Proxy",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP Adresse",
onebotMessageType: "OneBot Nachrichtentyp",
onebotGroupMessage: "Gruppe",
onebotPrivateMessage: "Privat",
onebotUserOrGroupId: "Gruppe/Nutzer ID",
onebotSafetyTips: "Zur Sicherheit ein access token setzen",
"PushDeer Key": "PushDeer Schlüssel",
RadiusSecret: "Radius Geheimnis",
RadiusSecretDescription: "Geteiltes Geheimnis zwischen Client und Server",
RadiusCalledStationId: "ID der angesprochenen Station",
RadiusCalledStationIdDescription: "Identifikation des angesprochenen Geräts",
RadiusCallingStationId: "ID der ansprechenden Station",
RadiusCallingStationIdDescription: "Identifikation des ansprechenden Geräts",
"Certificate Expiry Notification": "Benachrichtigung ablaufendes Zertifikat",
"API Username": "API Nutzername",
"API Key": "API Schlüssel",
"Recipient Number": "Empfängernummer",
"From Name/Number": "Von Name/Nummer",
"Leave blank to use a shared sender number.": "Leer lassen um eine geteilte Sendernummer zu nutzen.",
"Octopush API Version": "Octopush API Version",
"Legacy Octopush-DM": "Legacy Octopush-DM",
endpoint: "Endpunkt",
octopushAPIKey: "\"API Schlüssel\" der HTTP API Zugangsdaten im control panel",
octopushLogin: "\"Login\" der HTTP API Zugangsdaten im control panel",
promosmsLogin: "API Login Name",
promosmsPassword: "API Password",
"pushoversounds pushover": "Pushover (Standard)",
"pushoversounds bike": "Fahrrad",
"pushoversounds bugle": "Signalhorn",
"pushoversounds cashregister": "Kasse",
"pushoversounds classical": "Klassisch",
"pushoversounds cosmic": "Kosmisch",
"pushoversounds falling": "Abfallend",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Eingang",
"pushoversounds intermission": "Pause",
"pushoversounds magic": "Magisch",
"pushoversounds mechanical": "Mechanisch",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Sirene",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Schlepper Horn",
"pushoversounds alien": "Außerirdisch (lang)",
"pushoversounds climb": "Ansteigende (lang)",
"pushoversounds persistent": "Hartnäckig (lang)",
"pushoversounds echo": "Pushover Echo (lang)",
"pushoversounds updown": "Auf und Ab (lang)",
"pushoversounds vibrate": "Nur vibrieren",
"pushoversounds none": "Nichts (Stille)",
pushyAPIKey: "Geheimer API Schlüssel",
pushyToken: "Gerätetoken",
"Show update if available": "Verfügbare Updates anzeigen",
"Also check beta release": "Auch nach beta Versionen schauen",
"Using a Reverse Proxy?": "Wird ein Reverse Proxy genutzt?",
"Check how to config it for WebSocket": "Prüfen, wie er für die Nutzung mit WebSocket konfiguriert wird",
"Steam Game Server": "Steam Game Server",
"Most likely causes:": "Wahrscheinliche Ursachen:",
"The resource is no longer available.": "Die Quelle ist nicht mehr verfügbar.",
"There might be a typing error in the address.": "Es gibt einen Tippfehler in der Adresse.",
"What you can try:": "Was du versuchen kannst:",
"Retype the address.": "Schreibe die Adresse erneut.",
"Go back to the previous page.": "Gehe zur vorigen Seite.",
"Coming Soon": "Kommt bald",
wayToGetClickSendSMSToken: "Du kannst einen API Nutzernamen und Schlüssel unter {0} erhalten.",
"Connection String": "Verbindungstext",
Query: "Abfrage",
settingsCertificateExpiry: "TLS Zertifikatsablauf",
certificationExpiryDescription: "HTTPS Monitore senden eine Benachrichtigung, wenn das Zertifikat abläuft in:",
"Setup Docker Host": "Docker Host einrichten",
"Connection Type": "Verbindungstyp",
"Docker Daemon": "Docker Daemon",
deleteDockerHostMsg: "Bist du sicher diesen docker host für alle Monitore zu löschen?",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker Container",
"Container Name / ID": "Container Name / ID",
"Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Thema",
Domain: "Domain",
Workstation: "Workstation",
disableCloudflaredNoAuthMsg: "Du bist im nicht-authentifizieren modus, ein Passwort wird nicht benötigt.",
trustProxyDescription: "Vertraue 'X-Forwarded-*' headern. Wenn man die richtige client IP haben möchte und Uptime Kuma hinter einem Proxy wie Nginx or Apache läuft, wollte dies aktiviert werden.",
wayToGetLineNotifyToken: "Du kannst hier ein Token erhalten: {0}",
Examples: "Beispiele",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token": "Lange gültiges 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. ": "Lange gültige Access Token können durch klicken auf den Profilnamen (unten links) und dann einen Klick auf Create Token am Ende erstellt werden. ",
"Notification Service": "Benachrichtigungsdienst",
"default: notify all devices": "standard: Alle Geräte benachrichtigen",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Eine Liste der Benachrichtigungsdiesnte kann im Home Assistant unter \"Developer Tools > Services\" gefunden werden, wnen man nach \"notification\" sucht um den Geräte-/Telefonnamen zu finden.",
"Automations can optionally be triggered in Home Assistant:": "Automatisierungen können optional im Home Assistant ausgelöst werden:",
"Trigger type:": "Auslösertyp:",
"Event type:": "Ereignistyp:",
"Event data:": "Ereignis daten:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Dann eine Aktion wählen, zum Beispiel eine Scene wählen in der ein RGB Licht rot ist.",
"Frontend Version": "Frontend Version",
"Frontend Version do not match backend version!": "Die Frontend Version stimmt nicht mit der backend version überein!",
}; };

@ -557,9 +557,9 @@ export default {
"Docker Host": "Docker Host", "Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts", "Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Topic", "ntfy Topic": "ntfy Topic",
"Domain": "Domain", Domain: "Domain",
"Workstation": "Workstation", Workstation: "Workstation",
disableCloudflaredNoAuthMsg: "You are in No Auth mode, password is not require.", disableCloudflaredNoAuthMsg: "You are in No Auth mode, a password is not required.",
trustProxyDescription: "Trust 'X-Forwarded-*' headers. If you want to get the correct client IP and your Uptime Kuma is behind such as Nginx or Apache, you should enable this.", trustProxyDescription: "Trust 'X-Forwarded-*' headers. If you want to get the correct client IP and your Uptime Kuma is behind such as Nginx or Apache, you should enable this.",
wayToGetLineNotifyToken: "You can get an access token from {0}", wayToGetLineNotifyToken: "You can get an access token from {0}",
Examples: "Examples", Examples: "Examples",
@ -576,5 +576,11 @@ export default {
"Then choose an action, for example switch the scene to where an RGB light is red.": "Then choose an action, for example switch the scene to where an RGB light is red.", "Then choose an action, for example switch the scene to where an RGB light is red.": "Then choose an action, for example switch the scene to where an RGB light is red.",
"Frontend Version": "Frontend Version", "Frontend Version": "Frontend Version",
"Frontend Version do not match backend version!": "Frontend Version do not match backend version!", "Frontend Version do not match backend version!": "Frontend Version do not match backend version!",
"Base URL": "Base 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: "Get generic API integration key for the service in this format \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" usually the value of token parameter of copied URL.",
goAlert: "GoAlert",
backupOutdatedWarning: "Deprecated: Since a lot of features added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.",
backupRecommend: "Please backup the volume or the data folder (./data/) directly instead.",
"Body Encoding": "Body Encoding", "Body Encoding": "Body Encoding",
}; };

@ -2,6 +2,8 @@ export default {
languageName: "Bahasa Indonesia (Indonesian)", languageName: "Bahasa Indonesia (Indonesian)",
checkEverySecond: "Cek Setiap {0} detik.", checkEverySecond: "Cek Setiap {0} detik.",
retryCheckEverySecond: "Coba lagi setiap {0} detik.", retryCheckEverySecond: "Coba lagi setiap {0} detik.",
resendEveryXTimes: "Kirim ulang setiap {0} kali",
resendDisabled: "Kirim ulang dinonaktifkan",
retriesDescription: "Percobaan ulang maksimum sebelum layanan dinyatakan tidak aktif dan notifikasi dikirim", retriesDescription: "Percobaan ulang maksimum sebelum layanan dinyatakan tidak aktif dan notifikasi dikirim",
ignoreTLSError: "Abaikan kesalahan TLS/SSL untuk situs web HTTPS", ignoreTLSError: "Abaikan kesalahan TLS/SSL untuk situs web HTTPS",
upsideDownModeDescription: "Balikkan statusnya. Jika layanan dapat dijangkau, TIDAK AKTIF.", upsideDownModeDescription: "Balikkan statusnya. Jika layanan dapat dijangkau, TIDAK AKTIF.",
@ -13,6 +15,7 @@ export default {
pauseDashboardHome: "Jeda", pauseDashboardHome: "Jeda",
deleteMonitorMsg: "Apakah Anda mau menghapus monitor ini?", deleteMonitorMsg: "Apakah Anda mau menghapus monitor ini?",
deleteNotificationMsg: "Apakah Anda mau menghapus notifikasi untuk semua monitor?", deleteNotificationMsg: "Apakah Anda mau menghapus notifikasi untuk semua monitor?",
dnsPortDescription: "Port server DNS. Bawaan menggunakan 53. Anda dapat mengubah port kapan saja.",
resolverserverDescription: "Cloudflare adalah server bawaan, Anda dapat mengubah server resolver kapan saja.", resolverserverDescription: "Cloudflare adalah server bawaan, Anda dapat mengubah server resolver kapan saja.",
rrtypeDescription: "Pilih RR-Type yang mau Anda monitor", rrtypeDescription: "Pilih RR-Type yang mau Anda monitor",
pauseMonitorMsg: "Apakah Anda yakin mau menjeda?", pauseMonitorMsg: "Apakah Anda yakin mau menjeda?",
@ -33,6 +36,7 @@ export default {
Appearance: "Tampilan", Appearance: "Tampilan",
Theme: "Tema", Theme: "Tema",
General: "Umum", General: "Umum",
"Primary Base URL": "URL Dasar Utama",
Version: "Versi", Version: "Versi",
"Check Update On GitHub": "Cek Pembaruan di GitHub", "Check Update On GitHub": "Cek Pembaruan di GitHub",
List: "Daftar", List: "Daftar",
@ -54,7 +58,7 @@ export default {
Delete: "Hapus", Delete: "Hapus",
Current: "Saat ini", Current: "Saat ini",
Uptime: "Waktu aktif", Uptime: "Waktu aktif",
"Cert Exp.": "Cert Exp.", "Cert Exp.": "Batas kedaluwarsa SSL",
day: "hari | hari-hari", day: "hari | hari-hari",
"-day": "-hari", "-day": "-hari",
hour: "Jam", hour: "Jam",
@ -62,7 +66,7 @@ export default {
Response: "Tanggapan", Response: "Tanggapan",
Ping: "Ping", Ping: "Ping",
"Monitor Type": "Tipe Monitor", "Monitor Type": "Tipe Monitor",
Keyword: "Keyword", Keyword: "Kata Kunci",
"Friendly Name": "Nama yang Ramah", "Friendly Name": "Nama yang Ramah",
URL: "URL", URL: "URL",
Hostname: "Hostname", Hostname: "Hostname",
@ -70,10 +74,14 @@ export default {
"Heartbeat Interval": "Jarak Waktu Heartbeat ", "Heartbeat Interval": "Jarak Waktu Heartbeat ",
Retries: "Coba lagi", Retries: "Coba lagi",
"Heartbeat Retry Interval": "Jarak Waktu Heartbeat Mencoba kembali ", "Heartbeat Retry Interval": "Jarak Waktu Heartbeat Mencoba kembali ",
"Resend Notification if Down X times consequently": "Kirim Ulang Notifikasi jika Tidak Aktif X kali",
Advanced: "Tingkat Lanjut", Advanced: "Tingkat Lanjut",
"Upside Down Mode": "Mode Terbalik", "Upside Down Mode": "Mode Terbalik",
"Max. Redirects": "Maksimal Pengalihan", "Max. Redirects": "Maksimal Pengalihan",
"Accepted Status Codes": "Kode Status yang Diterima", "Accepted Status Codes": "Kode Status yang Diterima",
"Push URL": "Push URL",
needPushEvery: "Anda harus memanggil URL berikut setiap {0} detik..",
pushOptionalParams: "Parameter tambahan: {0}",
Save: "Simpan", Save: "Simpan",
Notifications: "Notifikasi", Notifications: "Notifikasi",
"Not available, please setup.": "Tidak tersedia, silakan atur.", "Not available, please setup.": "Tidak tersedia, silakan atur.",
@ -187,7 +195,7 @@ export default {
Required: "Dibutuhkan", Required: "Dibutuhkan",
telegram: "Telegram", telegram: "Telegram",
"Bot Token": "Bot Token", "Bot Token": "Bot Token",
"You can get a token from": "Anda bisa mendapatkan token dari", wayToGetTelegramToken: "Anda dapat mendapatkan token dari {0}.",
"Chat ID": "Chat ID", "Chat ID": "Chat ID",
supportTelegramChatID: "Mendukung Obrolan Langsung / Grup / Channel Chat ID", supportTelegramChatID: "Mendukung Obrolan Langsung / Grup / Channel Chat ID",
wayToGetTelegramChatID: "Anda bisa mendapatkan chat id Anda dengan mengirim pesan ke bot dan pergi ke url ini untuk melihat chat_id:", wayToGetTelegramChatID: "Anda bisa mendapatkan chat id Anda dengan mengirim pesan ke bot dan pergi ke url ini untuk melihat chat_id:",
@ -203,6 +211,7 @@ export default {
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Abaikan Kesalahan TLS", "Ignore TLS Error": "Abaikan Kesalahan TLS",
"From Email": "Dari Surel", "From Email": "Dari Surel",
emailCustomSubject: "Subjek",
"To Email": "Ke Surel", "To Email": "Ke Surel",
smtpCC: "CC", smtpCC: "CC",
smtpBCC: "BCC", smtpBCC: "BCC",
@ -236,10 +245,13 @@ export default {
"rocket.chat": "Rocket.chat", "rocket.chat": "Rocket.chat",
pushover: "Pushover", pushover: "Pushover",
pushy: "Pushy", pushy: "Pushy",
PushByTechulus: "Push by Techulus",
octopush: "Octopush", octopush: "Octopush",
promosms: "PromoSMS", promosms: "PromoSMS",
clicksendsms: "ClickSend SMS",
lunasea: "LunaSea", lunasea: "LunaSea",
apprise: "Apprise (Mendukung 50+ layanan notifikasi)", apprise: "Apprise (Mendukung 50+ layanan notifikasi)",
GoogleChat: "Google Chat (hanya Google Workspace)",
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
@ -253,6 +265,9 @@ export default {
"SMS Type": "Tipe SMS", "SMS Type": "Tipe SMS",
octopushTypePremium: "Premium (Cepat - direkomendasikan untuk mengingatkan)", octopushTypePremium: "Premium (Cepat - direkomendasikan untuk mengingatkan)",
octopushTypeLowCost: "Low Cost (Lambat, terkadang diblokir oleh operator)", octopushTypeLowCost: "Low Cost (Lambat, terkadang diblokir oleh operator)",
checkPrice: "Check {0} prices:",
apiCredentials: "Kredensial API",
octopushLegacyHint: "Apakah Anda menggunakan Octopush versi lama (2011-2020) atau versi baru?",
"Check octopush prices": "Cek harga octopush {0}.", "Check octopush prices": "Cek harga octopush {0}.",
octopushPhoneNumber: "Nomer Telpon/HP (format internasional, contoh : +33612345678) ", octopushPhoneNumber: "Nomer Telpon/HP (format internasional, contoh : +33612345678) ",
octopushSMSSender: "Nama Pengirim SMS : 3-11 karakter alfanumerik dan spasi (a-zA-Z0-9)", octopushSMSSender: "Nama Pengirim SMS : 3-11 karakter alfanumerik dan spasi (a-zA-Z0-9)",
@ -278,9 +293,293 @@ export default {
matrix: "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - murah tapi lambat dan sering kelebihan beban. Terbatas hanya untuk penerima Polandia.", promosmsTypeEco: "SMS ECO - murah tapi lambat dan sering kelebihan beban. Terbatas hanya untuk penerima Polandia.",
promosmsTypeFlash: "SMS FLASH - Pesan akan otomatis muncul di perangkat penerima. Terbatas hanya untuk penerima Polandia.", promosmsTypeFlash: "SMS FLASH - Pesan akan otomatis muncul di perangkat penerima. Terbatas hanya untuk penerima Polandia.",
promosmsTypeFull: "SMS FULL - SMS tingkat premium, Anda dapat menggunakan Nama Pengirim Anda (Anda harus mendaftarkan nama terlebih dahulu). Dapat diAndalkan untuk peringatan.", promosmsTypeFull: "SMS FULL - SMS tingkat premium, Anda dapat menggunakan Nama Pengirim Anda (Anda harus mendaftarkan nama terlebih dahulu). Dapat diandalkan untuk peringatan.",
promosmsTypeSpeed: "SMS SPEED - Prioritas tertinggi dalam sistem. Sangat cepat dan dapat diandalkan tetapi mahal (sekitar dua kali lipat dari harga SMS FULL).", promosmsTypeSpeed: "SMS SPEED - Prioritas tertinggi dalam sistem. Sangat cepat dan dapat diandalkan tetapi mahal (sekitar dua kali lipat dari harga SMS FULL).",
promosmsPhoneNumber: "Nomor telepon (untuk penerima Polandia Anda dapat melewati kode area)", promosmsPhoneNumber: "Nomor telepon (untuk penerima Polandia Anda dapat melewati kode area)",
promosmsSMSSender: "Nama Pengirim SMS : Nama pra-registrasi atau salah satu bawaan: InfoSMS, Info SMS, MaxSMS, INFO, SMS", promosmsSMSSender: "Nama Pengirim SMS : Nama pra-registrasi atau salah satu bawaan: InfoSMS, Info SMS, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "Feishu WebHookUrl", "Feishu WebHookUrl": "Feishu WebHookUrl",
matrixHomeserverURL: "Homeserver URL (dengan http(s):// dan port tambahan)",
"Internal Room Id": "Internal Room ID",
matrixDesc1: "Kamu dapat menemukan Internal Room ID dengan melihat di bagian konfigurasi ruang di Matrix. Seharusnya berbentuk seperti !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "Sangat direkomendasikan kepada Anda untuk membuat akun baru dan jangan menggunakan token atas akun terkini yang memiliki token akses secara penuh terhadap akun dan seluruh ruang yang terdaftar. Alih - alih, buat akun baru dan undang akun tsb ke ruang tempat anda ingin menerima notifikasi. Untuk mendapatkan token akses anda dapat menjalankan {0}",
Method: "Method",
Body: "Body",
Headers: "Headers",
PushUrl: "Push URL",
HeadersInvalidFormat: "Request Headers memiliki format JSON yang tidak sesuai: ",
BodyInvalidFormat: "Request Body memiliki format JSON yang tidak sesuai: ",
"Monitor History": "Riyawat Monitor",
clearDataOlderThan: "Simpan data riwayat monitoring selama {0} hari.",
PasswordsDoNotMatch: "Passwords tidak sama.",
records: "catatan",
"One record": "Satu catatan",
steamApiKeyDescription: "Untuk monitoring Steam Game Server Anda membutuhkan kunci Steam Web-API. Anda dapat mendaftarkan Kunci API Anda melalui: ",
"Current User": "Pengguna Saat Ini",
topic: "Topic",
topicExplanation: "MQTT topic untuk dimonitor",
successMessage: "Pesan Berhasil",
successMessageExplanation: "Pesan MQTT yang akan dianggap berhasil",
recent: "Baru saja",
Done: "Selesai",
Info: "Info",
Security: "Keamaan",
"Steam API Key": "Steam API Key",
"Shrink Database": "Shrink Database",
"Pick a RR-Type...": "Pilih RR-Type...",
"Pick Accepted Status Codes...": "Pilih Kode Status yang Diterima...",
Default: "Default",
"HTTP Options": "HTTP Options",
"Create Incident": "Buat Incident",
Title: "Judul",
Content: "Konten",
Style: "Gaya",
info: "info",
warning: "peringatan",
danger: "bahaya",
error: "kesalahan",
critical: "kritis",
primary: "utama",
light: "terang",
dark: "gelap",
Post: "Post",
"Please input title and content": "Masukkan judul dan konten",
Created: "Dibuat",
"Last Updated": "Terakhir Diperbarui",
Unpin: "Lepaskan Semat",
"Switch to Light Theme": "Ubah ke Tema Terang",
"Switch to Dark Theme": "Ubah ke Tema Gelap",
"Show Tags": "Tampilkan Tags",
"Hide Tags": "Sembunyikan Tags",
Description: "Deskripsi",
"No monitors available.": "Tidak ada monitor yang tersedia.",
"Add one": "Tambahkan",
"No Monitors": "Tidak ada monitor",
"Untitled Group": "Group Tanpa Judul",
Services: "Layanan",
Discard: "Buang",
Cancel: "Batal",
"Powered by": "Dipersembahkan oleh",
shrinkDatabaseDescription: "Trigger database VACUUM untuk SQLite. Jika database Anda dibuat setelah 1.10.0, AUTO_VACUUM sudah otomatis diaktifkan dan aksi berikut tidak dibutuhkan.",
serwersms: "SerwerSMS.pl",
serwersmsAPIUser: "Nama Pengguna API ( termamsuk awalan webapi_ )",
serwersmsAPIPassword: "Kata Sandi API",
serwersmsPhoneNumber: "Nomor Telepon",
serwersmsSenderName: "Nama Pengirim SMS (didaftarkan melalui portal pelanggan)",
stackfield: "Stackfield",
Customize: "Kustomisasi",
"Custom Footer": "Tambahan Footer",
"Custom CSS": "Tambahan CSS",
smtpDkimSettings: "Pengaturan DKIM",
smtpDkimDesc: "Silakan merujuk ke Nodemailer DKIM {0} untuk penggunaan.",
documentation: "dokumentasi",
smtpDkimDomain: "Nama Domain",
smtpDkimKeySelector: "Key Selector",
smtpDkimPrivateKey: "Private Key",
smtpDkimHashAlgo: "Algoritma Hash (Opsional)",
smtpDkimheaderFieldNames: "Header Keys untuk ditambahkan (Optional)",
smtpDkimskipFields: "Header Keys not untuk ditambahkan (Optional)",
wayToGetPagerDutyKey: "Anda dapat menambahkan melalui Service -> Service Directory -> (Select a service) -> Integrations -> Add integration. Lalu Anda dapat menjadi dengan kata kunci \"Events API V2\". Informasi tambahan {0}",
"Integration Key": "Integration Key",
"Integration URL": "Integration URL",
"Auto resolve or acknowledged": "Penyelesaian otomatis atau diakui",
"do nothing": "tidak melakukan apapun",
"auto acknowledged": "otomatis diakui",
"auto resolve": "otomatis terselesaikan",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "API Endpoint",
alertaEnvironment: "Lingkungan",
alertaApiKey: "Kunci API",
alertaAlertState: "Status Siaga",
alertaRecoverState: "Status Pemulihan",
deleteStatusPageMsg: "Apakah Anda yakin untuk menghapus halaman status berikut?",
Proxies: "Proxies",
default: "Bawaan",
enabled: "Diaktifkan",
setAsDefault: "Tetapkan sebagai bawaan",
deleteProxyMsg: "Apakah Anda yakin ingin menghapus proxy berikut untuk seluruh monitor?",
proxyDescription: "Proxy harus ditambahkan ke monitor agar berfungsi.",
enableProxyDescription: "Proxy berikut tidak akan berdampak ke monitor hingga diaktifkan. Anda dapat mengontrol menonaktifkan sementara proxy dari semua monitor dengan status aktivasi.",
setAsDefaultProxyDescription: "Proxy berikut akan diaktifkan sebagai bawaan untuk monitor baru. Anda masih dapat menonaktifkan proxy secara terpisah untuk setiap monitor.",
"Certificate Chain": "Certificate Chain",
Valid: "Sahih",
Invalid: "Tidak Sahih",
AccessKeyId: "AccessKey ID",
SecretAccessKey: "AccessKey Secret",
PhoneNumbers: "Nomor Telepon",
TemplateCode: "Kode Template",
SignName: "Nama Tanda",
"Sms template must contain parameters: ": "Template SMS harus memuat parameter: ",
"Bark Endpoint": "Bark Endpoint",
"Bark Group": "Bark Group",
"Bark Sound": "Bark Sound",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "Untuk keamaan Anda harus menggunakan kunci rahasia",
"Device Token": "Token Perangkat",
Platform: "Platform",
iOS: "iOS",
Android: "Android",
Huawei: "Huawei",
High: "Tinggi",
Retry: "Ulang",
Topic: "Topik",
"WeCom Bot Key": "Kunci WeCom Bot",
"Setup Proxy": "Siapkan Proxy",
"Proxy Protocol": "Protokol Proxy",
"Proxy Server": "Server Proxy",
"Proxy server has authentication": "Server Proxy memiliki autentikasi",
User: "Pengguna",
Installed: "Terpasang",
"Not installed": "Tidak terpasang",
Running: "Berlari",
"Not running": "Tidak berlari",
"Remove Token": "Hapus Token",
Start: "Mulai",
Stop: "Berhenti",
"Uptime Kuma": "Uptime Kuma",
"Add New Status Page": "Tambahkan Halaman Status Baru",
Slug: "Slug",
"Accept characters:": "Terima karakter:",
startOrEndWithOnly: "Mulai atau akhiri hanya dengan {0}",
"No consecutive dashes": "Tanda hubung tidak berurutan",
Next: "Selanjutnya",
"The slug is already taken. Please choose another slug.": "Slug is telah digunakan. Silakan pilih slug lain.",
"No Proxy": "TIdak ada Proxy",
Authentication: "Autentikasi",
"HTTP Basic Auth": "HTTP Basic Auth",
"New Status Page": "Halaman Status Baru",
"Page Not Found": "Halaman Tidak Ditemukan",
"Reverse Proxy": "Proxy Terbalik",
Backup: "Cadangan",
About: "Tentang",
wayToGetCloudflaredURL: "(Unduh cloudflared dari {0})",
cloudflareWebsite: "Situs Cloudflare",
"Message:": "Pesan:",
"Don't know how to get the token? Please read the guide:": "Tidak tahu cara mendapatkan token? Silakan baca panduannya:",
"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.": "Koneksi saat ini mungkin hilang jika Anda saat ini terhubung melalui CloudflareTunnel. Apakah Anda yakin ingin menghentikannya? Ketik kata sandi Anda saat ini untuk mengonfirmasinya.",
"HTTP Headers": "HTTP Headers",
"Trust Proxy": "Proxy Terpercaya",
"Other Software": "Perangkat Lunak lainnya",
"For example: nginx, Apache and Traefik.": "Sebagai contoh: nginx, Apache and Traefik.",
"Please read": "Harap dibaca",
"Subject:": "Subjek:",
"Valid To:": "Berlaku Untuk:",
"Days Remaining:": "Hari Tersisa:",
"Issuer:": "Penerbit:",
"Fingerprint:": "Sidik jari:",
"No status pages": "Tidak ada halaman status",
"Domain Name Expiry Notification": "Pemberitahuan Kedaluwarsa Nama Domain",
Proxy: "Proxy",
"Date Created": "Tanggal Dibuat",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "Alamat HTTP OneBot",
onebotMessageType: "Jenis Pesan OneBot",
onebotGroupMessage: "Grup",
onebotPrivateMessage: "Pribadi",
onebotUserOrGroupId: "Grup/Pengguna ID",
onebotSafetyTips: "Untuk keamanan, harus mengatur token akses",
"PushDeer Key": "Kunci PushDeer",
"Footer Text": "Tulisan Footer",
"Show Powered By": "Tampilkan Dipersembahkan oleh",
"Domain Names": "Nama Domain",
signedInDisp: "Masuk sebagai {0}",
signedInDispDisabled: "Autentikasi dinonaktifkan.",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "Shared Secret antara klien dan server",
RadiusCalledStationId: "Called Station Id",
RadiusCalledStationIdDescription: "Pengenal perangkat yang dipanggil",
RadiusCallingStationId: "Calling Station Id",
RadiusCallingStationIdDescription: "Pengenal perangkat panggilan",
"Certificate Expiry Notification": "Pemberitahuan Kedaluwarsa Sertifikat",
"API Username": "Nama Pengguna API",
"API Key": "Kunci API",
"Recipient Number": "Nomor Penerima Recipient Number",
"From Name/Number": "Dari Nama/Nomor",
"Leave blank to use a shared sender number.": "Biarkan kosong untuk menggunakan nomor pengirim bersama.",
"Octopush API Version": "Versi API Octopush",
"Legacy Octopush-DM": "Legacy Octopush-DM",
endpoint: "endpoint",
octopushAPIKey: "\"API key\" dari kredensial HTTP API di panel kontrol",
octopushLogin: "\"Login\" dari kredensial HTTP API di panel kontrol",
promosmsLogin: "Nama Masuk API",
promosmsPassword: "Kata Sandi 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: "Device token",
"Show update if available": "Tampilkan pembaruan jika tersedia",
"Also check beta release": "Periksa juga rilis beta",
"Using a Reverse Proxy?": "Menggunakan Proxy Terbalik?",
"Check how to config it for WebSocket": "Periksa cara mengonfigurasinya untuk A WebSocket",
"Steam Game Server": "Steam Game Server",
"Most likely causes:": "Kemungkinan besar penyebabnya:",
"The resource is no longer available.": "Sumber daya tidak lagi tersedia.",
"There might be a typing error in the address.": "Mungkin ada kesalahan pengetikan di alamat.",
"What you can try:": "Apa yang dapat kamu coba:",
"Retype the address.": "Ketik ulang alamat.",
"Go back to the previous page.": "Kembali ke halaman sebelumnya.",
"Coming Soon": "Segera",
wayToGetClickSendSMSToken: "Anda bisa mendapatkan Nama Pengguna API dan Kunci API dari {0} .",
"Connection String": "Connection String",
Query: "Query",
settingsCertificateExpiry: "Kedaluwarsa Sertifikat TLS",
certificationExpiryDescription: "Monitor HTTPS memicu pemberitahuan saat sertifikat TLS kedaluwarsa dalam:",
"Setup Docker Host": "Siapkan Host Docker",
"Connection Type": "Jenis Koneksi",
"Docker Daemon": "Docker Daemon",
deleteDockerHostMsg: "Apakah Anda yakin ingin menghapus host docker berikut untuk semua monitor?",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker Container",
"Container Name / ID": "Container Name / ID",
"Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Topic",
Domain: "Domain",
Workstation: "Workstation",
disableCloudflaredNoAuthMsg: "Anda berada dalam mode Tanpa Otentikasi, kata sandi tidak diperlukan.",
trustProxyDescription: "Trust 'X-Forwarded-*' headers. Jika Anda ingin mendapatkan IP klien yang benar dan Uptime Kuma Anda dibalik layanan seperti Nginxor Apache, Anda harus mengaktifkan ini.",
wayToGetLineNotifyToken: "Anda bisa mendapatkan token akses dari {0}",
Examples: "Contoh",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token": "Token Akses Berumur Panjang",
"Long-Lived Access Token canbe created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Token Akses Berumur Panjang dapat dibuat dengan mengklik nama profil Anda (kiri bawah) dan menggulir ke bawah lalu klik Buat Token. ",
"Notification Service": "Layanan Pemberitahuan",
"default: notify all devices": "bawaan: notifikasi seluruh perangkat",
"A listof Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Daftar Layanan Pemberitahuan dapat ditemukan di Home Assistant pada \"Developer Tools > Services\" cari \"notification\" lalu cari nama perangkat Anda.",
"Automations can optionally be triggered in Home Assistant:": "Otomatisasi dapat dipicu secara opsional di Home Assistant:",
"Trigger type:": "Trigger type:",
"Event type:": "Event type:",
"Event data:": "Event data:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Kemudian pilih tindakan, misalnya alihkan ke tempat dimana lampu RGB berwarna merah.",
"Frontend Version": "Versi Frontend",
"Frontend Version do not match backend version!": "Versi Frontend tidak sama dengan versi backend!",
"Base URL": "URL Dasar",
goAlertInfo: "GoAlert adalah aplikasi open source untuk penjadwalan panggilan, eskalasi otomatis dan pemberitahuan (seperti SMS atau panggilan suara). Secara otomatis melibatkan orang yang tepat, dengan cara yang benar, dan pada waktu yang tepat! {0}",
goAlertIntegrationKeyInfo: "Dapatkan kunci integrasi API generik untuk layanan dalam format ini \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" biasanya nilai parameter token dari URL yang disalin.",
goAlert: "GoAlert",
backupOutdatedWarning: "Usang: Karena banyak fitur ditambahkan dan fitur cadangan ini agak tidak terawat, itu tidak dapat menghasilkan atau memulihkan cadangan lengkap.",
backupRecommend: "Harap cadangkan volume atau folder data (./data/) secara langsung.",
}; };

@ -69,7 +69,7 @@ export default {
Port: "포트", Port: "포트",
"Heartbeat Interval": "하트비트 주기", "Heartbeat Interval": "하트비트 주기",
Retries: "재시도", Retries: "재시도",
"Heartbeat Retry Interval": "하트비 재시도 주기", "Heartbeat Retry Interval": "하트비 재시도 주기",
Advanced: "고급", Advanced: "고급",
"Upside Down Mode": "상태 반전 모드", "Upside Down Mode": "상태 반전 모드",
"Max. Redirects": "최대 리다이렉트", "Max. Redirects": "최대 리다이렉트",
@ -110,7 +110,7 @@ export default {
"Remember me": "비밀번호 기억하기", "Remember me": "비밀번호 기억하기",
Login: "로그인", Login: "로그인",
"No Monitors, please": "모니터링이 현재 없어요,", "No Monitors, please": "모니터링이 현재 없어요,",
"add one": "한번 추가해보실요?", "add one": "한번 추가해보실요?",
"Notification Type": "알림 종류", "Notification Type": "알림 종류",
Email: "이메일", Email: "이메일",
Test: "테스트", Test: "테스트",

@ -2,6 +2,8 @@ export default {
languageName: "Türkçe", languageName: "Türkçe",
checkEverySecond: "{0} Saniyede bir kontrol et.", checkEverySecond: "{0} Saniyede bir kontrol et.",
retryCheckEverySecond: "{0} Saniyede bir dene.", retryCheckEverySecond: "{0} Saniyede bir dene.",
resendEveryXTimes: "Her {0} bir yeniden gönder",
resendDisabled: "Yeniden gönderme devre dışı",
retriesDescription: "Servisin kapalı olarak işaretlenmeden ve bir bildirim gönderilmeden önce maksimum yeniden deneme sayısı", retriesDescription: "Servisin kapalı olarak işaretlenmeden ve bir bildirim gönderilmeden önce maksimum yeniden deneme sayısı",
ignoreTLSError: "HTTPS web siteleri için TLS/SSL hatasını yoksay", ignoreTLSError: "HTTPS web siteleri için TLS/SSL hatasını yoksay",
upsideDownModeDescription: "Servisin durumunu tersine çevirir. Servis çalışıyorsa kapalı olarak işaretler.", upsideDownModeDescription: "Servisin durumunu tersine çevirir. Servis çalışıyorsa kapalı olarak işaretler.",
@ -72,6 +74,7 @@ export default {
"Heartbeat Interval": "Servis Test Aralığı", "Heartbeat Interval": "Servis Test Aralığı",
Retries: "Yeniden deneme", Retries: "Yeniden deneme",
"Heartbeat Retry Interval": "Sağlık Durumları Tekrar Deneme Sıklığı", "Heartbeat Retry Interval": "Sağlık Durumları Tekrar Deneme Sıklığı",
"Resend Notification if Down X times consequently": "Sonuç olarak X kez düşerse bildirimi yeniden gönder",
Advanced: "Gelişmiş", Advanced: "Gelişmiş",
"Upside Down Mode": "Ters/Düz Modu", "Upside Down Mode": "Ters/Düz Modu",
"Max. Redirects": "Maksimum Yönlendirme", "Max. Redirects": "Maksimum Yönlendirme",
@ -333,6 +336,8 @@ export default {
info: "info", info: "info",
warning: "warning", warning: "warning",
danger: "danger", danger: "danger",
error: "hata",
critical: "kritik",
primary: "primary", primary: "primary",
light: "light", light: "light",
dark: "dark", dark: "dark",
@ -373,6 +378,13 @@ export default {
smtpDkimHashAlgo: "Hash Algoritması (Opsiyonel)", smtpDkimHashAlgo: "Hash Algoritması (Opsiyonel)",
smtpDkimheaderFieldNames: "İmzalanacak Başlık Anahtarları (Opsiyonel)", smtpDkimheaderFieldNames: "İmzalanacak Başlık Anahtarları (Opsiyonel)",
smtpDkimskipFields: "İmzalamayacak Başlık Anahtarları (Opsiyonel)", smtpDkimskipFields: "İmzalamayacak Başlık Anahtarları (Opsiyonel)",
wayToGetPagerDutyKey: "Bunu Hizmet -> Hizmet Dizini -> (Bir hizmet seçin) -> Entegrasyonlar -> Entegrasyon ekle'ye giderek alabilirsiniz. Burada \"Events API V2\" için arama yapabilirsiniz. Daha fazla bilgi {0}",
"Integration Key": "Entegrasyon Anahtarı",
"Integration URL": "Entegrasyon URL'si",
"Auto resolve or acknowledged": "Otomatik çözümleme veya onaylandı",
"do nothing": "hiçbir şey yapma",
"auto acknowledged": "otomatik onaylandı",
"auto resolve": "otomatik çözümleme",
gorush: "Gorush", gorush: "Gorush",
alerta: "Alerta", alerta: "Alerta",
alertaApiEndpoint: "API Endpoint", alertaApiEndpoint: "API Endpoint",
@ -399,6 +411,8 @@ export default {
SignName: "SignName", SignName: "SignName",
"Sms template must contain parameters: ": "Sms şablonu parametreleri içermelidir:", "Sms template must contain parameters: ": "Sms şablonu parametreleri içermelidir:",
"Bark Endpoint": "Bark Endpoint", "Bark Endpoint": "Bark Endpoint",
"Bark Group": "Bark Group",
"Bark Sound": "Bark Sound",
WebHookUrl: "WebHookUrl", WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey", SecretKey: "SecretKey",
"For safety, must use secret key": "Güvenlik için gizli anahtar kullanılmalıdır", "For safety, must use secret key": "Güvenlik için gizli anahtar kullanılmalıdır",
@ -432,6 +446,7 @@ export default {
Next: "Sonraki", Next: "Sonraki",
"The slug is already taken. Please choose another slug.": "Slug zaten alındı. Lütfen başka bir slug seçin.", "The slug is already taken. Please choose another slug.": "Slug zaten alındı. Lütfen başka bir slug seçin.",
"No Proxy": "Proxy Yok", "No Proxy": "Proxy Yok",
Authentication: "Kimlik doğrulama",
"HTTP Basic Auth": "HTTP Temel Yetkilendirme", "HTTP Basic Auth": "HTTP Temel Yetkilendirme",
"New Status Page": "Yeni Durum Sayfası", "New Status Page": "Yeni Durum Sayfası",
"Page Not Found": "Sayfa bulunamadı", "Page Not Found": "Sayfa bulunamadı",
@ -443,6 +458,8 @@ export default {
"Message:": "Mesaj:", "Message:": "Mesaj:",
"Don't know how to get the token? Please read the guide:": "Tokeni nasıl alacağınızı bilmiyor musunuz? Lütfen kılavuzu okuyun:", "Don't know how to get the token? Please read the guide:": "Tokeni nasıl alacağınızı bilmiyor musunuz? Lütfen kılavuzu okuyun:",
"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.": "Halihazırda Cloudflare Tüneli üzerinden bağlanıyorsanız mevcut bağlantı kesilebilir. Durdurmak istediğinden emin misin? Onaylamak için mevcut şifrenizi yazın.", "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.": "Halihazırda Cloudflare Tüneli üzerinden bağlanıyorsanız mevcut bağlantı kesilebilir. Durdurmak istediğinden emin misin? Onaylamak için mevcut şifrenizi yazın.",
"HTTP Headers": "HTTP Headers",
"Trust Proxy": "Trust Proxy",
"Other Software": "Diğer Yazılımlar", "Other Software": "Diğer Yazılımlar",
"For example: nginx, Apache and Traefik.": "Örneğin: nginx, Apache ve Traefik.", "For example: nginx, Apache and Traefik.": "Örneğin: nginx, Apache ve Traefik.",
"Please read": "Lütfen oku", "Please read": "Lütfen oku",
@ -455,6 +472,7 @@ export default {
"Domain Name Expiry Notification": "Alan Adı Sona Erme Bildirimi", "Domain Name Expiry Notification": "Alan Adı Sona Erme Bildirimi",
Proxy: "Proxy", Proxy: "Proxy",
"Date Created": "Tarih Oluşturuldu", "Date Created": "Tarih Oluşturuldu",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP Adresi", onebotHttpAddress: "OneBot HTTP Adresi",
onebotMessageType: "OneBot Mesaj Türü", onebotMessageType: "OneBot Mesaj Türü",
onebotGroupMessage: "Grup", onebotGroupMessage: "Grup",
@ -467,6 +485,12 @@ export default {
"Domain Names": "Alan isimleri", "Domain Names": "Alan isimleri",
signedInDisp: "{0} olarak oturum açıldı", signedInDisp: "{0} olarak oturum açıldı",
signedInDispDisabled: "Yetkilendirme Devre Dışı.", signedInDispDisabled: "Yetkilendirme Devre Dışı.",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "İstemci ve sunucu arasında paylaşılan gizli anahtar",
RadiusCalledStationId: "Aranan İstasyon Kimliği",
RadiusCalledStationIdDescription: "Aranan cihazın tanımlayıcısı",
RadiusCallingStationId: "Arayan İstasyon Kimliği",
RadiusCallingStationIdDescription: "Arayan cihazın tanımlayıcısı",
"Certificate Expiry Notification": "Sertifika Sona Erme Bildirimi", "Certificate Expiry Notification": "Sertifika Sona Erme Bildirimi",
"API Username": "API Kullanıc Adı", "API Username": "API Kullanıc Adı",
"API Key": "API Anahtarı", "API Key": "API Anahtarı",
@ -475,7 +499,7 @@ export default {
"Leave blank to use a shared sender number.": "Paylaşılan bir gönderen numarası kullanmak için boş bırakın.", "Leave blank to use a shared sender number.": "Paylaşılan bir gönderen numarası kullanmak için boş bırakın.",
"Octopush API Version": "Octopush API Sürümü", "Octopush API Version": "Octopush API Sürümü",
"Legacy Octopush-DM": "Eski Octopush-DM", "Legacy Octopush-DM": "Eski Octopush-DM",
"endpoint": "endpoint", endpoint: "uç nokta",
octopushAPIKey: "Kontrol panelindeki HTTP API kimlik bilgilerinden \"API Key\"", octopushAPIKey: "Kontrol panelindeki HTTP API kimlik bilgilerinden \"API Key\"",
octopushLogin: "Kontrol panelindeki HTTP API kimlik bilgilerinden \"Login\"", octopushLogin: "Kontrol panelindeki HTTP API kimlik bilgilerinden \"Login\"",
promosmsLogin: "API Oturum Açma Adı", promosmsLogin: "API Oturum Açma Adı",
@ -518,13 +542,44 @@ export default {
"Go back to the previous page.": "Bir önceki sayfaya geri git.", "Go back to the previous page.": "Bir önceki sayfaya geri git.",
"Coming Soon": "Yakında gelecek", "Coming Soon": "Yakında gelecek",
wayToGetClickSendSMSToken: "API Kullanıcı Adı ve API Anahtarını {0} adresinden alabilirsiniz.", wayToGetClickSendSMSToken: "API Kullanıcı Adı ve API Anahtarını {0} adresinden alabilirsiniz.",
error: "hata", "Connection String": "Bağlantı dizisi",
critical: "kritik", Query: "Sorgu",
wayToGetPagerDutyKey: "Bunu şuraya giderek alabilirsiniz: Servis -> Servis Dizini -> (Bir servis seçin) -> Entegrasyonlar -> Entegrasyon ekle. Burada \"Events API V2\" için arama yapabilirsiniz. Daha fazla bilgi {0}", settingsCertificateExpiry: "TLS Sertifikasının Geçerlilik Süresi",
"Integration Key": "Entegrasyon Anahtarı", certificationExpiryDescription: "HTTPS Monitörleri, TLS sertifikasının süresi dolduğunda bildirimi tetikler:",
"Integration URL": "Entegrasyon URL", "Setup Docker Host": "Docker Ana Bilgisayarını Kur",
"Auto resolve or acknowledged": "Otomatik çözümleme veya onaylama", "Connection Type": "Bağlantı türü",
"do nothing": "hiçbir şey yapma", "Docker Daemon": "Docker Daemon",
"auto acknowledged": "otomatik onaylama", deleteDockerHostMsg: "Bu docker ana bilgisayarını tüm monitörler için silmek istediğinizden emin misiniz?",
"auto resolve": "otomatik çözümleme", socket: "Soket",
tcp: "TCP / HTTP",
"Docker Container": "Docker Konteyneri",
"Container Name / ID": "Konteyner Adı / Kimliği",
"Docker Host": "Docker Ana Bilgisayarı",
"Docker Hosts": "Docker Ana Bilgisayarları",
"ntfy Topic": "ntfy Konu",
Domain: "Domain",
Workstation: "İş İstasyonu",
disableCloudflaredNoAuthMsg: "Yetki Yok modundasınız, şifre gerekli değil.",
trustProxyDescription: "'X-Forwarded-*' başlıklarına güvenin. Doğru istemci IP'sini almak istiyorsanız ve Uptime Kuma'nız Nginx veya Apache'nin arkasındaysa, bunu etkinleştirmelisiniz.",
wayToGetLineNotifyToken: "{0} adresinden bir erişim jetonu alabilirsiniz.",
Examples: "Örnekler",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token": "Long-Lived Erişim Anahtarı",
"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 Erişim Anahtarı, profil adınıza (sol altta) tıklayarak ve aşağıya kaydırarak ve ardından Anahtar Oluştur'a tıklayarak oluşturulabilir. ",
"Notification Service": "Bildirim Hizmeti",
"default: notify all devices": "varsayılan: tüm cihazları bilgilendir",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Cihazınızın/telefonunuzun adını bulmak için Home Assistant'ta \"Geliştirici Araçları > Hizmetler\" \"bildirim\" araması altında bir Bildirim Hizmetleri listesi bulunabilir.",
"Automations can optionally be triggered in Home Assistant:": "Otomasyonlar isteğe bağlı olarak Home Assistant'ta tetiklenebilir:",
"Trigger type:": "Trigger tipi:",
"Event type:": "Etkinlik tipi:",
"Event data:": "Etkinlik verileri:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Ardından bir eylem seçin, örneğin RGB ışığının kırmızı olduğu sahneyi değiştirin.",
"Frontend Version": "Frontend Sürümü",
"Frontend Version do not match backend version!": "Frontend Sürümü, backend sürümüyle eşleşmiyor!",
"Base URL": "Temel URL",
goAlertInfo: "GoAlert, çağrı üzerine zamanlama, otomatik eskalasyonlar ve bildirimler (SMS veya sesli çağrılar gibi) için açık kaynaklı bir uygulamadır. Doğru kişiyi, doğru şekilde ve doğru zamanda otomatik olarak devreye sokun! {0}",
goAlertIntegrationKeyInfo: "Servis için genel API entegrasyon anahtarını, genellikle kopyalanan URL'nin belirteç parametresinin değeri olan \"aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" biçiminde alın.",
goAlert: "GoAlert",
backupOutdatedWarning: "Kullanımdan Kaldırıldı: Birçok özellik eklendiğinden ve bu yedekleme özelliği biraz bakımsız olduğundan, tam bir yedekleme oluşturamaz veya geri yükleyemez.",
backupRecommend: "Lütfen bunun yerine birimi veya veri klasörünü (./data/) doğrudan yedekleyin.",
}; };

@ -6,7 +6,7 @@
<Tag v-for="tag in monitor.tags" :key="tag.id" :item="tag" :size="'sm'" /> <Tag v-for="tag in monitor.tags" :key="tag.id" :item="tag" :size="'sm'" />
</div> </div>
<p class="url"> <p class="url">
<a v-if="monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank">{{ monitor.url }}</a> <a v-if="monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank" rel="noopener noreferrer">{{ monitor.url }}</a>
<span v-if="monitor.type === 'port'">TCP Ping {{ monitor.hostname }}:{{ monitor.port }}</span> <span v-if="monitor.type === 'port'">TCP Ping {{ monitor.hostname }}:{{ monitor.port }}</span>
<span v-if="monitor.type === 'ping'">Ping: {{ monitor.hostname }}</span> <span v-if="monitor.type === 'ping'">Ping: {{ monitor.hostname }}</span>
<span v-if="monitor.type === 'keyword'"> <span v-if="monitor.type === 'keyword'">

@ -1,5 +1,5 @@
<template> <template>
<div class="form-container"> <div class="form-container" data-cy="setup-form">
<div class="form"> <div class="form">
<form @submit.prevent="submit"> <form @submit.prevent="submit">
<div> <div>
@ -23,21 +23,21 @@
</div> </div>
<div class="form-floating mt-3"> <div class="form-floating mt-3">
<input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username" required> <input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username" required data-cy="username-input">
<label for="floatingInput">{{ $t("Username") }}</label> <label for="floatingInput">{{ $t("Username") }}</label>
</div> </div>
<div class="form-floating mt-3"> <div class="form-floating mt-3">
<input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password" required> <input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password" required data-cy="password-input">
<label for="floatingPassword">{{ $t("Password") }}</label> <label for="floatingPassword">{{ $t("Password") }}</label>
</div> </div>
<div class="form-floating mt-3"> <div class="form-floating mt-3">
<input id="repeat" v-model="repeatPassword" type="password" class="form-control" placeholder="Repeat Password" required> <input id="repeat" v-model="repeatPassword" type="password" class="form-control" placeholder="Repeat Password" required data-cy="password-repeat-input">
<label for="repeat">{{ $t("Repeat Password") }}</label> <label for="repeat">{{ $t("Repeat Password") }}</label>
</div> </div>
<button class="w-100 btn btn-primary mt-3" type="submit" :disabled="processing"> <button class="w-100 btn btn-primary mt-3" type="submit" :disabled="processing" data-cy="submit-setup-form">
{{ $t("Create") }} {{ $t("Create") }}
</button> </button>
</form> </form>

@ -265,7 +265,7 @@
<Editable v-model="config.footerText" tag="div" :contenteditable="enableEditMode" :noNL="false" class="alert-heading p-2" /> <Editable v-model="config.footerText" tag="div" :contenteditable="enableEditMode" :noNL="false" class="alert-heading p-2" />
<p v-if="config.showPoweredBy"> <p v-if="config.showPoweredBy">
{{ $t("Powered by") }} <a target="_blank" href="https://github.com/louislam/uptime-kuma">{{ $t("Uptime Kuma" ) }}</a> {{ $t("Powered by") }} <a target="_blank" rel="noopener noreferrer" href="https://github.com/louislam/uptime-kuma">{{ $t("Uptime Kuma" ) }}</a>
</p> </p>
</footer> </footer>
</div> </div>

@ -11,9 +11,11 @@
"removeComments": false, "removeComments": false,
"preserveConstEnums": true, "preserveConstEnums": true,
"sourceMap": false, "sourceMap": false,
"strict": true "strict": true,
"types": ["cypress"]
}, },
"files": [ "files": [
"./src/util.ts" "./src/util.ts",
] ],
"include": ["cypress/**/*.ts"]
} }

Loading…
Cancel
Save