Compare commits

...

81 Commits

Author SHA1 Message Date
Louis Lam
4ae437dd61 Update to 1.21.1 2023-03-27 20:09:24 +08:00
Louis Lam
6cb296b07a Update SQLite and Vue 2023-03-27 19:05:18 +08:00
Louis Lam
644c6a872f Merge pull request #2978 from UptimeKumaBot/weblate-uptime-kuma-uptime-kuma
Translations Update from Weblate
2023-03-27 17:54:50 +08:00
Weblate
8c69c18f6d Merge remote-tracking branch 'origin/master' 2023-03-27 08:38:00 +00:00
Mirinek
c1a1160767 Translated using Weblate (Czech)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Mirinek <mirek.nozicka77@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/cs/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Louis Lam
a0ebd88849 Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 96.0% (681 of 709 strings)

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/zh_Hant_HK/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
401Unauthorized
2e9413cf33 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: 401Unauthorized <hi@4o1.to>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/zh_Hans/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Taha İPEK
278b52ec34 Translated using Weblate (Turkish)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Taha İPEK <ti.tahaipek@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/tr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Alex
caa757a27c Translated using Weblate (Russian)
Currently translated at 99.8% (708 of 709 strings)

Co-authored-by: Alex <proactivecam@inbox.ru>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Cyril59310
3ce117a943 Translated using Weblate (French)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Cyril59310 <archas.cyril@hotmail.fr>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/fr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Peter Petrík
cefe484b47 Translated using Weblate (Slovak)
Currently translated at 27.2% (193 of 708 strings)

Co-authored-by: Peter Petrík <peter.petrik.fefe@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/sk/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
ilya12077
a700892709 Translated using Weblate (Russian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: ilya12077 <mr.ilya.1207@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
Alex
13d721ccf8 Translated using Weblate (Russian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Alex <proactivecam@inbox.ru>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
DoyunShin
6c66bff518 Translated using Weblate (Korean)
Currently translated at 97.7% (692 of 708 strings)

Co-authored-by: DoyunShin <doyun.shin@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ko/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
AmadeusGraves
bea51d048b Translated using Weblate (Spanish)
Currently translated at 99.2% (703 of 708 strings)

Co-authored-by: AmadeusGraves <angelfx19@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/es/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
Louis Lam
2e1a0fe4d5 Merge pull request #2983 from GrantBirki/master
GitHub Actions - Validate json / yaml files 📁
2023-03-27 16:36:20 +08:00
grantbirki
27b0895722 fix branch names 2023-03-26 22:35:00 +01:00
grantbirki
e687698851 add json / yaml validate job 2023-03-26 22:34:25 +01:00
Louis Lam
fbdeb30ce7 Merge pull request #2973 from chakflying/fix/limit-precision
Fix: Apply toPrecision as last step
2023-03-26 15:46:00 +08:00
Louis Lam
41bda4e1d7 Merge pull request #2975 from chakflying/fix/badge-no-label
Fix: Allow status badge with empty label
2023-03-26 15:42:12 +08:00
Louis Lam
4869e6531c Merge pull request #2980 from Genc/feature/twilio-notification-provider
Add Twilio Sms Notification Provider
2023-03-26 15:38:53 +08:00
Louis Lam
302b9cf644 Merge pull request #2956 from wwniclask25/feature/opsgenie-alerts
Feat: Add opsgenie notification provider
2023-03-26 15:36:50 +08:00
Louis Lam
3c3a192943 Merge pull request #2906 from chakflying/fix/duplicate-expiry-notif
Fix: Check for TLS expiry notified days smaller than target
2023-03-26 15:34:26 +08:00
Faruk Genç
b64c835cee Add Twilio Sms Notification Provider 2023-03-25 19:56:01 +03:00
Louis Lam
5266e713e6 Update ask-for-help.yaml 2023-03-25 23:06:51 +08:00
Louis Lam
86579d245f Update ask-for-help.yaml 2023-03-25 23:06:23 +08:00
Louis Lam
b6169408be Merge pull request #2962 from chakflying/fix/missing-clear-form
Fix: Add missing clearForm func.
2023-03-25 14:31:47 +08:00
Nelson Chan
4f05912276 Fix: Allow status badge with empty label 2023-03-25 02:44:15 +08:00
Nelson Chan
bf525371d9 Fix: Apply toPrecision as last step 2023-03-24 22:42:50 +08:00
Louis Lam
89bfc3bf33 Merge pull request #2908 from chakflying/chore/encrypted-private-key
Chore: Add support for encrypted SSL-key
2023-03-24 21:36:22 +08:00
Louis Lam
a2014278b8 Fix #2969 2023-03-24 19:16:12 +08:00
Louis Lam
70572af1af Fix #2969 2023-03-24 18:40:05 +08:00
Louis Lam
b31c23a43b Merge pull request #2970 from louislam/fix-2968
Fix crash issue caused by mysqlQuery()
2023-03-24 18:20:15 +08:00
Louis Lam
f4ee5271af Improve error handling of mysqlQuery and return row count as result 2023-03-24 16:24:00 +08:00
Louis Lam
7330db3563 Improve error handling of mysqlQuery and return row count as result 2023-03-24 16:08:30 +08:00
Louis Lam
097567e5f0 Merge pull request #2878 from chakflying/feat/status-page-countdown
Feat: Add status page countdown to refresh
2023-03-23 17:18:57 +08:00
Louis Lam
35f300c8eb Improve and reuse language keys 2023-03-23 17:17:53 +08:00
Nelson Chan
4c9d7ac8ca Fix: Add missing clearForm func. 2023-03-22 15:06:38 +08:00
niclas.koegl
d9558833fc Fix linting 2023-03-21 19:45:44 +01:00
niclas.koegl
776a482a1d Add Opsgenie notification provider 2023-03-21 19:29:37 +01:00
niclas.koegl
d2527d7254 Merge branch 'master' into feature/opsgenie-alerts 2023-03-21 18:10:10 +01:00
niclas.koegl
6dfca0c163 Add Opsgenie notification provider 2023-03-21 18:07:19 +01:00
Louis Lam
72317633d9 Update to 1.21.0 2023-03-20 18:07:54 +08:00
Louis Lam
1973db28bf minor 2023-03-20 18:02:31 +08:00
Louis Lam
972ae60cfc Merge pull request #2913 from UptimeKumaBot/weblate-uptime-kuma-uptime-kuma
Translations Update from Weblate
2023-03-20 18:01:42 +08:00
Weblate
56410afc3b Merge remote-tracking branch 'origin/master' 2023-03-20 09:57:54 +00:00
Alanimdeo
df975c2750 Translated using Weblate (Korean)
Currently translated at 97.1% (688 of 708 strings)

Co-authored-by: Alanimdeo <alan@imdeo.kr>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ko/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Louis Lam
0cfd3fa642 Translated using Weblate (Georgian)
Currently translated at 1.5% (11 of 708 strings)

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ka/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Yoswaris Lawpaiboon
0b91391ced Translated using Weblate (Thai)
Currently translated at 81.3% (576 of 708 strings)

Co-authored-by: Yoswaris Lawpaiboon <konglha19@outlook.co.th>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/th/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Bart Callant
02fde56aec Translated using Weblate (Dutch)
Currently translated at 94.7% (671 of 708 strings)

Co-authored-by: Bart Callant <bart@callant.net>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/nl/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Mikolajek
da225a225f Translated using Weblate (French)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Mikolajek <weblate-1530@npk.pm>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/fr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Marco
a40c03f6f3 Translated using Weblate (German)
Currently translated at 100.0% (708 of 708 strings)

Translated using Weblate (German (Switzerland))

Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Marco <marco@nanoweb.ch>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/de/
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/de_CH/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Ghvinerias
c238508060 Translated using Weblate (Georgian)
Currently translated at 1.6% (12 of 708 strings)

Added translation using Weblate (Georgian)

Co-authored-by: Ghvinerias <Ghvinerias@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ka/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Tomasz Bielinski
abcbc3c55e Translated using Weblate (Slovak)
Currently translated at 11.7% (83 of 708 strings)

Added translation using Weblate (Slovak)

Co-authored-by: Tomasz Bielinski <tomasz@bielinski.sk>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/sk/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
DoyunShin
350451edc8 Translated using Weblate (Korean)
Currently translated at 95.6% (677 of 708 strings)

Translated using Weblate (Korean)

Currently translated at 95.0% (673 of 708 strings)

Co-authored-by: DoyunShin <doyun.shin@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ko/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:49 +00:00
Nelson Chan
b4b2ae55c0 Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 95.6% (677 of 708 strings)

Co-authored-by: Nelson Chan <chakflying@hotmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/zh_Hant_HK/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
stanol
9ecb890f56 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: stanol <stanol777@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/uk/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Ömer Faruk Genç
4329fc6751 Translated using Weblate (Turkish)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Ömer Faruk Genç <omer@farukgenc.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/tr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Alexey
836e125256 Translated using Weblate (Russian)
Currently translated at 92.9% (658 of 708 strings)

Co-authored-by: Alexey <aosmirnov@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Donker_Jumala
0fe98de256 Translated using Weblate (Japanese)
Currently translated at 72.1% (511 of 708 strings)

Co-authored-by: Donker_Jumala <weareh0711@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ja/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Deathart
3825dd9f42 Translated using Weblate (French)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Deathart <deathart@hotmail.fr>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/fr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Cyril59310
c6cd0d9312 Translated using Weblate (French)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Cyril59310 <archas.cyril@hotmail.fr>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/fr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Michal
82975f8d7b Translated using Weblate (Czech)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Michal <black23@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/cs/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
MrEddX
2ebbcc25a9 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: MrEddX <mreddx@chatrix.one>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/bg/
Translation: Uptime Kuma/Uptime Kuma
2023-03-20 09:57:48 +00:00
Louis Lam
f2323b012b Deleted translation using Weblate (Chinese (Literary))
Deleted translation using Weblate (Mongolian)

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2023-03-20 09:57:48 +00:00
401Unauthorized
e5a6238cde chore: remove invalid template 2023-03-19 21:59:34 +08:00
Louis Lam
61506b1af2 [Deploy to demo] No need to restart demo-kuma 2023-03-15 15:06:53 +08:00
tombii
dbe73bd6ae Update monitor.js (#2929)
Language
2023-03-15 15:00:28 +08:00
Ghvinerias
0778549a6d Update i18n.js (#2927)
I want to commit to this project by translating it to Georgian,
I added "ge" : "ქართული", "ქართული" means Georgian in Georgian language
2023-03-15 14:57:47 +08:00
Louis Lam
09fa60de55 Merge pull request #2531 from doubles-ss/master
Feat: Add mtls authen option to http
2023-03-14 00:04:40 +08:00
Louis Lam
1e80365b73 Update node-ping to 0.4.4 2023-03-12 20:44:30 +08:00
Louis Lam
491239415e Merge remote-tracking branch 'origin/master' into doubles-ss_master
# Conflicts:
#	server/database.js
2023-03-12 18:38:19 +08:00
Nelson Chan
391692a708 Chore: Add support for encrypted SSL-key 2023-03-09 00:00:07 +08:00
Nelson Chan
f32fcb204f Fix: Check for notified days smaller than target 2023-03-08 22:26:19 +08:00
Nelson Chan
193a273557 Feat: Add status page countdown to refresh 2023-03-03 08:25:41 +08:00
Louis Lam
d668812df1 Fix merge issue 2023-02-25 17:59:25 +08:00
Louis Lam
f32d3af62c Merge remote-tracking branch 'origin/master' into doubles-ss_master
# Conflicts:
#	server/database.js
2023-02-25 17:57:25 +08:00
Louis Lam
8a115670cd Fix label and id
Co-authored-by: AlexKraus <alex.b.kraus@googlemail.com>
2023-02-25 17:55:40 +08:00
Suriya Soutmun
43941fa2c6 feat: add mtls authen method in http/http keyword 2023-02-07 09:40:47 +07:00
Suriya Soutmun
faa78443d6 chore: alter table monitor add column tls_ca, tls_cert, tls_key for certificate data 2023-02-07 09:40:44 +07:00
Suriya Soutmun
ab3b2bddba [empty commit] pull request for http/http keyword mTLS authen 2023-02-07 09:37:55 +07:00
46 changed files with 2160 additions and 15812 deletions

View File

@@ -26,6 +26,12 @@ body:
label: "📝 Describe your problem" label: "📝 Describe your problem"
description: "Please walk us through it step by step." description: "Please walk us through it step by step."
placeholder: "Describe what are you asking for..." placeholder: "Describe what are you asking for..."
- type: textarea
id: error-msg
validations:
required: false
attributes:
label: "📝 Error Message(s) or Log"
- type: input - type: input
id: uptime-kuma-version id: uptime-kuma-version
attributes: attributes:

View File

@@ -0,0 +1,25 @@
name: json-yaml-validate
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pull-requests: write # enable write permissions for pull request comments
jobs:
json-yaml-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-yaml-validate
id: json-yaml-validate
uses: GrantBirki/json-yaml-validate@v1.2.0
with:
comment: "true" # enable comment mode

13
db/patch-monitor-tls.sql Normal file
View File

@@ -0,0 +1,13 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD tls_ca TEXT default null;
ALTER TABLE monitor
ADD tls_cert TEXT default null;
ALTER TABLE monitor
ADD tls_key TEXT default null;
COMMIT;

View File

@@ -43,10 +43,11 @@ const prompt = (query) => new Promise((resolve) => rl.question(query, resolve));
}); });
console.log(result.stdout + result.stderr); console.log(result.stdout + result.stderr);
/*
result = await ssh.execCommand("pm2 restart 1", { result = await ssh.execCommand("pm2 restart 1", {
cwd, cwd,
}); });
console.log(result.stdout + result.stderr); console.log(result.stdout + result.stderr);*/
} catch (e) { } catch (e) {
console.log(e); console.log(e);

View File

@@ -13,7 +13,7 @@ lines = lines.filter((line) => line !== "");
lines = [ ...new Set(lines) ]; lines = [ ...new Set(lines) ];
// Remove @weblate and @UptimeKumaBot // Remove @weblate and @UptimeKumaBot
lines = lines.filter((line) => line !== "@weblate" && line !== "@UptimeKumaBot"); lines = lines.filter((line) => line !== "@weblate" && line !== "@UptimeKumaBot" && line !== "@louislam");
// Sort the lines // Sort the lines
lines = lines.sort(); lines = lines.sort();

16947
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "1.21.0-beta.1", "version": "1.21.1",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -39,7 +39,7 @@
"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", "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.20.2 && npm ci --production && npm run download-dist", "setup": "git checkout 1.21.1 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js", "download-dist": "node extra/download-dist.js",
"mark-as-nightly": "node extra/mark-as-nightly.js", "mark-as-nightly": "node extra/mark-as-nightly.js",
"reset-password": "node extra/reset-password.js", "reset-password": "node extra/reset-password.js",
@@ -69,8 +69,8 @@
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "~1.7.3", "@grpc/grpc-js": "~1.7.3",
"@louislam/ping": "~0.4.2-mod.2", "@louislam/ping": "~0.4.4-mod.0",
"@louislam/sqlite3": "15.1.2", "@louislam/sqlite3": "15.1.6",
"args-parser": "~1.3.0", "args-parser": "~1.3.0",
"axios": "~0.27.0", "axios": "~0.27.0",
"axios-ntlm": "1.3.0", "axios-ntlm": "1.3.0",
@@ -172,7 +172,7 @@
"v-pagination-3": "~0.1.7", "v-pagination-3": "~0.1.7",
"vite": "~3.1.0", "vite": "~3.1.0",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vue": "next", "vue": "~3.2.47",
"vue-chart-3": "3.0.9", "vue-chart-3": "3.0.9",
"vue-confirm-dialog": "~1.0.2", "vue-confirm-dialog": "~1.0.2",
"vue-contenteditable": "~3.0.4", "vue-contenteditable": "~3.0.4",

View File

@@ -73,6 +73,7 @@ class Database {
"patch-http-body-encoding.sql": true, "patch-http-body-encoding.sql": true,
"patch-add-description-monitor.sql": true, "patch-add-description-monitor.sql": true,
"patch-api-key-table.sql": true, "patch-api-key-table.sql": true,
"patch-monitor-tls.sql": true,
}; };
/** /**

View File

@@ -133,6 +133,9 @@ class Monitor extends BeanModel {
mqttPassword: this.mqttPassword, mqttPassword: this.mqttPassword,
authWorkstation: this.authWorkstation, authWorkstation: this.authWorkstation,
authDomain: this.authDomain, authDomain: this.authDomain,
tlsCa: this.tlsCa,
tlsCert: this.tlsCert,
tlsKey: this.tlsKey,
}; };
} }
@@ -331,6 +334,18 @@ class Monitor extends BeanModel {
options.httpsAgent = new https.Agent(httpsAgentOptions); options.httpsAgent = new https.Agent(httpsAgentOptions);
} }
if (this.auth_method === "mtls") {
if (this.tlsCert !== null && this.tlsCert !== "") {
options.httpsAgent.options.cert = Buffer.from(this.tlsCert);
}
if (this.tlsCa !== null && this.tlsCa !== "") {
options.httpsAgent.options.ca = Buffer.from(this.tlsCa);
}
if (this.tlsKey !== null && this.tlsKey !== "") {
options.httpsAgent.options.key = Buffer.from(this.tlsKey);
}
}
log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`); log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`);
log.debug("monitor", `[${this.name}] Axios Request`); log.debug("monitor", `[${this.name}] Axios Request`);
@@ -622,9 +637,7 @@ class Monitor extends BeanModel {
} else if (this.type === "mysql") { } else if (this.type === "mysql") {
let startTime = dayjs().valueOf(); let startTime = dayjs().valueOf();
await mysqlQuery(this.databaseConnectionString, this.databaseQuery); bean.msg = await mysqlQuery(this.databaseConnectionString, this.databaseQuery);
bean.msg = "";
bean.status = UP; bean.status = UP;
bean.ping = dayjs().valueOf() - startTime; bean.ping = dayjs().valueOf() - startTime;
} else if (this.type === "mongodb") { } else if (this.type === "mongodb") {
@@ -836,7 +849,6 @@ class Monitor extends BeanModel {
domain: this.authDomain, domain: this.authDomain,
workstation: this.authWorkstation ? this.authWorkstation : undefined workstation: this.authWorkstation ? this.authWorkstation : undefined
}); });
} else { } else {
res = await axios.request(options); res = await axios.request(options);
} }
@@ -1233,7 +1245,7 @@ class Monitor extends BeanModel {
if (notificationList.length > 0) { if (notificationList.length > 0) {
let row = await R.getRow("SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days = ?", [ let row = await R.getRow("SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days <= ?", [
"certificate", "certificate",
this.id, this.id,
targetDays, targetDays,
@@ -1251,7 +1263,7 @@ class Monitor extends BeanModel {
for (let notification of notificationList) { for (let notification of notificationList) {
try { try {
log.debug("monitor", "Sending to " + notification.name); log.debug("monitor", "Sending to " + notification.name);
await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] Certificate will be expired in ${daysRemaining} days`); await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] Certificate will expire in ${daysRemaining} days`);
sent = true; sent = true;
} catch (e) { } catch (e) {
log.error("monitor", "Cannot send cert notification to " + notification.name); log.error("monitor", "Cannot send cert notification to " + notification.name);

View File

@@ -0,0 +1,97 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN } = require("../../src/util");
const opsgenieAlertsUrlEU = "https://api.eu.opsgenie.com/v2/alerts";
const opsgenieAlertsUrlUS = "https://api.opsgenie.com/v2/alerts";
let okMsg = "Sent Successfully.";
class Opsgenie extends NotificationProvider {
name = "Opsgenie";
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let opsgenieAlertsUrl;
let priority = (notification.opsgeniePriority == "") ? 3 : notification.opsgeniePriority;
const textMsg = "Uptime Kuma Alert";
try {
switch (notification.opsgenieRegion) {
case "US":
opsgenieAlertsUrl = opsgenieAlertsUrlUS;
break;
case "EU":
opsgenieAlertsUrl = opsgenieAlertsUrlEU;
break;
default:
opsgenieAlertsUrl = opsgenieAlertsUrlUS;
}
if (heartbeatJSON == null) {
let notificationTestAlias = "uptime-kuma-notification-test";
let data = {
"message": msg,
"alias": notificationTestAlias,
"source": "Uptime Kuma",
"priority": "P5"
};
return this.post(notification, opsgenieAlertsUrl, data);
}
if (heartbeatJSON.status === DOWN) {
let data = {
"message": monitorJSON ? textMsg + `: ${monitorJSON.name}` : textMsg,
"alias": monitorJSON.name,
"description": msg,
"source": "Uptime Kuma",
"priority": `P${priority}`
};
return this.post(notification, opsgenieAlertsUrl, data);
}
if (heartbeatJSON.status === UP) {
let opsgenieAlertsCloseUrl = `${opsgenieAlertsUrl}/${encodeURIComponent(monitorJSON.name)}/close?identifierType=alias`;
let data = {
"source": "Uptime Kuma",
};
return this.post(notification, opsgenieAlertsCloseUrl, data);
}
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
*
* @param {BeanModel} notification
* @param {string} url Request url
* @param {Object} data Request body
* @returns {Promise<string>}
*/
async post(notification, url, data) {
let config = {
headers: {
"Content-Type": "application/json",
"Authorization": `GenieKey ${notification.opsgenieApiKey}`,
}
};
let res = await axios.post(url, data, config);
if (res.status == null) {
return "Opsgenie notification failed with invalid response!";
}
if (res.status < 200 || res.status >= 300) {
return `Opsgenie notification failed with status code ${res.status}`;
}
return okMsg;
}
}
module.exports = Opsgenie;

View File

@@ -0,0 +1,41 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class Twilio extends NotificationProvider {
name = "twilio";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
let accountSID = notification.twilioAccountSID;
let authToken = notification.twilioAuthToken;
try {
let config = {
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
"Authorization": "Basic " + Buffer.from(accountSID + ":" + authToken).toString("base64"),
}
};
let data = new URLSearchParams();
data.append("To", notification.twilioToNumber);
data.append("From", notification.twilioFromNumber);
data.append("Body", msg);
let url = "https://api.twilio.com/2010-04-01/Accounts/" + accountSID + "/Messages.json";
await axios.post(url, data, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = Twilio;

View File

@@ -23,6 +23,7 @@ const Mattermost = require("./notification-providers/mattermost");
const Ntfy = require("./notification-providers/ntfy"); const Ntfy = require("./notification-providers/ntfy");
const Octopush = require("./notification-providers/octopush"); const Octopush = require("./notification-providers/octopush");
const OneBot = require("./notification-providers/onebot"); const OneBot = require("./notification-providers/onebot");
const Opsgenie = require("./notification-providers/opsgenie");
const PagerDuty = require("./notification-providers/pagerduty"); const PagerDuty = require("./notification-providers/pagerduty");
const PagerTree = require("./notification-providers/pagertree"); const PagerTree = require("./notification-providers/pagertree");
const PromoSMS = require("./notification-providers/promosms"); const PromoSMS = require("./notification-providers/promosms");
@@ -41,6 +42,7 @@ const Stackfield = require("./notification-providers/stackfield");
const Teams = require("./notification-providers/teams"); const Teams = require("./notification-providers/teams");
const TechulusPush = require("./notification-providers/techulus-push"); const TechulusPush = require("./notification-providers/techulus-push");
const Telegram = require("./notification-providers/telegram"); const Telegram = require("./notification-providers/telegram");
const Twilio = require("./notification-providers/twilio");
const Splunk = require("./notification-providers/splunk"); const Splunk = require("./notification-providers/splunk");
const Webhook = require("./notification-providers/webhook"); const Webhook = require("./notification-providers/webhook");
const WeCom = require("./notification-providers/wecom"); const WeCom = require("./notification-providers/wecom");
@@ -83,6 +85,7 @@ class Notification {
new Ntfy(), new Ntfy(),
new Octopush(), new Octopush(),
new OneBot(), new OneBot(),
new Opsgenie(),
new PagerDuty(), new PagerDuty(),
new PagerTree(), new PagerTree(),
new PromoSMS(), new PromoSMS(),
@@ -103,6 +106,7 @@ class Notification {
new Teams(), new Teams(),
new TechulusPush(), new TechulusPush(),
new Telegram(), new Telegram(),
new Twilio(),
new Splunk(), new Splunk(),
new Webhook(), new Webhook(),
new WeCom(), new WeCom(),

View File

@@ -147,7 +147,11 @@ router.get("/api/badge/:id/status", cache("5 minutes"), async (request, response
const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId); const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId);
const state = overrideValue !== undefined ? overrideValue : heartbeat.status; const state = overrideValue !== undefined ? overrideValue : heartbeat.status;
badgeValues.label = label ?? "Status"; if (label === undefined) {
badgeValues.label = "Status";
} else {
badgeValues.label = label;
}
switch (state) { switch (state) {
case DOWN: case DOWN:
badgeValues.color = downColor; badgeValues.color = downColor;
@@ -224,7 +228,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
); );
// limit the displayed uptime percentage to four (two, when displayed as percent) decimal digits // limit the displayed uptime percentage to four (two, when displayed as percent) decimal digits
const cleanUptime = parseFloat(uptime.toPrecision(4)); const cleanUptime = (uptime * 100).toPrecision(4);
// use a given, custom color or calculate one based on the uptime value // use a given, custom color or calculate one based on the uptime value
badgeValues.color = color ?? percentageToColor(uptime); badgeValues.color = color ?? percentageToColor(uptime);
@@ -235,7 +239,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
labelPrefix, labelPrefix,
label ?? `Uptime (${requestedDuration}${labelSuffix})`, label ?? `Uptime (${requestedDuration}${labelSuffix})`,
]); ]);
badgeValues.message = filterAndJoin([ prefix, `${cleanUptime * 100}`, suffix ]); badgeValues.message = filterAndJoin([ prefix, cleanUptime, suffix ]);
} }
// build the SVG based on given values // build the SVG based on given values

View File

@@ -688,6 +688,9 @@ let needSetup = false;
bean.headers = monitor.headers; bean.headers = monitor.headers;
bean.basic_auth_user = monitor.basic_auth_user; bean.basic_auth_user = monitor.basic_auth_user;
bean.basic_auth_pass = monitor.basic_auth_pass; bean.basic_auth_pass = monitor.basic_auth_pass;
bean.tlsCa = monitor.tlsCa;
bean.tlsCert = monitor.tlsCert;
bean.tlsKey = monitor.tlsKey;
bean.interval = monitor.interval; bean.interval = monitor.interval;
bean.retryInterval = monitor.retryInterval; bean.retryInterval = monitor.retryInterval;
bean.resendInterval = monitor.resendInterval; bean.resendInterval = monitor.resendInterval;

View File

@@ -74,6 +74,7 @@ class UptimeKumaServer {
// SSL // SSL
const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined; const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined;
const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined; const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined;
const sslKeyPassphrase = args["ssl-key-passphrase"] || process.env.UPTIME_KUMA_SSL_KEY_PASSPHRASE || process.env.SSL_KEY_PASSPHRASE || undefined;
log.info("server", "Creating express and socket.io instance"); log.info("server", "Creating express and socket.io instance");
this.app = express(); this.app = express();
@@ -81,7 +82,8 @@ class UptimeKumaServer {
log.info("server", "Server Type: HTTPS"); log.info("server", "Server Type: HTTPS");
this.httpServer = https.createServer({ this.httpServer = https.createServer({
key: fs.readFileSync(sslKey), key: fs.readFileSync(sslKey),
cert: fs.readFileSync(sslCert) cert: fs.readFileSync(sslCert),
passphrase: sslKeyPassphrase,
}, this.app); }, this.app);
} else { } else {
log.info("server", "Server Type: HTTP"); log.info("server", "Server Type: HTTP");

View File

@@ -322,21 +322,28 @@ exports.postgresQuery = function (connectionString, query) {
* Run a query on MySQL/MariaDB * Run a query on MySQL/MariaDB
* @param {string} connectionString The database connection string * @param {string} connectionString The database connection string
* @param {string} query The query to validate the database with * @param {string} query The query to validate the database with
* @returns {Promise<(string[]|Object[]|Object)>} * @returns {Promise<(string)>}
*/ */
exports.mysqlQuery = function (connectionString, query) { exports.mysqlQuery = function (connectionString, query) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const connection = mysql.createConnection(connectionString); const connection = mysql.createConnection(connectionString);
connection.promise().query(query)
.then(res => { connection.on("error", (err) => {
resolve(res); reject(err);
}) });
.catch(err => {
connection.query(query, (err, res) => {
if (err) {
reject(err); reject(err);
}) } else {
.finally(() => { if (Array.isArray(res)) {
connection.destroy(); resolve("Rows: " + res.length);
}); } else {
resolve("No Error, but the result is not an array. Type: " + typeof res);
}
}
connection.destroy();
});
}); });
}; };

View File

@@ -159,6 +159,16 @@ export default {
} }
}); });
}, },
/** Clear Form inputs */
clearForm() {
this.key = {
name: "",
expires: this.minDate,
active: 1,
};
this.noExpire = false;
},
} }
}; };
</script> </script>

View File

@@ -13,6 +13,9 @@
:disabled="disabled" :disabled="disabled"
> >
<!-- A hidden textarea for copying text on non-https -->
<textarea ref="hiddenTextarea" style="position: fixed; left: -999999px; top: -999999px;"></textarea>
<a class="btn btn-outline-primary" @click="copyToClipboard(model)"> <a class="btn btn-outline-primary" @click="copyToClipboard(model)">
<font-awesome-icon :icon="icon" /> <font-awesome-icon :icon="icon" />
</a> </a>
@@ -111,24 +114,19 @@ export default {
}, 3000); }, 3000);
// navigator clipboard api needs a secure context (https) // navigator clipboard api needs a secure context (https)
// For http, use the text area method (else part)
if (navigator.clipboard && window.isSecureContext) { if (navigator.clipboard && window.isSecureContext) {
// navigator clipboard api method' // navigator clipboard api method'
return navigator.clipboard.writeText(textToCopy); return navigator.clipboard.writeText(textToCopy);
} else { } else {
// text area method // text area method
let textArea = document.createElement("textarea"); let textArea = this.$refs.hiddenTextarea;
textArea.value = textToCopy; textArea.value = textToCopy;
// make the textarea out of viewport
textArea.style.position = "fixed";
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus(); textArea.focus();
textArea.select(); textArea.select();
return new Promise((res, rej) => { return new Promise((res, rej) => {
// here the magic happens // here the magic happens
document.execCommand("copy") ? res() : rej(); document.execCommand("copy") ? res() : rej();
textArea.remove();
}); });
} }
} }

View File

@@ -129,6 +129,7 @@ export default {
"ntfy": "Ntfy", "ntfy": "Ntfy",
"octopush": "Octopush", "octopush": "Octopush",
"OneBot": "OneBot", "OneBot": "OneBot",
"Opsgenie": "Opsgenie",
"PagerDuty": "PagerDuty", "PagerDuty": "PagerDuty",
"pushbullet": "Pushbullet", "pushbullet": "Pushbullet",
"PushByTechulus": "Push by Techulus", "PushByTechulus": "Push by Techulus",
@@ -143,6 +144,7 @@ export default {
"stackfield": "Stackfield", "stackfield": "Stackfield",
"teams": "Microsoft Teams", "teams": "Microsoft Teams",
"telegram": "Telegram", "telegram": "Telegram",
"twilio": "Twilio",
"Splunk": "Splunk", "Splunk": "Splunk",
"webhook": "Webhook", "webhook": "Webhook",
"GoAlert": "GoAlert", "GoAlert": "GoAlert",

View File

@@ -0,0 +1,36 @@
<template>
<div class="mb-3">
<label for="opsgenie-region" class="form-label">{{ $t("Region") }}<span style="color: red;"><sup>*</sup></span></label>
<select id="opsgenie-region" v-model="$parent.notification.opsgenieRegion" class="form-select" required>
<option value="us">
US (Default)
</option>
<option value="eu">
EU
</option>
</select>
</div>
<div class="mb-3">
<label for="opsgenie-apikey" class="form-label">{{ $t("API Key") }}<span style="color: red;"><sup>*</sup></span></label>
<HiddenInput id="opsgenie-apikey" v-model="$parent.notification.opsgenieApiKey" required="true" autocomplete="false"></HiddenInput>
</div>
<div class="mb-3">
<label for="opsgenie-priority" class="form-label">{{ $t("Priority") }}</label>
<input id="opsgenie-priority" v-model="$parent.notification.opsgeniePriority" type="number" class="form-control" min="1" max="5" step="1">
</div>
<div class="form-text">
<span style="color: red;"><sup>*</sup></span>{{ $t("Required") }}
<i18n-t tag="p" keypath="aboutWebhooks" style="margin-top: 8px;">
<a href="https://docs.opsgenie.com/docs/alert-api" target="_blank">https://docs.opsgenie.com/docs/alert-api</a>
</i18n-t>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

View File

@@ -97,7 +97,6 @@
(leave blank for default one)<br /> (leave blank for default one)<br />
{{NAME}}: Service Name<br /> {{NAME}}: Service Name<br />
{{HOSTNAME_OR_URL}}: Hostname or URL<br /> {{HOSTNAME_OR_URL}}: Hostname or URL<br />
{{URL}}: URL<br />
{{STATUS}}: Status<br /> {{STATUS}}: Status<br />
</div> </div>
</div> </div>

View File

@@ -0,0 +1,27 @@
<template>
<div class="mb-3">
<label for="twilio-account-sid" class="form-label">{{ $t("Account SID") }}</label>
<input id="twilio-account-sid" v-model="$parent.notification.twilioAccountSID" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-auth-token" class="form-label">{{ $t("Auth Token") }}</label>
<input id="twilio-auth-token" v-model="$parent.notification.twilioAuthToken" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-from-number" class="form-label">{{ $t("From Number") }}</label>
<input id="twilio-from-number" v-model="$parent.notification.twilioFromNumber" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-to-number" class="form-label">{{ $t("To Number") }}</label>
<input id="twilio-to-number" v-model="$parent.notification.twilioToNumber" type="text" class="form-control" required>
</div>
<div class="mb-3">
<i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
<a href="https://www.twilio.com/docs/sms" target="_blank">https://www.twilio.com/docs/sms</a>
</i18n-t>
</div>
</template>

View File

@@ -21,6 +21,7 @@ import Mattermost from "./Mattermost.vue";
import Ntfy from "./Ntfy.vue"; import Ntfy from "./Ntfy.vue";
import Octopush from "./Octopush.vue"; import Octopush from "./Octopush.vue";
import OneBot from "./OneBot.vue"; import OneBot from "./OneBot.vue";
import Opsgenie from "./Opsgenie.vue";
import PagerDuty from "./PagerDuty.vue"; import PagerDuty from "./PagerDuty.vue";
import PagerTree from "./PagerTree.vue"; import PagerTree from "./PagerTree.vue";
import PromoSMS from "./PromoSMS.vue"; import PromoSMS from "./PromoSMS.vue";
@@ -41,6 +42,7 @@ import STMP from "./SMTP.vue";
import Teams from "./Teams.vue"; import Teams from "./Teams.vue";
import TechulusPush from "./TechulusPush.vue"; import TechulusPush from "./TechulusPush.vue";
import Telegram from "./Telegram.vue"; import Telegram from "./Telegram.vue";
import Twilio from "./Twilio.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"; import GoAlert from "./GoAlert.vue";
@@ -76,6 +78,7 @@ const NotificationFormList = {
"ntfy": Ntfy, "ntfy": Ntfy,
"octopush": Octopush, "octopush": Octopush,
"OneBot": OneBot, "OneBot": OneBot,
"Opsgenie": Opsgenie,
"PagerDuty": PagerDuty, "PagerDuty": PagerDuty,
"PagerTree": PagerTree, "PagerTree": PagerTree,
"promosms": PromoSMS, "promosms": PromoSMS,
@@ -95,6 +98,7 @@ const NotificationFormList = {
"stackfield": Stackfield, "stackfield": Stackfield,
"teams": Teams, "teams": Teams,
"telegram": Telegram, "telegram": Telegram,
"twilio": Twilio,
"Splunk": Splunk, "Splunk": Splunk,
"webhook": Webhook, "webhook": Webhook,
"WeCom": WeCom, "WeCom": WeCom,

View File

@@ -41,7 +41,8 @@ const languageList = {
"el-GR": "Ελληνικά", "el-GR": "Ελληνικά",
"yue": "繁體中文 (廣東話 / 粵語)", "yue": "繁體中文 (廣東話 / 粵語)",
"ro": "Limba română", "ro": "Limba română",
"ur": "Urdu" "ur": "Urdu",
"ge": "ქართული"
}; };
let messages = { let messages = {

View File

@@ -681,7 +681,7 @@
"infiniteRetention": "Задайте стойност 0 за безкрайно съхранение.", "infiniteRetention": "Задайте стойност 0 за безкрайно съхранение.",
"Monitor": "Монитор | Монитори", "Monitor": "Монитор | Монитори",
"dataRetentionTimeError": "Периодът на съхранение трябва да е 0 или по-голям", "dataRetentionTimeError": "Периодът на съхранение трябва да е 0 или по-голям",
"confirmDeleteTagMsg": "Сигурни ли сте, че желаете да изтриете този таг? Мониторите, свързани с него, няма да бъдат изтрити.", "confirmDeleteTagMsg": "Сигурни ли сте, че желаете да изтриете този етикет? Мониторите, свързани с него, няма да бъдат изтрити.",
"promosmsAllowLongSMS": "Позволи дълъг SMS", "promosmsAllowLongSMS": "Позволи дълъг SMS",
"Packet Size": "Размер на пакет", "Packet Size": "Размер на пакет",
"Custom Monitor Type": "Потребителски тип монитор", "Custom Monitor Type": "Потребителски тип монитор",
@@ -694,7 +694,7 @@
"confirmUninstallPlugin": "Сигурни ли сте, че желаете да деинсталирате този плъгин?", "confirmUninstallPlugin": "Сигурни ли сте, че желаете да деинсталирате този плъгин?",
"markdownSupported": "Поддържа се Markdown синтаксис", "markdownSupported": "Поддържа се Markdown синтаксис",
"Google Analytics ID": "Google Analytics ID", "Google Analytics ID": "Google Analytics ID",
"Edit Tag": "Редактиране на таг", "Edit Tag": "Редактиране на етикет",
"Learn More": "Научете повече", "Learn More": "Научете повече",
"Server Address": "Сървър адрес", "Server Address": "Сървър адрес",
"notificationRegional": "Регионални", "notificationRegional": "Регионални",
@@ -734,5 +734,9 @@
"wayToGetPagerTreeIntegrationURL": "След като създадете интеграция на Uptime Kuma в PagerTree, копирайте крайната точка. За пълни подробности вижте {0}", "wayToGetPagerTreeIntegrationURL": "След като създадете интеграция на Uptime Kuma в PagerTree, копирайте крайната точка. За пълни подробности вижте {0}",
"pagertreeIntegrationUrl": "URL Адрес за интеграция", "pagertreeIntegrationUrl": "URL Адрес за интеграция",
"pagertreeMedium": "Средна", "pagertreeMedium": "Средна",
"pagertreeCritical": "Критична" "pagertreeCritical": "Критична",
"Add New Tag": "Добави нов етикет",
"lunaseaTarget": "Цел",
"lunaseaDeviceID": "ID на устройството",
"lunaseaUserID": "ID на потребител"
} }

View File

@@ -736,7 +736,8 @@
"pagertreeHigh": "Nahlas", "pagertreeHigh": "Nahlas",
"wayToGetPagerTreeIntegrationURL": "Po vytvoření integrace Uptime Kuma v aplikaci PagerTree zkopírujte koncový bod. Zobrazit všechny podrobnosti {0}", "wayToGetPagerTreeIntegrationURL": "Po vytvoření integrace Uptime Kuma v aplikaci PagerTree zkopírujte koncový bod. Zobrazit všechny podrobnosti {0}",
"Add New Tag": "Přidat nový štítek", "Add New Tag": "Přidat nový štítek",
"lunaseaTarget": "cíl", "lunaseaTarget": "Cíl",
"lunaseaDeviceID": "ID zařízení", "lunaseaDeviceID": "ID zařízení",
"lunaseaUserID": "ID uživatele" "lunaseaUserID": "ID uživatele",
"statusPageRefreshIn": "Obnovení za: {0}"
} }

View File

@@ -731,5 +731,9 @@
"smseagleGroup": "Telefonbuch Gruppenname(n)", "smseagleGroup": "Telefonbuch Gruppenname(n)",
"smseagleRecipient": "Empfänger (mehrere müssen durch Komma getrennt werden)", "smseagleRecipient": "Empfänger (mehrere müssen durch Komma getrennt werden)",
"API Keys": "API Schlüssel", "API Keys": "API Schlüssel",
"Continue": "Weiter" "Continue": "Weiter",
"Add New Tag": "Neuen Tag hinzufügen",
"lunaseaTarget": "Ziel",
"lunaseaDeviceID": "Geräte-ID",
"lunaseaUserID": "Benutzer-ID"
} }

View File

@@ -734,5 +734,9 @@
"telegramMessageThreadID": "(Optional) Nachrichten Thread ID", "telegramMessageThreadID": "(Optional) Nachrichten Thread ID",
"telegramMessageThreadIDDescription": "Optionale eindeutige Kennung für den Ziel-Thread (Thema) des Forums; nur für Forum-Supergroups", "telegramMessageThreadIDDescription": "Optionale eindeutige Kennung für den Ziel-Thread (Thema) des Forums; nur für Forum-Supergroups",
"telegramSendSilently": "Stumm Senden", "telegramSendSilently": "Stumm Senden",
"telegramSendSilentlyDescription": "Sende die Nachricht stumm. Nutzer bekommen eine Benachrichtigung ohne Ton." "telegramSendSilentlyDescription": "Sende die Nachricht stumm. Nutzer bekommen eine Benachrichtigung ohne Ton.",
"Add New Tag": "Neuen Tag hinzufügen",
"lunaseaDeviceID": "Geräte-ID",
"lunaseaTarget": "Ziel",
"lunaseaUserID": "Benutzer-ID"
} }

View File

@@ -174,6 +174,7 @@
"Avg. Response": "Avg. Response", "Avg. Response": "Avg. Response",
"Entry Page": "Entry Page", "Entry Page": "Entry Page",
"statusPageNothing": "Nothing here, please add a group or a monitor.", "statusPageNothing": "Nothing here, please add a group or a monitor.",
"statusPageRefreshIn": "Refresh in: {0}",
"No Services": "No Services", "No Services": "No Services",
"All Systems Operational": "All Systems Operational", "All Systems Operational": "All Systems Operational",
"Partially Degraded Service": "Partially Degraded Service", "Partially Degraded Service": "Partially Degraded Service",
@@ -706,5 +707,9 @@
"wayToGetPagerTreeIntegrationURL": "After creating the Uptime Kuma integration in PagerTree, copy the Endpoint. See full details {0}", "wayToGetPagerTreeIntegrationURL": "After creating the Uptime Kuma integration in PagerTree, copy the Endpoint. See full details {0}",
"lunaseaTarget": "Target", "lunaseaTarget": "Target",
"lunaseaDeviceID": "Device ID", "lunaseaDeviceID": "Device ID",
"lunaseaUserID": "User ID" "lunaseaUserID": "User ID",
"twilioAccountSID": "Account SID",
"twilioAuthToken": "Auth Token",
"twilioFromNumber": "From Number",
"twilioToNumber": "To Number"
} }

View File

@@ -696,5 +696,47 @@
"Bark Endpoint": "Endpoint Bark", "Bark Endpoint": "Endpoint Bark",
"WebHookUrl": "WebHookUrl", "WebHookUrl": "WebHookUrl",
"High": "Alto", "High": "Alto",
"alertaApiEndpoint": "Endpoint API" "alertaApiEndpoint": "Endpoint API",
"Body Encoding": "Codificación del cuerpo",
"Expiry date": "Fecha de expiración",
"Expiry": "Expiración",
"API Keys": "Claves API",
"Key Added": "Clave añadida",
"Add Another": "Añadir otro",
"Continue": "Continuar",
"Don't expire": "No caduca",
"apiKey-inactive": "Inactivo",
"apiKey-expired": "Expirado",
"apiKey-active": "Activo",
"No API Keys": "No hay claves API",
"Add API Key": "Añadir clave API",
"apiKeyAddedMsg": "Su clave API ha sido añadida. Anótala, ya que no se volverá a mostrar.",
"Clone": "Clonar",
"cloneOf": "Clon de {0}",
"pagertreeDoNothing": "No hacer nada",
"pagertreeResolve": "Resolución automática",
"pagertreeCritical": "Crítico",
"pagertreeHigh": "Alto",
"pagertreeMedium": "Medio",
"pagertreeLow": "Bajo",
"pagertreeSilent": "Silencio",
"pagertreeUrgency": "Urgencia",
"pagertreeIntegrationUrl": "URL de integración",
"lunaseaTarget": "Objetivo",
"wayToGetPagerTreeIntegrationURL": "Después de crear la integración Uptime Kuma en PagerTree, copie el Endpoint. Ver todos los detalles {0}",
"Generate": "Generar",
"deleteAPIKeyMsg": "¿Está seguro de que desea eliminar esta clave API?",
"telegramMessageThreadID": "(Opcional) ID del hilo de mensajes",
"telegramMessageThreadIDDescription": "Opcional Identificador único para el hilo de mensajes de destino (asunto) del foro; solo para supergrupos de foros",
"telegramProtectContent": "Proteger Forwarding/Saving",
"telegramProtectContentDescription": "Si se activa, los mensajes del bot en Telegram estarán protegidos contra el reenvío y el guardado.",
"notificationRegional": "Regional",
"Clone Monitor": "Clonar Monitor",
"telegramSendSilently": "Enviar en silencio",
"telegramSendSilentlyDescription": "Envía el mensaje en silencio. Los usuarios recibirán una notificación sin sonido.",
"Add New Tag": "Añadir nueva etiqueta",
"lunaseaUserID": "ID Usuario",
"lunaseaDeviceID": "ID Dispositivo",
"disableAPIKeyMsg": "¿Está seguro de que desea desactivar esta clave API?",
"Expires": "Expira"
} }

View File

@@ -73,11 +73,11 @@
"Delete": "Supprimer", "Delete": "Supprimer",
"Current": "Actuellement", "Current": "Actuellement",
"Uptime": "Disponibilité", "Uptime": "Disponibilité",
"Cert Exp.": "Expiration SSL.", "Cert Exp.": "Expiration SSL",
"day": "jour | jours", "day": "jour | jours",
"-day": "-jour", "-day": "-jour",
"hour": "heure", "hour": "heure",
"-hour": "-heure", "-hour": "heures",
"Response": "Temps de réponse", "Response": "Temps de réponse",
"Ping": "Ping", "Ping": "Ping",
"Monitor Type": "Type de sonde", "Monitor Type": "Type de sonde",
@@ -734,5 +734,10 @@
"pagertreeDoNothing": "Ne fais rien", "pagertreeDoNothing": "Ne fais rien",
"pagertreeIntegrationUrl": "URL d'intégration", "pagertreeIntegrationUrl": "URL d'intégration",
"pagertreeCritical": "Critique", "pagertreeCritical": "Critique",
"wayToGetPagerTreeIntegrationURL": "Après avoir créé l'intégration Uptime Kuma dans PagerTree, copiez le fichier Endpoint. Voir tous les détails {0}" "wayToGetPagerTreeIntegrationURL": "Après avoir créé l'intégration Uptime Kuma dans PagerTree, copiez le fichier Endpoint. Voir tous les détails {0}",
"lunaseaDeviceID": "Identifiant de l'appareil",
"lunaseaUserID": "Identifiant de l'utilisateur",
"Add New Tag": "Ajouter une étiquette",
"lunaseaTarget": "Cible",
"statusPageRefreshIn": "Actualisation dans: {0}"
} }

View File

@@ -510,5 +510,7 @@
"Android": "Android", "Android": "Android",
"Huawei": "Huawei", "Huawei": "Huawei",
"Device Token": "デバイストークン", "Device Token": "デバイストークン",
"recurringIntervalMessage": "毎日1回実行する{0} 日に1回実行する" "recurringIntervalMessage": "毎日1回実行する{0} 日に1回実行する",
"Add New Tag": "新しいタグを追加",
"statusPageMaintenanceEndDate": "終了日"
} }

21
src/lang/ka.json Normal file
View File

@@ -0,0 +1,21 @@
{
"Dashboard": "დაფა",
"Help": "დახმარება",
"New Update": "განახლება",
"Language": "ენა",
"Appearance": "ვიზუალი",
"Theme": "სტილი",
"Game": "თამაში",
"Version": "ვერსია",
"Quick Stats": "თვალის გადავლება",
"Up": "მაღლა",
"Pending": "მოლოდინი",
"languageName": "Georgian",
"Settings": "კონფიგურაცია",
"General": "ძირითადი",
"Check Update On GitHub": "GitHub_ზე განახლების შემოწმება",
"List": "სია",
"Add": "დამატება",
"Add New Monitor": "ახალი მონიტორის დამატება",
"Down": "დაბლა"
}

View File

@@ -208,7 +208,7 @@
"smtpBCC": "숨은 참조", "smtpBCC": "숨은 참조",
"discord": "Discord", "discord": "Discord",
"Discord Webhook URL": "Discord 웹훅 URL", "Discord Webhook URL": "Discord 웹훅 URL",
"wayToGetDiscordURL": "서버 설정 -> 연동 -> 웹후크 보기 -> 새 웹후크에서 얻을 수 있어요", "wayToGetDiscordURL": "서버 설정 -> 연동 -> 웹 보기 -> 새 웹에서 얻을 수 있어요",
"Bot Display Name": "표시 이름", "Bot Display Name": "표시 이름",
"Prefix Custom Message": "접두사 메시지", "Prefix Custom Message": "접두사 메시지",
"Hello @everyone is...": "{'@'}everyone 서버 상태 알림이에요…", "Hello @everyone is...": "{'@'}everyone 서버 상태 알림이에요…",
@@ -691,5 +691,38 @@
"webhookAdditionalHeadersTitle": "추가 헤더", "webhookAdditionalHeadersTitle": "추가 헤더",
"webhookAdditionalHeadersDesc": "웹훅과 함께 전송될 추가 헤더를 설정해요.", "webhookAdditionalHeadersDesc": "웹훅과 함께 전송될 추가 헤더를 설정해요.",
"HTTP Headers": "HTTP 헤더", "HTTP Headers": "HTTP 헤더",
"Trust Proxy": "프록시 신뢰" "Trust Proxy": "프록시 신뢰",
"API Keys": "API 키",
"markdownSupported": "Markdown 문법이 지원됨",
"telegramMessageThreadID": "(선택) 메시지 스레드 ID",
"Clone": "복제",
"cloneOf": "{0}의 복제본",
"Clone Monitor": "모니터링 복제",
"telegramProtectContent": "포워딩/저장 보호",
"telegramProtectContentDescription": "활성화 시, 텔레그램 봇 메시지는 포워딩 및 저장으로부터 보호됩니다.",
"telegramSendSilentlyDescription": "조용히 메시지를 보냅니다. 사용자들은 무음으로 알림을 받습니다.",
"telegramSendSilently": "무음 알림",
"Add New Tag": "태그 추가",
"Edit Tag": "태그 수정",
"Server Address": "서버 주소",
"Learn More": "자세히 알아보기",
"Continue": "계속",
"Key Added": "키 추가됨",
"No API Keys": "API 키 없음",
"disableAPIKeyMsg": "이 API키를 정말로 비활성화하시겠습니까?",
"deleteAPIKeyMsg": "이 API키를 정말로 삭제하시겠습니까?",
"Generate": "생성",
"Body Encoding": "Body 인코딩",
"Expiry": "만료",
"Expiry date": "만료 날짜",
"Don't expire": "만료되지 않음",
"notificationRegional": "지역별",
"Google Analytics ID": "Google Analytics ID",
"Add API Key": "API 키 추가",
"apiKeyAddedMsg": "API 키가 추가되었습니다. 다시 표시되지 않을 것이므로 메모해 두세요.",
"pagertreeCritical": "치명적인",
"apiKey-active": "사용 가능",
"lunaseaUserID": "사용자 ID",
"apiKey-expired": "만료됨",
"Expires": "만료일"
} }

View File

@@ -1 +0,0 @@
{}

View File

@@ -1 +0,0 @@
{}

View File

@@ -696,5 +696,12 @@
"markdownSupported": "Markdown syntax ondersteund", "markdownSupported": "Markdown syntax ondersteund",
"Resend Notification if Down X times consecutively": "Melding x keer opnieuw sturen als monitor offline is", "Resend Notification if Down X times consecutively": "Melding x keer opnieuw sturen als monitor offline is",
"loadingError": "Kan de data niet ophalen, probeer het later opnieuw.", "loadingError": "Kan de data niet ophalen, probeer het later opnieuw.",
"smseagleContact": "Telefoonboek contact namen" "smseagleContact": "Telefoonboek contact namen",
"apiKey-active": "Actief",
"apiKey-expired": "Verlopen",
"pagertreeLow": "Laag",
"pagertreeHigh": "Hoog",
"Clone": "Dupliceer",
"cloneOf": "Duplicaat van {0}",
"Add New Tag": "Voeg nieuw label toe"
} }

View File

@@ -8,7 +8,7 @@
"acceptedStatusCodesDescription": "Выберите коды статусов для определения доступности сервиса.", "acceptedStatusCodesDescription": "Выберите коды статусов для определения доступности сервиса.",
"passwordNotMatchMsg": "Повтор пароля не совпадает.", "passwordNotMatchMsg": "Повтор пароля не совпадает.",
"notificationDescription": "Привяжите уведомления к мониторам.", "notificationDescription": "Привяжите уведомления к мониторам.",
"keywordDescription": "Поиск слова в чистом HTML или в JSON-ответе (чувствительно к регистру)", "keywordDescription": "Поиск слова в чистом HTML или в JSON-ответе (чувствительно к регистру).",
"pauseDashboardHome": "Пауза", "pauseDashboardHome": "Пауза",
"deleteMonitorMsg": "Вы действительно хотите удалить данный монитор?", "deleteMonitorMsg": "Вы действительно хотите удалить данный монитор?",
"deleteNotificationMsg": "Вы действительно хотите удалить это уведомление для всех мониторов?", "deleteNotificationMsg": "Вы действительно хотите удалить это уведомление для всех мониторов?",
@@ -45,9 +45,9 @@
"Uptime": "Аптайм", "Uptime": "Аптайм",
"Cert Exp.": "Сертификат истекает.", "Cert Exp.": "Сертификат истекает.",
"day": "день | дней", "day": "день | дней",
"-day": " дней", "-day": "-дней",
"hour": "час", "hour": "час",
"-hour": " часа", "-hour": "-часа",
"Response": "Ответ", "Response": "Ответ",
"Ping": "Пинг", "Ping": "Пинг",
"Monitor Type": "Тип монитора", "Monitor Type": "Тип монитора",
@@ -124,12 +124,12 @@
"Also apply to existing monitors": "Применить к существующим мониторам", "Also apply to existing monitors": "Применить к существующим мониторам",
"Export": "Экспорт", "Export": "Экспорт",
"Import": "Импорт", "Import": "Импорт",
"backupDescription": "Вы можете сохранить резервную копию всех мониторов и уведомлений в виде JSON-файла", "backupDescription": "Вы можете сохранить резервную копию всех мониторов и уведомлений в виде JSON-файла.",
"backupDescription2": "P.S. История и события сохранены не будут", "backupDescription2": "Важно: история и события сохранены не будут.",
"backupDescription3": "Важные данные, такие как токены уведомлений, добавляются при экспорте, поэтому храните файлы в безопасном месте", "backupDescription3": "Важные данные, такие как токены уведомлений, добавляются при экспорте, поэтому храните файлы в безопасном месте.",
"alertNoFile": "Выберите файл для импорта.", "alertNoFile": "Выберите файл для импорта.",
"alertWrongFileType": "Выберите JSON-файл.", "alertWrongFileType": "Выберите JSON-файл.",
"twoFAVerifyLabel": "Пожалуйста, введите свой токен, чтобы проверить работу 2FA", "twoFAVerifyLabel": "Пожалуйста, введите свой токен, чтобы проверить работу 2FA:",
"tokenValidSettingsMsg": "Токен действителен! Теперь вы можете сохранить настройки 2FA.", "tokenValidSettingsMsg": "Токен действителен! Теперь вы можете сохранить настройки 2FA.",
"confirmEnableTwoFAMsg": "Вы действительно хотите включить 2FA?", "confirmEnableTwoFAMsg": "Вы действительно хотите включить 2FA?",
"confirmDisableTwoFAMsg": "Вы действительно хотите выключить 2FA?", "confirmDisableTwoFAMsg": "Вы действительно хотите выключить 2FA?",
@@ -444,11 +444,11 @@
"The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.", "The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.",
"Page Not Found": "Страница не найдена", "Page Not Found": "Страница не найдена",
"wayToGetCloudflaredURL": "(Скачать cloudflared с {0})", "wayToGetCloudflaredURL": "(Скачать cloudflared с {0})",
"cloudflareWebsite": "Cloudflare Website", "cloudflareWebsite": "Веб-сайт Cloudflare",
"Message:": "Сообщение:", "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:", "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.", "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.": "Текущее соединение может быть потеряно, если вы в данный момент подключаетесь через туннель Cloudflare. Вы уверены, что хотите это остановить? Введите свой текущий пароль, чтобы подтвердить это.",
"HTTP Headers": "HTTP заголовки", "HTTP Headers": "заголовки HTTP",
"Trust Proxy": "Доверять прокси", "Trust Proxy": "Доверять прокси",
"Other Software": "Другое программное обеспечение", "Other Software": "Другое программное обеспечение",
"For example: nginx, Apache and Traefik.": "К примеру: nginx, Apache и Traefik.", "For example: nginx, Apache and Traefik.": "К примеру: nginx, Apache и Traefik.",
@@ -463,13 +463,13 @@
"Proxy": "Прокси", "Proxy": "Прокси",
"Date Created": "Дата создания", "Date Created": "Дата создания",
"HomeAssistant": "Home Assistant", "HomeAssistant": "Home Assistant",
"onebotHttpAddress": "OneBot HTTP Address", "onebotHttpAddress": "HTTP-адрес OneBot",
"onebotMessageType": "OneBot Message Type", "onebotMessageType": "Тип сообщения OneBot",
"onebotGroupMessage": "Группа", "onebotGroupMessage": "Группа",
"onebotPrivateMessage": "Private", "onebotPrivateMessage": "Private",
"onebotUserOrGroupId": "ID группы или пользователя", "onebotUserOrGroupId": "ID группы или пользователя",
"onebotSafetyTips": "В целях безопасности необходимо установить токен доступа", "onebotSafetyTips": "В целях безопасности необходимо установить токен доступа",
"PushDeer Key": "PushDeer Key", "PushDeer Key": "ключ PushDeer",
"Footer Text": "Текст нижнего колонтитула", "Footer Text": "Текст нижнего колонтитула",
"Show Powered By": "Показывать на чем создано", "Show Powered By": "Показывать на чем создано",
"Domain Names": "Доменные имена", "Domain Names": "Доменные имена",
@@ -488,40 +488,40 @@
"From Name/Number": "Имя/номер отправителя", "From Name/Number": "Имя/номер отправителя",
"Leave blank to use a shared sender number.": "Оставьте пустым, чтобы использовать общий номер отправителя.", "Leave blank to use a shared sender number.": "Оставьте пустым, чтобы использовать общий номер отправителя.",
"Octopush API Version": "Версия API Octopush", "Octopush API Version": "Версия API Octopush",
"Legacy Octopush-DM": "Legacy Octopush-DM", "Legacy Octopush-DM": "устаревший Octopush-DM",
"endpoint": "endpoint", "endpoint": "конечная точка",
"octopushAPIKey": "\"API key\" из учетных данных HTTP API в панели управления", "octopushAPIKey": "\"API key\" из учетных данных HTTP API в панели управления",
"octopushLogin": "\"Login\" из учетных данных HTTP API в панели управления", "octopushLogin": "\"Login\" из учетных данных HTTP API в панели управления",
"promosmsLogin": "Логин API", "promosmsLogin": "Логин API",
"promosmsPassword": "Пароль API", "promosmsPassword": "Пароль API",
"pushoversounds pushover": "Pushover (default)", "pushoversounds pushover": "Pushover (по умолчанию)",
"pushoversounds bike": "Bike", "pushoversounds bike": "Велосипед",
"pushoversounds bugle": "Bugle", "pushoversounds bugle": "Горн",
"pushoversounds cashregister": "Cash Register", "pushoversounds cashregister": "Кассовый аппарат",
"pushoversounds classical": "Classical", "pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic", "pushoversounds cosmic": "Космический",
"pushoversounds falling": "Falling", "pushoversounds falling": "Падающий",
"pushoversounds gamelan": "Gamelan", "pushoversounds gamelan": "Гамелан",
"pushoversounds incoming": "Incoming", "pushoversounds incoming": "Входящий",
"pushoversounds intermission": "Intermission", "pushoversounds intermission": "Антракт",
"pushoversounds magic": "Magic", "pushoversounds magic": "Магия",
"pushoversounds mechanical": "Mechanical", "pushoversounds mechanical": "Механический",
"pushoversounds pianobar": "Piano Bar", "pushoversounds pianobar": "Пиано-бар",
"pushoversounds siren": "Siren", "pushoversounds siren": "Сирена",
"pushoversounds spacealarm": "Space Alarm", "pushoversounds spacealarm": "Космическая сигнализация",
"pushoversounds tugboat": "Tug Boat", "pushoversounds tugboat": "Буксирное судно",
"pushoversounds alien": "Alien Alarm (long)", "pushoversounds alien": "Инопланетная тревога (долгое)",
"pushoversounds climb": "Climb (long)", "pushoversounds climb": "Подъем (долгое)",
"pushoversounds persistent": "Persistent (long)", "pushoversounds persistent": "Стойкий (долгое)",
"pushoversounds echo": "Pushover Echo (long)", "pushoversounds echo": "Pushover Эхо (долгое)",
"pushoversounds updown": "Up Down (long)", "pushoversounds updown": "Вверх вниз (долгое)",
"pushoversounds vibrate": "Vibrate Only", "pushoversounds vibrate": "Только вибрация",
"pushoversounds none": "None (silent)", "pushoversounds none": "Нет (тихо)",
"pushyAPIKey": "Secret API Key", "pushyAPIKey": "Секретный ключ API",
"pushyToken": "Токен устройства", "pushyToken": "Токен устройства",
"Using a Reverse Proxy?": "Используете обратный прокси?", "Using a Reverse Proxy?": "Используете обратный прокси?",
"Check how to config it for WebSocket": "Проверьте, как настроить его для WebSocket", "Check how to config it for WebSocket": "Проверьте, как настроить его для WebSocket",
"Steam Game Server": "Steam Game Server", "Steam Game Server": "Игровой сервер Steam",
"Most likely causes:": "Наиболее вероятные причины:", "Most likely causes:": "Наиболее вероятные причины:",
"The resource is no longer available.": "Ресурс больше не доступен.", "The resource is no longer available.": "Ресурс больше не доступен.",
"There might be a typing error in the address.": "В адресе может быть опечатка.", "There might be a typing error in the address.": "В адресе может быть опечатка.",
@@ -536,24 +536,24 @@
"certificationExpiryDescription": "HTTPS Мониторы инициируют уведомление, когда срок действия сертификата TLS истечет:", "certificationExpiryDescription": "HTTPS Мониторы инициируют уведомление, когда срок действия сертификата TLS истечет:",
"Setup Docker Host": "Настроить Docker Host", "Setup Docker Host": "Настроить Docker Host",
"Connection Type": "Тип соединения", "Connection Type": "Тип соединения",
"Docker Daemon": "Docker Daemon", "Docker Daemon": "Демон Docker",
"deleteDockerHostMsg": "Are you sure want to delete this docker host for all monitors?", "deleteDockerHostMsg": "Вы уверены, что хотите удалить этот узел docker для всех мониторов?",
"socket": "Socket", "socket": "Сокет",
"tcp": "TCP / HTTP", "tcp": "TCP / HTTP",
"Docker Container": "Docker контейнер", "Docker Container": "Docker контейнер",
"Container Name / ID": "Название контейнера / ID", "Container Name / ID": "Название контейнера / ID",
"Docker Host": "Docker Host", "Docker Host": "Хост Docker",
"Docker Hosts": "Docker Hosts", "Docker Hosts": "Хосты Docker",
"ntfy Topic": "ntfy Topic", "ntfy Topic": "тема ntfy",
"Domain": "Домен", "Domain": "Домен",
"Workstation": "Workstation", "Workstation": "Рабочая станция",
"disableCloudflaredNoAuthMsg": "Вы находитесь в режиме без авторизации, пароль не требуется.", "disableCloudflaredNoAuthMsg": "Вы находитесь в режиме без авторизации, пароль не требуется.",
"trustProxyDescription": "Доверять заголовкам 'X-Forwarded-*'. Если вы хотите получить правильный IP-адрес клиента, а ваш Uptime Kuma находится под Nginx или Apache, вам следует включить этот параметр.", "trustProxyDescription": "Доверять заголовкам 'X-Forwarded-*'. Если вы хотите получить правильный IP-адрес клиента, а ваш Uptime Kuma находится под Nginx или Apache, вам следует включить этот параметр.",
"wayToGetLineNotifyToken": "Вы можете получить токен доступа в {0}", "wayToGetLineNotifyToken": "Вы можете получить токен доступа в {0}",
"Examples": "Примеры", "Examples": "Примеры",
"Home Assistant URL": "Home Assistant URL", "Home Assistant URL": "URL-адрес Home Assistant",
"Long-Lived Access Token": "Токен доступа с длительным сроком службы", "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. ", "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": "Служба уведомлений", "Notification Service": "Служба уведомлений",
"default: notify all devices": "по стандарту: уведомлять все устройства", "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.": "Список служб уведомлений можно найти в Home Assistant в разделе \"Инструменты разработчика > Службы\", выполнив поиск по слову \"уведомление\", чтобы найти название вашего устройства/телефона.", "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Список служб уведомлений можно найти в Home Assistant в разделе \"Инструменты разработчика > Службы\", выполнив поиск по слову \"уведомление\", чтобы найти название вашего устройства/телефона.",
@@ -618,7 +618,7 @@
"Custom CSS": "Пользовательские CSS", "Custom CSS": "Пользовательские CSS",
"weekdayShortTue": "Вт", "weekdayShortTue": "Вт",
"dayOfWeek": "День недели", "dayOfWeek": "День недели",
"confirmDeleteTagMsg": "Вы уверены, что хотите удалить этот тег? Мониторы, связанные с этим тегом не будут удалены.", "confirmDeleteTagMsg": "Вы уверены, что хотите удалить этот тег? Мониторы, связанные с этим тегом не будут удалены.",
"loadingError": "Невозможно получить данные, пожалуйста попробуйте позже.", "loadingError": "Невозможно получить данные, пожалуйста попробуйте позже.",
"Packet Size": "Размер пакета", "Packet Size": "Размер пакета",
"warningTimezone": "Используется часовой пояс сервера", "warningTimezone": "Используется часовой пояс сервера",
@@ -676,10 +676,10 @@
"Integration URL": "URL интеграции", "Integration URL": "URL интеграции",
"do nothing": "ничего не делать", "do nothing": "ничего не делать",
"smseagleTo": "Номер(а) телефона", "smseagleTo": "Номер(а) телефона",
"smseagleGroup": "Имена групп в телефонной книжке", "smseagleGroup": "Название(я) групп телефонной книги",
"smseagleContact": "Имена контактов из телефонной книжки", "smseagleContact": "Имена контактов из телефонной книжки",
"smseagleRecipientType": "Тип получателя", "smseagleRecipientType": "Тип получателя",
"smseagleRecipient": "Получатель (через запятую, если несколько)", "smseagleRecipient": "Получатель(я) (через запятую, если необходимо указать несколько)",
"smseagleToken": "Токен доступа API", "smseagleToken": "Токен доступа API",
"smseagleUrl": "URL вашего SMSEagle устройства", "smseagleUrl": "URL вашего SMSEagle устройства",
"smseagleEncoding": "Отправить в юникоде", "smseagleEncoding": "Отправить в юникоде",
@@ -687,9 +687,9 @@
"Server Address": "Адрес сервера", "Server Address": "Адрес сервера",
"Learn More": "Узнать больше", "Learn More": "Узнать больше",
"topicExplanation": "MQTT топик для мониторинга", "topicExplanation": "MQTT топик для мониторинга",
"Guild ID": "Guild ID", "Guild ID": "Идентификатор гильдии",
"Kook": "Kook", "Kook": "Kook",
"wayToGetKookBotToken": "Создайте приложение и получите токен вашего бота тут {0}.", "wayToGetKookBotToken": "Создайте приложение и получите токен бота по адресу {0}",
"Resend Notification if Down X times consecutively": "Повторная отправка уведомления при падении несколько раз", "Resend Notification if Down X times consecutively": "Повторная отправка уведомления при падении несколько раз",
"telegramProtectContent": "Запретить пересылку/сохранение", "telegramProtectContent": "Запретить пересылку/сохранение",
"telegramProtectContentDescription": "Если включено, сообщения бота в Telegram будут запрещены для пересылки и сохранения.", "telegramProtectContentDescription": "Если включено, сообщения бота в Telegram будут запрещены для пересылки и сохранения.",
@@ -699,5 +699,54 @@
"Clone Monitor": "Копия", "Clone Monitor": "Копия",
"Clone": "Копия", "Clone": "Копия",
"cloneOf": "Копия {0}", "cloneOf": "Копия {0}",
"notificationRegional": "Региональный" "notificationRegional": "Региональный",
"Add New Tag": "Добавить тег",
"Body Encoding": "Тип содержимого запроса.(JSON or XML)",
"Strategy": "Стратегия",
"Free Mobile User Identifier": "Бесплатный идентификатор мобильного пользователя",
"Auto resolve or acknowledged": "Автоматическое разрешение или подтверждение",
"auto acknowledged": "автоматическое подтверждение",
"auto resolve": "автоматическое разрешение",
"API Keys": "Ключи API",
"Expiry": "Истекает",
"Expiry date": "Дата окончания действия",
"Don't expire": "Не истекает",
"Continue": "Продолжать",
"Add Another": "Добавьте еще один",
"Key Added": "Ключ добавлен",
"Add API Key": "Добавить ключ API",
"No API Keys": "Нет API ключей",
"apiKey-active": "Активный",
"apiKey-expired": "Истёк",
"apiKey-inactive": "Неактивный",
"Expires": "Истекает",
"disableAPIKeyMsg": "Вы уверены, что хотите отключить этот ключ?",
"Generate": "Создать",
"pagertreeResolve": "Автоматическое разрешение",
"pagertreeDoNothing": "ничего не делать",
"lunaseaTarget": "Цель",
"lunaseaDeviceID": "Идентификатор устройства",
"lunaseaUserID": "Идентификатор пользователя",
"Lowcost": "Низкая стоимость",
"pagertreeIntegrationUrl": "URL-адрес интеграции",
"pagertreeUrgency": "Срочность",
"pagertreeSilent": "Тихий",
"pagertreeLow": "Низкий",
"pagertreeMedium": "Средний",
"pagertreeHigh": "Высокий",
"pagertreeCritical": "Критический",
"high": "высокий",
"promosmsAllowLongSMS": "Разрешить длинные SMS-сообщения",
"Economy": "Экономия",
"wayToGetPagerDutyKey": "Вы можете получить это, перейдя в службу -> Каталог служб -> (Выберите службу) -> Интеграции -> Добавить интеграцию. Здесь вы можете выполнить поиск по \"Events API V2\". Дополнительная информация {0}",
"apiKeyAddedMsg": "Ваш API ключ был добавлен. Пожалуйста, запишите это, так как оно больше не будет показан.",
"deleteAPIKeyMsg": "Вы уверены, что хотите удалить этот ключ?",
"wayToGetPagerTreeIntegrationURL": "После создания интеграции Uptime Kuma в PagerTree, скопируйте конечную точку. Смотрите полную информацию {0}",
"telegramMessageThreadIDDescription": "Необязательный уникальный идентификатор для цепочки сообщений (темы) форума; только для форумов-супергрупп",
"grpcMethodDescription": "Название метода - преобразовать в формат cammelCase, такой как sayHello, check и т.д.",
"Proto Service Name": "название службы Proto",
"Proto Method": "Метод Proto",
"Proto Content": "Содержание Proto",
"telegramMessageThreadID": "(Необязательно) ID цепочки сообщений",
"statusPageRefreshIn": "Обновлять каждые: {0}"
} }

195
src/lang/sk.json Normal file
View File

@@ -0,0 +1,195 @@
{
"Settings": "Nastavenia",
"Help": "Nápoveda",
"New Update": "Nová aktualizácia",
"Language": "Jazyk",
"Appearance": "Vzhľad",
"Theme": "Téma",
"General": "Základné",
"Primary Base URL": "Základná URL",
"Version": "Verzia",
"List": "Zoznam",
"Add": "Pridať",
"Add New Monitor": "Pridať nové Sledovanie",
"Quick Stats": "Rýchly prehľad",
"Pending": "Čaká sa",
"statusMaintenance": "Údržba",
"Maintenance": "Údržba",
"General Monitor Type": "Základný typ Sledovania",
"Passive Monitor Type": "Pasívny typ Sledovania",
"Specific Monitor Type": "Špecifický typ Sledovania",
"pauseDashboardHome": "Pauza",
"Pause": "Pauza",
"Status": "Stav",
"Message": "Správa",
"No important events": "Žiadne dôležité udalosti",
"Edit": "Upraviť",
"Delete": "Odstrániť",
"Current": "Aktuálne",
"Cert Exp.": "Platnosť cert.",
"day": "deň | dni",
"hour": "hodina",
"Response": "Odpoveď",
"Ping": "Ping",
"Keyword": "Kľúčové slovo",
"Friendly Name": "Názov",
"Port": "Port",
"Retries": "Opakovania",
"Resend Notification if Down X times consecutively": "Poslať oznámenie znovu, ak je nedostupné X-krát za sebou",
"Advanced": "Pokročilé",
"checkEverySecond": "Skontrolovať každých {0} sekúnd",
"retryCheckEverySecond": "Zopakovať každých {0} sekúnd",
"resendEveryXTimes": "Znovu poslať každých {0} krát",
"resendDisabled": "Opakované odoslanie vypnuté",
"ignoreTLSError": "Ignorovať TLS/SSL chyby pre HTTPS stránky",
"upsideDownModeDescription": "Obrátiť stav. Pokiaľ je služba dostupná, zobrazuje sa ako NEDOSTUPNÁ.",
"Upside Down Mode": "Obrátený režim",
"Max. Redirects": "Max. počet presmerovaní",
"Accepted Status Codes": "Akceptované stavové kódy",
"Push URL": "Push URL",
"Save": "Uložiť",
"Notifications": "Notifikácie",
"Not available, please setup.": "Nedostupné, prosím nastavte.",
"Setup Notification": "Nastavenie notifikácií",
"Dark": "Tmavá",
"Light": "Svetlá",
"Auto": "Automaticky",
"Normal": "Normálna",
"Bottom": "Dole",
"None": "Žiadne",
"Timezone": "Časová zóna",
"languageName": "Slovenčina",
"Dashboard": "Dashboard",
"Check Update On GitHub": "Skontrolovať aktualizáciu na GitHub-e",
"Up": "Dostupné",
"Down": "Nedostupné",
"Unknown": "Neznáme",
"markdownSupported": "Podpora Markdown syntaxu",
"Name": "Názov",
"DateTime": "Dátum a čas",
"Resume": "Pokračovať",
"Uptime": "Doba prevádzky",
"Monitor": "Sledovanie | Sledovania",
"-day": "-dní",
"-hour": "-hodín",
"Monitor Type": "Typ Sledovania",
"URL": "URL",
"Hostname": "Adresa",
"Heartbeat Interval": "Heartbeat Interval",
"Heartbeat Retry Interval": "Interval opakovania pre Heartbeat",
"retriesDescription": "Maximálny počet opakovaní pred tým, ako je služba označená ako nedostupná a je zaslaná notifikácia",
"maxRedirectDescription": "Maximálny počet presmerovaní. Hodnota 0 vypne presmerovania.",
"needPushEvery": "Tuto adresu by ste mali volať každých {0} sekúnd.",
"pushOptionalParams": "Voliteľné parametre: {0}",
"Theme - Heartbeat Bar": "Téma - Heartbeat riadok",
"Game": "Hra",
"Search Engine Visibility": "Viditeľnosť vyhľadávačmi",
"Allow indexing": "Povoliť indexovanie",
"Change Password": "Zmeniť heslo",
"Current Password": "Aktuálne heslo",
"New Password": "Nové heslo",
"Repeat New Password": "Zopakovať nové heslo",
"Update Password": "Aktualizovať heslo",
"Disable Auth": "Vypnúť autentifikáciu",
"Enable Auth": "Zapnúť autentifikáciu",
"Please use this option carefully!": "Túto možnosť používajte opatrne!",
"Logout": "Odhlásiť sa",
"Leave": "Odísť",
"I understand, please disable": "Rozumiem, vypnite to",
"Yes": "Áno",
"No": "Nie",
"Username": "Používateľské meno",
"Password": "Heslo",
"Login": "Prihlásiť sa",
"No Monitors, please": "Žiadne sledovanie, prosím",
"add one": "pridať jeden",
"Notification Type": "Typ notifikácie",
"Email": "E-mail",
"Test": "Test",
"Certificate Info": "Informácie o certifikáte",
"Resolver Server": "DNS server",
"Last Result": "Posledný výsledok",
"Repeat Password": "Zopakovať heslo",
"Import Backup": "Importovať zálohu",
"Export Backup": "Exportovať zálohu",
"Export": "Exportovať",
"Import": "Importovať",
"respTime": "Čas odozvy (ms)",
"notAvailableShort": "Nie je číslo",
"Default enabled": "Predvolene povolené",
"Create": "Vytvoriť",
"Clear Data": "Vyčistiť dáta",
"Events": "Udalosti",
"Heartbeats": "Odpovede",
"Auto Get": "Získať automaticky",
"Schedule maintenance": "Naplánovať údržbu",
"Affected Monitors": "Dotknuté sledovania",
"Pick Affected Monitors...": "Vybrať dotknuté sledovania…",
"Start of maintenance": "Začiatok údržby",
"All Status Pages": "Všetky stavové stránky",
"Select status pages...": "Vybrať stránky stavu…",
"alertNoFile": "Vyberte súbor na import.",
"alertWrongFileType": "Vyberte súbor JSON.",
"Clear all statistics": "Vymazať všetky štatistiky",
"Skip existing": "Preskočiť existujúce",
"Overwrite": "Prepísať",
"Options": "Možnosti",
"Keep both": "Ponechať obe",
"Setup 2FA": "Nastavenie 2FA",
"Disable 2FA": "Zakázať 2FA",
"2FA Settings": "Nastavenia 2FA",
"Two Factor Authentication": "Dvojfaktorová autentifikácia",
"Inactive": "Neaktívne",
"Token": "Token",
"Show URI": "Zobraziť URI",
"Tags": "Značky",
"Add New below or Select...": "Pridať novú nižšie alebo vybrať…",
"Tag with this value already exist.": "Značka s touto hodnotou už existuje.",
"color": "Farba",
"value (optional)": "hodnota (voliteľné)",
"Gray": "Šedá",
"Red": "Červená",
"Orange": "Oranžová",
"Green": "Zelená",
"Indigo": "Indigo",
"Purple": "Fialová",
"Pink": "Ružová",
"Custom": "Vlastná",
"Avg. Ping": "Priemerný ping",
"Avg. Response": "Priemerný čas odpovede",
"Entry Page": "Vstupná stránka",
"No Services": "Žiadne služby",
"All Systems Operational": "Všetky systémy funkčné",
"Partially Degraded Service": "Čiastočne zhoršená služba",
"Degraded Service": "Degradovaná služba",
"Add Group": "Pridať skupinu",
"Add a monitor": "Pridať sledovanie",
"Edit Status Page": "Upraviť stavovú stránku",
"Go to Dashboard": "Prejdite na informačný panel",
"Status Page": "Stavová stránka",
"Status Pages": "Stavové stránky",
"defaultNotificationName": "Moje {notification} upozornenie ({number})",
"here": "tu",
"Required": "Povinné",
"Post URL": "Post URL",
"Content Type": "Druh obsahu",
"webhookJsonDesc": "{0} je vhodný pre všetky moderné servery HTTP, ako napríklad Express.js",
"webhookFormDataDesc": "{multipart} je dobré pre PHP. JSON bude potrebné analyzovať pomocou {decodeFunction}",
"Generate": "Generovať",
"Discourage search engines from indexing site": "Odradiť vyhľadávacie nástroje od indexovania stránky",
"disableauth.message1": "Ste si istý, že chcete <strong>vypnúť autentifikáciu</strong>?",
"disableauth.message2": "Je navrhnutý pre scenáre, <strong>kde máte v úmysle implementovať autentifikáciu treťou stranou</strong> pred Uptime Kuma, ako je Cloudflare Access, Authelia alebo iné autentifikačné mechanizmy.",
"Confirm": "Potvrdiť",
"Remember me": "Zapamätať si ma",
"Resource Record Type": "Typ záznamu",
"Create your admin account": "Vytvorte si účet administrátora",
"Apply on all existing monitors": "Aplikujte na všetky existujúce sledovania",
"Verify Token": "Overiť token",
"Enable 2FA": "Povoliť 2FA",
"Active": "Aktívne",
"Add New Tag": "Pridať novú značku",
"Tag with this name already exist.": "Značka s týmto názvom už existuje.",
"Blue": "Modrá",
"Search...": "Hľadať…",
"statusPageNothing": "Nič tu nie je, pridajte skupinu alebo sledovanie."
}

View File

@@ -4,7 +4,7 @@
"retryCheckEverySecond": "ลองใหม่ทุก {0} วินาที", "retryCheckEverySecond": "ลองใหม่ทุก {0} วินาที",
"retriesDescription": "จำนวนครั้งสูงสุดที่จะลองก่อนบริการถูกระบุว่าไม่สามารถใช้งานได้และส่งการแจ้งเตือน", "retriesDescription": "จำนวนครั้งสูงสุดที่จะลองก่อนบริการถูกระบุว่าไม่สามารถใช้งานได้และส่งการแจ้งเตือน",
"ignoreTLSError": "ไม่สนใจข้อผิดพลาด TLS/SSL สำหรับเว็บไซต์ HTTPS", "ignoreTLSError": "ไม่สนใจข้อผิดพลาด TLS/SSL สำหรับเว็บไซต์ HTTPS",
"upsideDownModeDescription": "ลับด้านสถานะ เช่น ถ้าบริการสามารถใช้งานได้จะถูกเปลี่ยนเป็นใช้งานไม่ได้", "upsideDownModeDescription": "ลับสถานะ เช่น ถ้าบริการสามารถใช้งานได้จะถูกเปลี่ยนเป็นใช้งานไม่ได้",
"maxRedirectDescription": "จำนวนครั้งสูงสุดที่จะเปลี่ยนเส้นทาง, ตั้งเป็น 0 เพื่อปิดการเปลี่ยนเส้นทาง", "maxRedirectDescription": "จำนวนครั้งสูงสุดที่จะเปลี่ยนเส้นทาง, ตั้งเป็น 0 เพื่อปิดการเปลี่ยนเส้นทาง",
"acceptedStatusCodesDescription": "เลือกรหัสสถานะที่ถือว่าการตอบกลับสำเร็จ", "acceptedStatusCodesDescription": "เลือกรหัสสถานะที่ถือว่าการตอบกลับสำเร็จ",
"passwordNotMatchMsg": "รหัสผ่านไม่ตรงกัน", "passwordNotMatchMsg": "รหัสผ่านไม่ตรงกัน",
@@ -30,7 +30,7 @@
"Dashboard": "แผงควบคุม", "Dashboard": "แผงควบคุม",
"New Update": "อัพเดทใหม่", "New Update": "อัพเดทใหม่",
"Language": "ภาษา", "Language": "ภาษา",
"Appearance": "รูปร่าง", "Appearance": "หน้าตา",
"Theme": "หน้าตา", "Theme": "หน้าตา",
"General": "ทั่วไป", "General": "ทั่วไป",
"Primary Base URL": "URL หลัก", "Primary Base URL": "URL หลัก",
@@ -73,7 +73,7 @@
"Retries": "จำนวนครั้งที่จะลองใหม่", "Retries": "จำนวนครั้งที่จะลองใหม่",
"Heartbeat Retry Interval": "ระยะห่างระหว่างการทดสอบใหม่หลังจากไม่สำเร็จ", "Heartbeat Retry Interval": "ระยะห่างระหว่างการทดสอบใหม่หลังจากไม่สำเร็จ",
"Advanced": "ขั้นสูง", "Advanced": "ขั้นสูง",
"Upside Down Mode": "โหมดลับด้าน", "Upside Down Mode": "โหมดลับ",
"Max. Redirects": "จำนวนการเปลี่ยนเส้นทางสูงสุด", "Max. Redirects": "จำนวนการเปลี่ยนเส้นทางสูงสุด",
"Accepted Status Codes": "รหัสสถานะที่ยอมรับ", "Accepted Status Codes": "รหัสสถานะที่ยอมรับ",
"Push URL": "URL เป้าหมาย", "Push URL": "URL เป้าหมาย",

View File

@@ -734,5 +734,10 @@
"pagertreeDoNothing": "Hiçbir şey yapma", "pagertreeDoNothing": "Hiçbir şey yapma",
"wayToGetPagerTreeIntegrationURL": "PagerTree'de Uptime Kuma entegrasyonunu oluşturduktan sonra Endpoint'i kopyalayın. Tüm ayrıntıları görün {0}", "wayToGetPagerTreeIntegrationURL": "PagerTree'de Uptime Kuma entegrasyonunu oluşturduktan sonra Endpoint'i kopyalayın. Tüm ayrıntıları görün {0}",
"pagertreeIntegrationUrl": "Entegrasyon URL", "pagertreeIntegrationUrl": "Entegrasyon URL",
"pagertreeResolve": "Otomatik Çöz" "pagertreeResolve": "Otomatik Çöz",
"lunaseaTarget": "Hedef",
"Add New Tag": "Yeni Etiket Ekle",
"lunaseaDeviceID": "Cihaz ID",
"lunaseaUserID": "Kullanıcı ID",
"statusPageRefreshIn": "{0} içinde yenilenecek"
} }

View File

@@ -740,5 +740,9 @@
"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. ": "Довготривалий токен доступу можна створити, натиснувши на ім'я вашого профілю (внизу ліворуч), прокрутивши його донизу і натиснувши кнопку Створити токен. ",
"high": "високий", "high": "високий",
"Disable": "Вимкнути", "Disable": "Вимкнути",
"Resend Notification if Down X times consecutively": "Повторно надіслати сповіщення, якщо було падіння X разів поспіль" "Resend Notification if Down X times consecutively": "Повторно надіслати сповіщення, якщо було падіння X разів поспіль",
"lunaseaTarget": "Ціль",
"Add New Tag": "Додати новий тег",
"lunaseaDeviceID": "ID пристрою",
"lunaseaUserID": "ID користувача"
} }

View File

@@ -740,5 +740,6 @@
"Add New Tag": "添加新标签", "Add New Tag": "添加新标签",
"lunaseaDeviceID": "设备ID", "lunaseaDeviceID": "设备ID",
"lunaseaTarget": "目标", "lunaseaTarget": "目标",
"lunaseaUserID": "用户ID" "lunaseaUserID": "用户ID",
"statusPageRefreshIn": "将于 {0} 后刷新"
} }

View File

@@ -228,7 +228,7 @@
"smtpCC": "CC", "smtpCC": "CC",
"smtpBCC": "BCC", "smtpBCC": "BCC",
"Discord Webhook URL": "Discord Webhook 網址", "Discord Webhook URL": "Discord Webhook 網址",
"wayToGetDiscordURL": "您可以前往伺服器設定 -> 整合 -> Webhook -> 新 Webhook 以取得", "wayToGetDiscordURL": "您可以前往 伺服器設定 -> 整合 -> Webhook -> 新 Webhook 以取得",
"Bot Display Name": "機器人顯示名稱", "Bot Display Name": "機器人顯示名稱",
"Prefix Custom Message": "前綴自訂訊息", "Prefix Custom Message": "前綴自訂訊息",
"Webhook URL": "Webhook 網址", "Webhook URL": "Webhook 網址",
@@ -376,10 +376,10 @@
"default": "預設", "default": "預設",
"enabled": "啟用", "enabled": "啟用",
"setAsDefault": "設為預設", "setAsDefault": "設為預設",
"deleteProxyMsg": "您確定要為所有監測器刪除此代理伺服器嗎?", "deleteProxyMsg": "您確定要為所有監測器刪除此 Proxy 嗎?",
"proxyDescription": "必須將代理伺服器指派給監測器才能運作。", "proxyDescription": "必須將 Proxy 指派給監測器才能運作。",
"enableProxyDescription": "此代理伺服器在啟用前不會在監測器上生效,您可以藉由控制啟用狀態來暫時對所有的監測器停用代理伺服器。", "enableProxyDescription": "此 Proxy 在啟用前不會在監測器上生效,您可以藉由控制啟用狀態來暫時對所有的監測器停用 Proxy。",
"setAsDefaultProxyDescription": "預設情況下,新監測器將啟用此代理伺服器。您仍可分別停用各監測器的代理伺服器。", "setAsDefaultProxyDescription": "預設情況下,新監測器將啟用此 Proxy。您仍可分別停用各監測器的 Proxy。",
"Maintenance": "維護", "Maintenance": "維護",
"statusMaintenance": "維護中", "statusMaintenance": "維護中",
"Enable DNS Cache": "啟用 DNS 快取", "Enable DNS Cache": "啟用 DNS 快取",
@@ -430,8 +430,8 @@
"Remove Token": "移除 Token", "Remove Token": "移除 Token",
"Start": "開始", "Start": "開始",
"User": "使用者", "User": "使用者",
"trustProxyDescription": "信任 'X-Forwarded-*' 的 Header。如果您想取得正確的 Client IP且您的 Uptime Kuma 架設於 Nginx 或 Apache 之後,您應啟用此選項。", "trustProxyDescription": "信任 'X-Forwarded-*' 的 Header。如果您想取得正確的 Client IP且您的 Uptime Kuma 架設於 Nginx 或 Apache Proxy 之後,您應啟用此選項。",
"Reverse Proxy": "Reverse Proxy", "Reverse Proxy": "反向 Proxy",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "若要取得長期有效 Access Token請按您的個人檔案名稱 (左下角),捲動至最下方,然後按建立 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. ": "若要取得長期有效 Access Token請按您的個人檔案名稱 (左下角),捲動至最下方,然後按建立 Token。 ",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "您可以在 Home Assistant 中查看通知服務的列表,在\"開發者工具 > 服務\"下搜尋\"通知\"來找到您的裝置/手機的名稱。", "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "您可以在 Home Assistant 中查看通知服務的列表,在\"開發者工具 > 服務\"下搜尋\"通知\"來找到您的裝置/手機的名稱。",
"loadingError": "未能取得數據,請重新再試。", "loadingError": "未能取得數據,請重新再試。",
@@ -483,7 +483,7 @@
"API Key": "API Key", "API Key": "API Key",
"Show update if available": "有更新時顯示", "Show update if available": "有更新時顯示",
"Also check beta release": "檢查 Beta 版本", "Also check beta release": "檢查 Beta 版本",
"Using a Reverse Proxy?": "正在使用 Reverse Proxy", "Using a Reverse Proxy?": "正在使用反向代理 (Reverse Proxy)",
"Check how to config it for WebSocket": "查看如何加入 WebSocket 設定", "Check how to config it for WebSocket": "查看如何加入 WebSocket 設定",
"Steam Game Server": "Steam 遊戲 Server", "Steam Game Server": "Steam 遊戲 Server",
"Most likely causes:": "最可能原因:", "Most likely causes:": "最可能原因:",
@@ -702,5 +702,12 @@
"Platform": "平台", "Platform": "平台",
"Device Token": "裝置 Token", "Device Token": "裝置 Token",
"telegramProtectContent": "禁止轉發/儲存", "telegramProtectContent": "禁止轉發/儲存",
"telegramProtectContentDescription": "如果選擇,用戶將不能轉發/儲存收到的信息。" "telegramProtectContentDescription": "如果選擇,用戶將不能轉發/儲存收到的信息。",
"Add New Tag": "加新標籤",
"Economy": "經濟",
"Lowcost": "平價",
"high": "高價",
"statusPageRefreshIn": "將於 {0} 後重新整理",
"SendKey": "SendKey",
"SMSManager API Docs": "SMSManager API 文件 "
} }

View File

@@ -546,28 +546,47 @@
<option value="ntlm"> <option value="ntlm">
NTLM NTLM
</option> </option>
<option value="mtls">
mTLS
</option>
</select> </select>
</div> </div>
<template v-if="monitor.authMethod && monitor.authMethod !== null "> <template v-if="monitor.authMethod && monitor.authMethod !== null ">
<div class="my-3"> <template v-if="monitor.authMethod === 'mtls' ">
<label for="basicauth" class="form-label">{{ $t("Username") }}</label>
<input id="basicauth-user" v-model="monitor.basic_auth_user" type="text" class="form-control" :placeholder="$t('Username')">
</div>
<div class="my-3">
<label for="basicauth" class="form-label">{{ $t("Password") }}</label>
<input id="basicauth-pass" v-model="monitor.basic_auth_pass" type="password" autocomplete="new-password" class="form-control" :placeholder="$t('Password')">
</div>
<template v-if="monitor.authMethod === 'ntlm' ">
<div class="my-3"> <div class="my-3">
<label for="basicauth" class="form-label">{{ $t("Domain") }}</label> <label for="tls-cert" class="form-label">{{ $t("Cert") }}</label>
<input id="basicauth-domain" v-model="monitor.authDomain" type="text" class="form-control" :placeholder="$t('Domain')"> <textarea id="tls-cert" v-model="monitor.tlsCert" class="form-control" :placeholder="$t('Cert body')" required></textarea>
</div>
<div class="my-3">
<label for="tls-key" class="form-label">{{ $t("Key") }}</label>
<textarea id="tls-key" v-model="monitor.tlsKey" class="form-control" :placeholder="$t('Key body')" required></textarea>
</div>
<div class="my-3">
<label for="tls-ca" class="form-label">{{ $t("CA") }}</label>
<textarea id="tls-ca" v-model="monitor.tlsCa" class="form-control" :placeholder="$t('Server CA')"></textarea>
</div>
</template>
<template v-else>
<div class="my-3">
<label for="basicauth-user" class="form-label">{{ $t("Username") }}</label>
<input id="basicauth-user" v-model="monitor.basic_auth_user" type="text" class="form-control" :placeholder="$t('Username')">
</div> </div>
<div class="my-3"> <div class="my-3">
<label for="basicauth" class="form-label">{{ $t("Workstation") }}</label> <label for="basicauth-pass" class="form-label">{{ $t("Password") }}</label>
<input id="basicauth-workstation" v-model="monitor.authWorkstation" type="text" class="form-control" :placeholder="$t('Workstation')"> <input id="basicauth-pass" v-model="monitor.basic_auth_pass" type="password" autocomplete="new-password" class="form-control" :placeholder="$t('Password')">
</div> </div>
<template v-if="monitor.authMethod === 'ntlm' ">
<div class="my-3">
<label for="ntlm-domain" class="form-label">{{ $t("Domain") }}</label>
<input id="ntlm-domain" v-model="monitor.authDomain" type="text" class="form-control" :placeholder="$t('Domain')">
</div>
<div class="my-3">
<label for="ntlm-workstation" class="form-label">{{ $t("Workstation") }}</label>
<input id="ntlm-workstation" v-model="monitor.authWorkstation" type="text" class="form-control" :placeholder="$t('Workstation')">
</div>
</template>
</template> </template>
</template> </template>
</template> </template>
@@ -925,6 +944,14 @@ message HealthCheckResponse {
} else if (this.isEdit || this.isClone) { } else if (this.isEdit || this.isClone) {
this.$root.getSocket().emit("getMonitor", this.$route.params.id, (res) => { this.$root.getSocket().emit("getMonitor", this.$route.params.id, (res) => {
if (res.ok) { if (res.ok) {
if (this.isClone) {
// Reset push token for cloned monitors
if (res.monitor.type === "push") {
res.monitor.pushToken = undefined;
}
}
this.monitor = res.monitor; this.monitor = res.monitor;
if (this.isClone) { if (this.isClone) {

View File

@@ -306,6 +306,11 @@
<p v-if="config.showPoweredBy"> <p v-if="config.showPoweredBy">
{{ $t("Powered by") }} <a target="_blank" rel="noopener noreferrer" 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>
<div class="refresh-info mb-2">
<div>{{ $t("Last Updated") }}: <date-time :value="lastUpdateTime" /></div>
<div>{{ $tc("statusPageRefreshIn", [ updateCountdownText]) }}</div>
</div>
</footer> </footer>
</div> </div>
@@ -322,6 +327,7 @@
<script> <script>
import axios from "axios"; import axios from "axios";
import dayjs from "dayjs"; import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import Favico from "favico.js"; import Favico from "favico.js";
// import highlighting library (you can use any library you want just return html string) // import highlighting library (you can use any library you want just return html string)
import { highlight, languages } from "prismjs/components/prism-core"; import { highlight, languages } from "prismjs/components/prism-core";
@@ -337,10 +343,12 @@ import DOMPurify from "dompurify";
import Confirm from "../components/Confirm.vue"; import Confirm from "../components/Confirm.vue";
import PublicGroupList from "../components/PublicGroupList.vue"; import PublicGroupList from "../components/PublicGroupList.vue";
import MaintenanceTime from "../components/MaintenanceTime.vue"; import MaintenanceTime from "../components/MaintenanceTime.vue";
import DateTime from "../components/Datetime.vue";
import { getResBaseURL } from "../util-frontend"; import { getResBaseURL } from "../util-frontend";
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts"; import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts";
const toast = useToast(); const toast = useToast();
dayjs.extend(duration);
const leavePageMsg = "Do you really want to leave? you have unsaved changes!"; const leavePageMsg = "Do you really want to leave? you have unsaved changes!";
@@ -359,6 +367,7 @@ export default {
Confirm, Confirm,
PrismEditor, PrismEditor,
MaintenanceTime, MaintenanceTime,
DateTime,
}, },
// Leave Page for vue route change // Leave Page for vue route change
@@ -400,6 +409,10 @@ export default {
baseURL: "", baseURL: "",
clickedEditButton: false, clickedEditButton: false,
maintenanceList: [], maintenanceList: [],
autoRefreshInterval: 5,
lastUpdateTime: dayjs(),
updateCountdown: null,
updateCountdownText: null,
}; };
}, },
computed: { computed: {
@@ -637,11 +650,13 @@ export default {
console.log(error); console.log(error);
}); });
// 5mins a loop // Configure auto-refresh loop
this.updateHeartbeatList(); this.updateHeartbeatList();
feedInterval = setInterval(() => { feedInterval = setInterval(() => {
this.updateHeartbeatList(); this.updateHeartbeatList();
}, (300 + 10) * 1000); }, (this.autoRefreshInterval * 60 + 10) * 1000);
this.updateUpdateTimer();
// Go to edit page if ?edit present // Go to edit page if ?edit present
// null means ?edit present, but no value // null means ?edit present, but no value
@@ -700,10 +715,29 @@ export default {
favicon.badge(downMonitors); favicon.badge(downMonitors);
this.loadedData = true; this.loadedData = true;
this.lastUpdateTime = dayjs();
this.updateUpdateTimer();
}); });
} }
}, },
/**
* Setup timer to display countdown to refresh
* @returns {void}
*/
updateUpdateTimer() {
clearInterval(this.updateCountdown);
this.updateCountdown = setInterval(() => {
const countdown = dayjs.duration(this.lastUpdateTime.add(this.autoRefreshInterval, "minutes").add(10, "seconds").diff(dayjs()));
if (countdown.as("seconds") < 0) {
clearInterval(this.updateCountdown);
} else {
this.updateCountdownText = countdown.format("mm:ss");
}
}, 1000);
},
/** Enable editing mode */ /** Enable editing mode */
edit() { edit() {
if (this.hasToken) { if (this.hasToken) {
@@ -1118,4 +1152,8 @@ footer {
} }
} }
.refresh-info {
opacity: 0.7;
}
</style> </style>