Compare commits

...

309 Commits

Author SHA1 Message Date
Louis Lam
16b2cf0e89 Update to 1.18.2 2022-10-04 17:50:11 +08:00
Louis Lam
c538983b87 Merge pull request #2169 from louislam/fix-docker-monitor
Fix Docker container monitor not working in 1.18.1
2022-10-04 17:47:56 +08:00
Louis Lam
0686757160 [Docker Monitor] Change tcp:// to http:// 2022-10-04 16:19:56 +08:00
Louis Lam
25ea99a436 Merge pull request #2161 from 5idereal/patch-1
Update zh-tw translation
2022-10-03 20:53:13 +08:00
5idereal
c2c3f981bc update zh-tw translation 2022-10-03 18:03:15 +08:00
Louis Lam
2c237e9c03 Merge pull request #2127 from phindmarsh/squadcast-notification-support
Squadcast notification support
2022-10-03 16:18:54 +08:00
Louis Lam
3e85893bdd Merge remote-tracking branch 'origin/master' into squadcast-notification-support
# Conflicts:
#	src/languages/en.js
2022-10-03 16:16:50 +08:00
Louis Lam
543a74ecab Merge pull request #1923 from rolfbachmann/ntfy-auth-support
Add authentication support for ntfy
2022-10-03 15:54:55 +08:00
Louis Lam
62ad2f9bb4 Merge pull request #2148 from Computroniks/bug/octopush-notifications-#2144
Fixed octopush legacy doesn't return error code
2022-10-03 15:53:54 +08:00
Louis Lam
7672057319 [ntfy] Do not autofill 2022-10-03 15:51:29 +08:00
Louis Lam
0f99d49a27 Merge remote-tracking branch 'origin/master' into ntfy-auth-support 2022-10-03 15:30:00 +08:00
Louis Lam
d93f7b33be Merge pull request #2153 from Computroniks/bug/#2009-teams-unnecessary-url-field
Fixed alert features unnecessary URL field #2009
2022-10-03 15:20:45 +08:00
Louis Lam
894aeaea0a Merge pull request #2158 from SametKUM/master
fix some translations
2022-10-03 15:16:15 +08:00
Louis Lam
97dc8eba13 Merge pull request #2156 from AnTheMaker/patch-2
Improve German translation
2022-10-03 15:15:47 +08:00
5idereal
d39a4770e0 sync 2022-10-03 13:11:39 +08:00
SametKUM
f6ac09b751 fix some translations 2022-10-02 21:14:00 +03:00
Louis Lam
9c1ad4f8c6 Merge pull request #2155 from AnTheMaker/patch-1
Fix typos in CONTRIBUTING.md
2022-10-02 20:14:23 +08:00
An | Anton Röhm
8595824b5d Improve German translation 2022-10-02 13:49:40 +02:00
An | Anton Röhm
da34685019 fix typos 2022-10-02 13:38:33 +02:00
Louis Lam
0cf28c2025 Merge pull request #2154 from MrEddX/bulgarian
Update bg-BG.js
2022-10-02 17:59:59 +08:00
MrEddX
ed7bc0e6d1 Update bg-BG.js
Added New Fields
2022-10-02 09:55:58 +03:00
Matthew Nickson
6a3eccf6a6 Fixed alert features unnecessary URL field #2009
The filling of the URL field was incorrect previously. It has been
updated to handle new monitor types.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-02 02:26:38 +01:00
Matthew Nickson
97de3959cd Updated octopush error handling to accept 000
The legacy octopush API includes an error code with all responses. A
code other than 000 is an error.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-01 19:48:00 +01:00
Matthew Nickson
63e408f4f2 Fixed octopush legacy doesn't return error code
The octopush legacy API does not return a HTTP error code and instead
always returns a HTTP 200. This means that no error it thrown even if
something like the parameters are incorrect.
Instead the error code is given in the json response data.
Therefore we must look at the response data and check for the presence
of the "error_code" key in the response data.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-01 15:42:34 +01:00
Louis Lam
a3b1123e82 Merge pull request #2147 from Computroniks/bug/octopush-notifications-#2144
Fixed Octopush Notifier not working #2144
2022-10-01 22:27:42 +08:00
Matthew Nickson
2e54dee817 Fixed Octopush Notifier not working #2144
The version number was passed as a string from the frontend but was
checked against a number in the backend provider. This caused the if else
if to fall through into an error. The literal it is now being compared
has been changed to a string and the unknown version error is no longer
encountered.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-01 15:03:28 +01:00
Louis Lam
ceeb47bf82 Merge pull request #2145 from Faris0520/patch-1
update some typo at id-ID.js
2022-10-01 14:36:57 +08:00
FarisDaffa
929d238106 Update id-ID.js 2022-10-01 12:17:17 +07:00
Patrick
bef9cb6a5f Linting fixes 2022-09-26 22:30:43 +13:00
Patrick
4157c7d546 Add support for Squadcast incoming webhook 2022-09-26 22:16:34 +13:00
Louis Lam
c3eef28443 Merge pull request #2122 from mjysci/test
feat: Add ServerChan Notification support
2022-09-25 15:01:58 +08:00
Louis Lam
443235b20b Update stale-bot.yml 2022-09-24 00:11:22 +08:00
Louis Lam
35810e299d Merge pull request #2121 from rezzorix/patch-6
Update stale-bot.yml
2022-09-24 00:07:37 +08:00
MA Junyi
b03624b7e3 feat: Add ServerChan Notification support 2022-09-23 23:27:22 +08:00
rezzorix
dcbd9c12cf Update stale-bot.yml
1. cron every 6 hours (from 24hrs)
2. close after 2 days scale (from 7)
3. operations per run 200 (from 90)
2022-09-23 21:59:38 +08:00
Louis Lam
83ca74eba7 Merge pull request #2118 from Buchtic/patch-2
Update cs-CZ.js
2022-09-23 16:22:29 +08:00
Buchtič
c6cf600722 Update cs-CZ.js
localization improvements
2022-09-22 19:30:43 +02:00
Louis Lam
22ef8ff751 Merge pull request #2111 from rezzorix/patch-6
Update stale-bot.yml
2022-09-21 18:41:45 +08:00
rezzorix
565e9233fe Update stale-bot.yml
Adding "operations-per-run: 90" to ensure the action catches all 600+ items that need to be processed etc.

If not defined, the default is 30 which captures only about 200 items a run which is not enough.
2022-09-21 18:27:18 +08:00
Louis Lam
9a7c2d562a Update PULL_REQUEST_TEMPLATE.md 2022-09-19 23:15:19 +08:00
Louis Lam
c4cb825fef Update PULL_REQUEST_TEMPLATE.md 2022-09-19 23:14:25 +08:00
Louis Lam
3193533a60 Update CONTRIBUTING.md 2022-09-19 19:56:30 +08:00
Louis Lam
1f1825dbff Update CONTRIBUTING.md 2022-09-19 19:39:30 +08:00
Louis Lam
e4e47c3976 Update README.md 2022-09-18 23:07:17 +08:00
Louis Lam
1c4e97439c Fix pr-test 2022-09-17 01:59:25 +08:00
Louis Lam
d23085cddc Fix #2100, the monitor name cannot display if too long 2022-09-17 01:18:49 +08:00
Louis Lam
f96bad1629 Merge pull request #2089 from jakubenglicky/smsmanager
feat: Add support notification via SMSManager
2022-09-16 14:29:50 +08:00
Super Manito
38c45a3fe3 Fix previously PR bug about Bark Notification (#2084)
Co-authored-by: zuosc <zorro.zsc@hotmail.com>
2022-09-16 14:21:22 +08:00
Louis Lam
e815e51608 Merge pull request #2099 from burakurer/patch-5
Update tr-TR.js
2022-09-16 14:17:01 +08:00
burakurer
bec3b0d2dc Update tr-TR.js 2022-09-16 00:16:08 +03:00
jakubenglicky
2d5096317f Fix warning at goalert.js 2022-09-15 09:11:27 +02:00
jakubenglicky
1c3da995e3 Add support notification via SMSManager 2022-09-15 09:11:05 +02:00
Louis Lam
db6fdf5e26 Update Project Plan URL
Migrated to the new GitHub Project
2022-09-14 02:36:18 +08:00
Louis Lam
fce175cad6 Merge pull request #2081 from cunkz/chore/update-language-id-ID
chore: update existing and add new text for language id-ID
2022-09-14 00:23:14 +08:00
Gilas Amalanda
b673cfbe94 chore: update typo for Tag with this name already exist at language id-ID 2022-09-13 21:38:58 +07:00
Gilas Amalanda
0ae8010156 chore: update typo for promosmsTypeFull at language id-ID 2022-09-13 21:37:58 +07:00
Gilas Amalanda
527e479f2d chore: update existing and add new text for language id-ID 2022-09-13 21:30:15 +07:00
Louis Lam
d63022676a Fix build issue after updated vite 2022-09-13 15:17:39 +08:00
Louis Lam
08fdbeaa75 Merge pull request #1866 from ThomasChr/logintitle
change page title to " - Login" when on Login Form
2022-09-12 18:48:05 +08:00
Louis Lam
0dd858d516 Warn about the backup feature 2022-09-12 18:45:18 +08:00
Louis Lam
104d521633 Update vite from 2.9.9 to 3.1.0 2022-09-12 18:33:46 +08:00
Louis Lam
839183aa85 Merge pull request #2071 from d3vyce/master
Add phishing security to link in status page
2022-09-12 14:39:20 +08:00
Louis Lam
e83ff0d679 Merge pull request #2070 from kdevkr/chore/typo
chore: fix typo
2022-09-12 14:10:33 +08:00
Louis Lam
80c1054877 Merge pull request #2072 from rezzorix/patch-5
Create stale-bot.yml
2022-09-11 15:41:28 +08:00
rezzorix
f503488618 Create stale-bot.yml 2022-09-11 14:54:33 +08:00
d3vyce
7577477ae8 Add rel="noopener noreferrer" to html link 2022-09-10 21:35:22 +02:00
Mambo
3ea57600ba chore: fix typo
Modifying Korean Spelling
2022-09-10 23:16:05 +09:00
Louis Lam
b22176d218 Merge pull request #1780 from tamasmagyar/test/add-cypress-tests
test: added cypress framework and tests for setup page
2022-09-09 21:05:12 +08:00
Louis Lam
7f9e291206 Ignore /cypress in .dockerignore 2022-09-09 16:36:32 +08:00
Louis Lam
197d44981f Merge remote-tracking branch 'origin/master' into test/add-cypress-tests
# Conflicts:
#	package.json
2022-09-09 16:32:23 +08:00
Louis Lam
97e9bc7705 Update README.md 2022-09-09 16:24:08 +08:00
Louis Lam
87b72191e5 Update README.md 2022-09-09 16:23:15 +08:00
Louis Lam
8827176390 Merge remote-tracking branch 'origin/master' 2022-09-09 16:00:14 +08:00
Louis Lam
42969d11ee Merge pull request #2044 from burakurer/patch-4
Update tr-TR.js
2022-09-09 15:50:51 +08:00
Louis Lam
7b8f9c7655 Fix checkout-pr by using fetch & checkout instead of pull 2022-09-09 15:49:39 +08:00
Louis Lam
e90a4f1f34 Merge pull request #2023 from louislam/pr-test
A special docker image for testing pull requests
2022-09-09 03:35:01 +08:00
Louis Lam
1e5376d80b Merge pull request #2011 from mhkarimi1383/goalert-notification
Adding GoAlert Notification
2022-09-09 03:34:37 +08:00
Louis Lam
dad2ec1164 Use pull 2022-09-09 01:57:42 +08:00
Louis Lam
676e64c77d Merge branch 'goalert-notification' of https://github.com/mhkarimi1383/uptime-kuma into pr-test 2022-09-09 01:57:00 +08:00
Louis Lam
0244507a07 Output 2022-09-08 22:40:45 +08:00
Louis Lam
6601e9bbba Output 2022-09-08 22:36:34 +08:00
Louis Lam
9589fcfdef Checkout pr without GitHub Cli 2022-09-08 22:12:27 +08:00
Louis Lam
ce3fe9f0a6 Merge pull request #2056 from mtelgkamp/german-translations
German translations, update de-DE.js
2022-09-08 21:42:02 +08:00
Michael Telgkamp
995276badc fix typo and formatting in en language string 2022-09-08 14:30:41 +02:00
Michael Telgkamp
9e62a6ec7d add some new translated strings 2022-09-08 14:29:45 +02:00
burakurer
75deab2cc5 Update tr-TR.js 2022-09-06 23:04:24 +03:00
Louis Lam
50f7b39672 Merge pull request #2040 from cyril59310/master
Update Fr language
2022-09-07 02:24:17 +08:00
cyril59310
6a802bf68c fix by eslint 2022-09-06 18:38:55 +02:00
Louis Lam
be8caa0d1e Merge pull request #2043 from ivanbratovic/croatian-language
Update Croatian (hr-HR) translation file
2022-09-06 23:09:22 +08:00
Ivan Bratović
d1aa9cfbcc Change small details in hr-HR translation 2022-09-06 14:51:27 +02:00
Ivan Bratović
808efb267f Update Croatian (hr-HR) translation file 2022-09-06 11:32:58 +02:00
cyril59310
252d6ea9c9 Remove unused translations 2022-09-05 20:58:00 +02:00
cyril59310
7d12cd0d42 Update Fr language 2022-09-05 20:21:46 +02:00
Louis Lam
cf10e26aff Update to 1.18.0 2022-09-05 17:43:42 +08:00
Louis Lam
53135641f3 Fix 2022-09-05 17:42:23 +08:00
Louis Lam
c0fe2d54f9 Merge pull request #2034 from Max-le/fr_translate
French translation contribution
2022-09-05 17:41:58 +08:00
Louis Lam
d8303f1f4d Merge pull request #2036 from Buchtic/patch-1
Update cs-CZ.js
2022-09-05 17:41:04 +08:00
Buchtič
ee14ab6751 Update cs-CZ.js 2022-09-04 09:43:07 +02:00
Louis Lam
fd2df562b1 Add checkout pr logic 2022-09-03 18:37:31 +08:00
max
87e45b21fa [empty commit] pull request for French translation contribution 2022-09-02 10:56:54 +02:00
Muhammed Hussein Karimi
626accedee change node version 2022-09-01 16:47:25 +04:30
Muhammed Hussein Karimi
b890812411 use npm 7 2022-09-01 16:36:24 +04:30
Louis Lam
cbc0b9c553 Merge pull request #2026 from filipporomani/patch-1
Italian language fixes
2022-08-31 17:59:12 +08:00
Filippo Romani
c2472bf750 Italian language fixes
A few grammar fixes made from an italian.
Some phrases were not really correct.
2022-08-30 19:11:54 +02:00
Louis Lam
e0cdc3e7c5 Update dockerfile for pr-test 2022-08-29 22:06:47 +08:00
Louis Lam
84fad93555 Merge pull request #1735 from woooferz/patch-1
Added label to status badge
2022-08-29 21:19:15 +08:00
Muhammed Hussein Karimi
b9b00050dd fix package lock version 2022-08-28 21:37:19 +04:30
Muhammed Hussein karimi
064fe50e38 Update src/components/notifications/index.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-08-26 17:06:13 +04:30
Muhammed Hussein karimi
a8ea76e8a1 Remove extra debug log
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-08-26 17:05:32 +04:30
Louis Lam
2975204a0a Merge pull request #2017 from kiznick/master
Update th-TH.js
2022-08-26 15:09:40 +08:00
Yoswaris Lawpaiboon
31150642cd forgot to save lol 2022-08-26 01:08:21 +07:00
Yoswaris Lawpaiboon
3c5c49c16d Update th-TH.js 2022-08-26 00:57:44 +07:00
Muhammed Hussein Karimi
584d52517a [Linter] fixing quotes with doublequote 2022-08-24 10:41:42 +04:30
Muhammed Hussein Karimi
82dd9a7c16 golaert req fix and axios update for formdata 2022-08-24 10:36:29 +04:30
Muhammed Hussein Karimi
d44663c57c provider name fix 2022-08-24 09:37:15 +04:30
Muhammed Hussein Karimi
e557545c97 goalert needs post instead of get 2022-08-24 08:46:20 +04:30
Muhammed Hussein Karimi
055948d1b9 [Linter] typo fixes 2022-08-23 23:58:46 +04:30
Muhammed Hussein Karimi
4ac80cfc02 goAlertInfo language fix 2022-08-23 23:54:26 +04:30
Muhammed Hussein Karimi
af89c4d8ae GoAlert Notification added done
needs test
2022-08-23 23:49:28 +04:30
Muhammed Hussein Karimi
40b9d9ed17 goalert provider missing semicolon fix for linter 2022-08-23 22:26:20 +04:30
Muhammed Hussein Karimi
65e6921a41 goalert notification provider added 2022-08-23 22:22:54 +04:30
Muhammed Hussein Karimi
04fc124928 [empty commit] pull request for GoAlert Notification 2022-08-23 21:14:09 +04:30
Louis Lam
5c25354682 Merge pull request #1998 from MrEddX/bulgarian
Bulgarian
2022-08-17 16:55:58 +08:00
Louis Lam
2aad2510b7 Merge pull request #1993 from AnnAngela/1.18.0-zhCN
1.18.0 zh-CN
2022-08-17 16:55:02 +08:00
MrEddX
fac2f1cbc6 Update bg-BG.js
Translated new fields for the upcoming 1.18.0 release.
2022-08-14 08:52:53 +03:00
MrEddX
8bc3651a7d Merge branch 'louislam:master' into bulgarian 2022-08-14 07:20:37 +03:00
AnnAngela
684d0a7eb8 feat: Update zh-CN languages file
Due to no Radius server and Home Assistant device or server in my hands, the translation may be incorrect.\nRef:\n- Radius secret → Radius 共享机密: https://docs.microsoft.com/zh-cn/azure/active-directory/authentication/howto-mfaserver-dir-radius#:~:text=%E5%8F%AF%E9%80%89%EF%BC%89%E5%92%8C-,%E5%85%B1%E4%BA%AB%E6%9C%BA%E5%AF%86,-%E3%80%82\n- Called Station Id → NAS 网络访问服务器号码: https://docs.microsoft.com/zh-cn/windows-server/networking/technologies/nps/nps-plan-proxy#:~:text=Called%2DStation%2DID%E3%80%82-,NAS%20%E7%BD%91%E7%BB%9C%E8%AE%BF%E9%97%AE%E6%9C%8D%E5%8A%A1%E5%99%A8%20(%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81),-%E3%80%82%20%E6%AD%A4%E5%B1%9E%E6%80%A7%E7%9A%84\n- Calling Station Id → 呼叫方号码: https://docs.microsoft.com/zh-cn/windows-server/networking/technologies/nps/nps-plan-proxy#:~:text=Calling%2DStation%2DID%E3%80%82-,%E5%91%BC%E5%8F%AB%E6%96%B9%E4%BD%BF%E7%94%A8%E7%9A%84%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81,-%E3%80%82%20%E6%AD%A4%E5%B1%9E%E6%80%A7%E7%9A%84
2022-08-13 16:23:51 +08:00
AnnAngela
b3712ee1cc fix: Update en language file to match up newest development 2022-08-13 16:19:51 +08:00
Louis Lam
af94424283 Update to 1.18.0-beta.0 2022-08-13 14:04:17 +08:00
Louis Lam
728e811969 Update Apprise to 1.0.0 2022-08-13 13:35:03 +08:00
Louis Lam
a6007adce3 Update to 1.18.0-beta.1 2022-08-13 13:32:16 +08:00
Louis Lam
30b72d81cf Merge pull request #1212 from OidaTiftla/introduce-resend-interval
Resend Notification if Down X times consequently
2022-08-13 13:27:49 +08:00
Louis Lam
de6e1e7ddd Merge remote-tracking branch 'origin/master' into introduce-resend-interval
# Conflicts:
#	server/database.js
2022-08-13 13:24:00 +08:00
Louis Lam
2af754b5e8 Update package-lock.json 2022-08-11 21:09:16 +08:00
Louis Lam
3b3763351b Merge remote-tracking branch 'origin/master' into radius-check
# Conflicts:
#	server/database.js
#	server/model/monitor.js
#	server/server.js
#	server/util-server.js
#	src/pages/EditMonitor.vue
2022-08-11 21:08:06 +08:00
Louis Lam
9a488d6968 Merge pull request #1752 from SuperManito/master
Add Bark Notification Parameters
2022-08-08 17:04:08 +08:00
Louis Lam
aca395cea1 Merge pull request #1957 from jbenguira/patch-2
Avoid error "SQLITE_BUSY: database is locked"
2022-08-08 17:00:06 +08:00
Louis Lam
a49faf09b9 Merge pull request #1836 from rmtsrc/add-home-assistant-notification
feat: added Home Assistant notification integration
2022-08-06 18:08:06 +08:00
Louis Lam
d0d1e0de28 Merge remote-tracking branch 'origin/master' into introduce-resend-interval
# Conflicts:
#	src/pages/EditMonitor.vue
2022-08-05 15:40:06 +08:00
Louis Lam
70aa8fe453 Merge pull request #1183 from c0derMo/master
Adding option to monitor other docker containers
2022-08-02 19:08:46 +08:00
MrEddX
19d8761305 Update bg-BG.js
Just a typo
2022-08-02 07:48:54 +03:00
Joseph Benguira
d6a113396a Update server/database.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-08-01 13:18:19 +03:00
Louis Lam
fb3fe17c28 Fix getClientIP
Co-authored-by: Mateusz Hajder <6783135+mhajder@users.noreply.github.com>
2022-08-01 15:42:58 +08:00
Joseph Benguira
71d62ee151 removed ; after the PRAGMA command 2022-07-31 19:00:19 +03:00
Joseph Benguira
82b9bfc5a0 fixed Trailing spaces not allowed lint issue 2022-07-31 18:59:02 +03:00
Joseph Benguira
f016caa513 Avoid error "SQLITE_BUSY: database is locked"
Avoid error "SQLITE_BUSY: database is locked" by allowing SQLITE to wait up to 5 seconds to do a write
2022-07-31 18:51:53 +03:00
Louis Lam
6e29feffd3 Merge pull request #1827 from theS1LV3R/master
feat: get client ip from x-forwarded-for header if available
2022-07-31 23:43:39 +08:00
Louis Lam
2389b604fe Use Settings.get 2022-07-31 23:41:29 +08:00
Louis Lam
a3b1612938 getClientIP respect trustProxy setting 2022-07-31 23:36:33 +08:00
Louis Lam
a07f54f35b Merge remote-tracking branch 'origin/master' into theS1LV3R_master 2022-07-31 23:27:35 +08:00
Louis Lam
b777c0c3e4 Merge pull request #1862 from harryzcy/issue-1861
Support X-Forwarded-Host header
2022-07-31 20:53:15 +08:00
Louis Lam
bea8679788 Merge branch 'master' into issue-1861 2022-07-31 20:06:45 +08:00
rmt/src
f091e92c70 Merge branch 'master' of github.com:rmtsrc/uptime-kuma into add-home-assistant-notification 2022-07-31 12:41:18 +01:00
Louis Lam
a0843745f9 Remove unused language key 2022-07-31 18:12:41 +08:00
Louis Lam
16d6885a88 Fix radio button and add description 2022-07-31 18:11:40 +08:00
Louis Lam
4d975a5bd5 Merge pull request #1955 from dtorner/patch-1
Updated ES translation
2022-07-31 17:24:15 +08:00
MrEddX
96ec46765b Update en.js
Just a typo.
2022-07-31 17:23:23 +08:00
MrEddX
96971f6776 Update bg-BG.js
- Translation Update
- Fixed Some Accidentally Deleted Fields
2022-07-31 17:23:23 +08:00
MrEddX
ffb1a948fe Update bg-BG.js
Translation Update
2022-07-31 17:23:23 +08:00
dtorner
4e4156285a Updated ES tramaslation
Just some changes here and there, mainly caps and some words.
TY to the developers for this good piece of code :-)
2022-07-31 11:13:36 +02:00
Louis Lam
1223b56205 Add example 2022-07-30 19:57:51 +08:00
Louis Lam
8ced61697a Fix save docker host issue 2022-07-30 19:48:12 +08:00
Louis Lam
f3322398e5 Fix and improve test docker host 2022-07-29 20:57:13 +08:00
Louis Lam
b76ca59dfe Merge pull request #1786 from treboryx/master
fix: hide mobile header when not logged in
2022-07-29 15:25:43 +08:00
Louis Lam
554b0d2bc3 Merge pull request #1931 from mariogarridopt/add-language-pt-pt
Add pt-PT language file
2022-07-29 15:19:51 +08:00
0x01code
4575f31094 Add support for line notify providers (#1781)
* add line notify support

* add way to get line notify

* Fix duplicate key 'HTTP Basic Auth'

* Revert language files changes

* Revert language files changes

* Fix general message

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-07-29 15:13:50 +08:00
Louis Lam
df7f0b078d Merge pull request #1934 from ankhgerel/locale/ko
chore(locale): change some typo ko-KR
2022-07-26 14:43:06 +08:00
Mario Garrido
d8253405b4 fix: add language to the language list 2022-07-26 02:07:38 +01:00
Mário Garrido
56c6c0c6f1 Merge branch 'louislam:master' into add-language-pt-pt 2022-07-26 02:04:50 +01:00
__filename
b16cb6a337 fix(locale): Edit non-space place
Co-authored-by: Kyungyoon Kim <ruddbs5302@gmail.com>
2022-07-25 20:11:51 +08:00
__filename
694b4cadb3 fix(locale): Edit typo
Co-authored-by: Kyungyoon Kim <ruddbs5302@gmail.com>
2022-07-25 16:41:29 +08:00
__filename
75f6ff8b58 fix(locale): Edit multiple space
Co-authored-by: Kyungyoon Kim <ruddbs5302@gmail.com>
2022-07-25 16:39:00 +08:00
c0derMo
1062e629c5 Fix linting issues 2022-07-24 12:50:43 +00:00
__filename
13f7db655b chore(locale): change some typo ko-KR 2022-07-24 20:44:43 +08:00
Moritz R
60e7824ff0 Merge branch 'master' into master 2022-07-24 14:37:22 +02:00
c0derMo
fb3b407577 Added a settings page & localization 2022-07-24 12:34:43 +00:00
Louis Lam
d54c652d26 Merge pull request #1778 from christopherpickering/master
Added postgres monitor
2022-07-24 14:22:36 +08:00
Louis Lam
f1bcecb0c6 Merge package-lock.json 2022-07-24 14:08:03 +08:00
Louis Lam
88afd662db Merge remote-tracking branch 'origin/master' into postgres
# Conflicts:
#	package-lock.json
#	package.json
2022-07-24 14:07:30 +08:00
c0derMo
e356d5f623 Fixing linting & adding documentation 2022-07-22 15:57:40 +00:00
c0derMo
0d098b0958 Docker Hosts are now a table & have their own dialog 2022-07-22 15:47:04 +00:00
Louis Lam
239611a016 Do not set sendUrl if sendUrl is undefined 2022-07-22 23:27:02 +08:00
Mario Garrido
2ccf1fe41b fix: small changes in semantics 2022-07-22 15:42:38 +01:00
Mario Garrido
77340cf0d2 feat: adicionar pt-PT 2022-07-22 15:16:23 +01:00
Mario Garrido
c412c66aeb Add pt-PT language file 2022-07-22 06:29:41 +01:00
Rolf Bachmann
c4a2ce4e78 Add authentication support for ntfy 2022-07-19 12:17:15 +02:00
tamasmagyar
a382f811f4 added comment to startE2eTests function 2022-07-18 20:51:17 +02:00
tamasmagyar
986c03aecd test cypress run 2022-07-18 20:51:17 +02:00
tamasmagyar
31c388a6e3 added cypress framework and tests for setup page 2022-07-18 20:51:13 +02:00
Louis Lam
9a8b484ee8 Merge pull request #1853 from louislam/dns
Add cacheable-lookup
2022-07-18 23:46:55 +08:00
Louis Lam
17ed051401 Add CacheableDnsHttpAgent.install() 2022-07-18 23:32:45 +08:00
Louis Lam
8f7b7e74c9 socks-proxy-agent 6.2.X is a breaking change, freeze to 6.1.1. 2022-07-18 23:28:19 +08:00
Louis Lam
9cd060c6c3 socks-proxy-agent 6.2.X is a breaking change, freeze to 6.1.1. 2022-07-18 23:27:05 +08:00
Louis Lam
1999541802 Merge remote-tracking branch 'origin/master' into dns 2022-07-18 23:25:14 +08:00
Louis Lam
65d71e5db0 Fix mssqlQuery keep adding error listener, which causes memory leak.
Also it is not necessary since the error catched in the promise .catch(..).
2022-07-18 23:14:16 +08:00
Louis Lam
2073f0c284 Bind cacheable-lookup to custom http agent 2022-07-18 22:33:35 +08:00
Louis Lam
25d711e683 Fix jsdoc data type 2022-07-18 22:06:25 +08:00
Louis Lam
77a7801992 Merge pull request #1917 from Deni7/patch-1
Update ukrainian language
2022-07-18 14:28:47 +08:00
Denis Stepanov
525607f49e Update ukrainian language 2022-07-18 09:00:44 +03:00
Louis Lam
8613d3ffa9 Merge pull request #1893 from SiderealArt/patch-1
update zh-TW
2022-07-16 00:23:42 +08:00
SiderealArt
d44d984a46 update zh-TW 2022-07-14 22:25:39 +08:00
Louis Lam
d362372b05 Merge pull request #1749 from daeho-ro/feature/alertnow
Feat: New Notification Type for AlertNow
2022-07-14 15:04:35 +08:00
Chongyi Zheng
3fa5dfc873 Use x-forwarded-host only when trustProxy is true 2022-07-12 22:59:23 -04:00
Chongyi Zheng
6ce012c9a1 Add trust proxy checkbox in Settings page 2022-07-12 22:45:54 -04:00
Chongyi Zheng
f33b6de157 Support X-Forwarded-Host header 2022-07-11 01:28:50 -04:00
Louis Lam
e0a2ed2523 Update Apprise from 0.9.8.3 to 0.9.9 2022-07-10 02:15:51 +08:00
Louis Lam
a78cb7ab42 Merge pull request #1880 from Jontes-Tech/patch-1
Fixing small Readme links.
2022-07-09 21:45:56 +08:00
Jonatan
278d9f5689 Fixing Markdown whoopsie I made 2022-07-09 12:25:41 +02:00
Jonatan
2ad79a68b9 Some small changes in the Reddit section. 2022-07-09 12:22:03 +02:00
Louis Lam
d29955f3ba Merge pull request #1741 from Computroniks/feature/#1221-clickable-hostaname-on-status-page
Added #1221 clickable hostname in status page
2022-07-06 15:09:26 +08:00
theS1LV3R
c4125a8334 style: fix linter error 2022-07-04 20:38:44 +02:00
Zoe
0a368ff553 feat: add x-real-ip as a secondary header for client ip
Now allows both x-forwarded-for as well as x-real-ip to be used for the client ip, preferring x-forwarded-for
2022-07-04 20:36:03 +02:00
Louis Lam
27dbc021b4 Add standalone manifest.json for each status page. Close #1668 2022-07-04 21:58:27 +08:00
Matthew Nickson
1b120f8a6f Made link icon only show for http and keyword
The option to enable links to the monitors is now only available for
http and keyword monitor types. The link will also no longer be shown
on the edit page to prevent issues with the url not being present if
the monitor was not already enabled for sendUrl

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-07-04 13:31:05 +01:00
Louis Lam
6f57c4195a Slightly improve css 2022-07-04 18:33:38 +08:00
Louis Lam
baa592bce3 Merge remote-tracking branch 'origin/master' into feature/#1221-clickable-hostaname-on-status-page 2022-07-04 18:21:56 +08:00
Thomas Christlieb
42e30de209 change page title to " - Login" when on Login Form 2022-07-04 10:16:33 +02:00
Louis Lam
624678826d Move all frontend dependencies to devDependencies, as it is not used in the production environment 2022-07-04 03:59:20 +08:00
Louis Lam
e8c3807594 Move all frontend dependencies to devDependencies, as it is not used in the production environment 2022-07-04 03:54:56 +08:00
Louis Lam
4d8e755400 Merge pull request #1859 from jjasghar/patch-2
Update docker-compose.yml
2022-07-01 23:51:34 +08:00
JJ Asghar
9b92a02968 Update docker-compose.yml
It's a docker-compose file, not "r" :), thanks for making this app, I love it. 🤘
2022-06-30 11:46:14 -05:00
Louis Lam
6418f99f1a Merge pull request #1852 from thehijacker/patch-1
Update sl-SI.js
2022-06-30 16:40:03 +08:00
Louis Lam
93ac4e1b96 Merge pull request #1856 from gBasil/master
Clean up logo svg file
2022-06-30 16:24:52 +08:00
Louis Lam
f65bef686c Merge pull request #1857 from MarcHagen/lang/nl
[i18n] Update NL (Dutch)
2022-06-30 16:19:26 +08:00
Marc Hagen
2f26864892 [i18n] Update NL (Dutch) 2022-06-29 23:26:41 +02:00
Basil
a802f7ebed Clean up logo svg file 2022-06-29 13:20:26 -06:00
Louis Lam
e5e8db6c38 Add cacheable-lookup 2022-06-29 22:17:47 +08:00
thehijacker
303738b7c2 Update sl-SI.js 2022-06-29 13:58:52 +02:00
Louis Lam
dddd2c0042 Cache settings, reduce the database / disk usage 2022-06-29 16:18:56 +08:00
Louis Lam
515095ecfb Move all settings code from util-server.js into settings.js 2022-06-29 14:57:40 +08:00
Louis Lam
83284b6d2c [stylelint] Turn off color-hex-length 2022-06-28 22:26:27 +08:00
Louis Lam
1af6d33fcd Make sure the backup database process is actually created backup files. Improve https://github.com/louislam/uptime-kuma/issues/1412#issuecomment-1166576395 2022-06-28 22:11:59 +08:00
Louis Lam
e36b65c2df Add frontend version 2022-06-28 21:55:05 +08:00
Louis Lam
8542e6cbb9 Drop npm-check-updates due to security vulnerability of got, and it is unlikely to be fixed shortly
Read more:
https://github.com/raineorshine/npm-check-updates/pull/1147#event-6880466174
2022-06-27 10:50:38 +08:00
rmt/src
5dd197374d fix: only add en translation 2022-06-26 10:56:46 +01:00
rmt/src
f84ae82983 feat: added Home Assistant notification integration 2022-06-25 21:27:30 +01:00
Louis Lam
9650418ef7 Fix dependencies warning 2022-06-25 20:55:14 +08:00
Louis Lam
b546c846ae Merge pull request #1828 from utolosa002/master
Add Basque language
2022-06-25 19:26:38 +08:00
Unai Tolosa
b5cbc6f5f6 fix: lint 2022-06-23 23:30:01 +02:00
Unai Tolosa Pontesta
f8def5aa6f Merge branch 'louislam:master' into master 2022-06-23 23:12:54 +02:00
theS1LV3R
6f01a448ad feat: get client ip from x-forwarded-for header if available
Useful for use-cases where Uptime Kuma is running behind a reverse proxy
2022-06-23 23:08:04 +02:00
Unai Tolosa
5dd3d32d77 add: basque translations 2022-06-23 16:20:24 +02:00
Unai Tolosa
ff8bba6863 add: basque translation file 2022-06-23 13:29:37 +02:00
Louis Lam
ed1f88a852 Change fs.rmdir to fs.rm as it is deprecated 2022-06-23 19:18:28 +08:00
Louis Lam
0ecaa2cbd7 Update to 1.17.1 2022-06-23 16:05:42 +08:00
Louis Lam
3c3dc05621 Merge pull request #1823 from louislam/revert-1598
Revert #1598
2022-06-23 16:02:44 +08:00
Louis Lam
1f5466a3e8 Revert #1598 2022-06-23 15:54:33 +08:00
Matthew Nickson
f1d24782f8 Merge branch 'master' into feature/#1221-clickable-hostaname-on-status-page 2022-06-18 23:53:35 +01:00
Robert
c4e2d67d17 fix: hide mobile header when not logged in 2022-06-17 10:11:53 +03:00
sur.la.route
47e82ed83a Removed blank line
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-15 20:14:36 -05:00
sur.la.route
e1f766756f Removed blank line
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-15 20:14:26 -05:00
sur.la.route
4b2a465c94 Fix order of type and placeholder
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-15 20:14:06 -05:00
Christopher Pickering
edcdedcaae Added check for blank password. 2022-06-15 13:00:14 -05:00
Christopher Pickering
945288f0c0 Added postgres monitor 2022-06-15 12:12:47 -05:00
OidaTiftla
ac27e6e2af Rename feature to: Resend Notification if Down X times consequently
Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-06-15 17:50:35 +02:00
OidaTiftla
869a040011 Merge branch 'master' into introduce-resend-interval 2022-06-15 16:19:47 +02:00
Moritz R
ac449ec1c2 Merge branch 'master' into master 2022-06-15 11:33:00 +02:00
Super Manito
54b9698a05 Update 2022-06-13 21:44:10 +08:00
Super Manito
1c4ddaeddf Update 2022-06-13 18:17:47 +08:00
Super Manito
55a6e5af42 Update server/notification-providers/bark.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-06-13 17:06:12 +08:00
Super Manito
252709ff49 Update server/notification-providers/bark.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-06-13 17:06:05 +08:00
Super Manito
774fe58ddc Update 2022-06-13 01:30:27 +08:00
Super Manito
5f347b10ba Update 2022-06-13 01:15:38 +08:00
Super Manito
f442507cab Update 2022-06-13 00:16:34 +08:00
Super Manito
a23ab9d1de Update 2022-06-12 23:18:32 +08:00
Super Manito
404923b7c8 bugfix 2022-06-12 22:49:04 +08:00
Super Manito
a41023ca2a Update 2022-06-12 22:41:24 +08:00
Super Manito
817c941489 Add Bark Notification Parameters 2022-06-12 22:30:42 +08:00
Daeho Ro
5f6347d277 pull request for adding alertnow notification 2022-06-12 04:02:44 +09:00
Matthew Nickson
fbfa5a33ed Added Clickable hostname on status page. #1221
This should fully implement #1221 by modifying the API and adding two
new properties to the result. The `sendUrl` property denotes if the URL
is sent and `url` is included when required.
Client side checks have been implemented in order to only show a link
when the URL is vaugely correct. I.e not "" or "https://". This prevents
the link from being included if the monitor type is not HTTP without
having to publicly expose the monitor type.
The exposure of the URL is configuarable for each monitor on each
status page by clicking on the link icon.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-11 17:23:12 +01:00
Wooferz
aa398948da Merge branch 'louislam:master' into patch-1 2022-06-11 09:41:03 +10:00
Wooferz
54548e34ed Added label to status badge 2022-06-08 20:05:10 +10:00
Moritz R
e9e78c26e5 Merge branch 'master' into master 2022-05-27 13:59:58 +02:00
c0derMo
32cfd411f8 Fixed style & code errors 2022-05-19 12:35:55 +00:00
Moritz R
a9f3142cee Merge branch 'master' into master 2022-05-19 14:24:02 +02:00
Sascha Kruse
da99a57560 Merge remote-tracking branch 'fxgh/radius-check' into radius-check 2022-05-18 15:56:21 +02:00
Sascha Kruse
42d68edab0 (style) add trailing comma
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-05-18 15:55:36 +02:00
Sascha Kruse
019d638767 Merge remote-tracking branch 'ghupstream/master' into radius-check 2022-05-18 15:54:10 +02:00
Sascha Kruse
398ecb7666 add radius check 2022-05-12 15:21:13 +02:00
OidaTiftla
93050208bb Merge database changes into single patch file 2022-05-05 16:01:19 +02:00
OidaTiftla
98ee9caf2c Add variable for currentTime
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-05-05 15:55:33 +02:00
OidaTiftla
8e99cbf426 Merge branch 'master' into introduce-resend-interval 2022-05-04 22:58:40 +02:00
OidaTiftla
7ed8ae9f7c Fix trailing space warning 2022-04-21 18:23:32 +02:00
OidaTiftla
c7ec9a07e2 Add translation for text label 2022-04-21 17:59:38 +02:00
OidaTiftla
052fde5a24 Fix casing of text label
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 17:56:38 +02:00
OidaTiftla
d6b591a513 Make comment more readable
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 17:45:58 +02:00
OidaTiftla
19933bbd99 Improve backwards compatibility 2022-04-21 12:18:15 +02:00
OidaTiftla
60f8ab7285 Use new logging mechanism 2022-04-21 12:09:59 +02:00
OidaTiftla
b7e2489d22 Merge branch 'master' into introduce-resend-interval 2022-04-21 11:58:04 +02:00
Moritz R
361e44ad6a Merge branch 'louislam:master' into master 2022-04-13 15:58:17 +02:00
Moritz R
af44b0beab Merge branch 'master' into master 2022-04-03 17:19:29 +02:00
Moritz R
84a0b24448 Update server/model/monitor.js
As per recommendation of @Computroniks

Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-03 17:15:21 +02:00
OidaTiftla
d8013f31e8 Update version after merging new master branch 2022-03-27 21:24:41 +02:00
OidaTiftla
91366ff565 Merge branch 'master' into introduce-resend-interval 2022-03-27 21:19:57 +02:00
OidaTiftla
d446a57d42 Add german translation 2022-01-24 22:20:48 +01:00
OidaTiftla
855b12f435 Add text for resend disabled 2022-01-24 22:20:38 +01:00
OidaTiftla
f390a8caf1 Fix missing DB patch and use DATETIME as column format 2022-01-24 21:59:25 +01:00
OidaTiftla
30ce53f57c Fix min value of resend interval 2022-01-24 09:18:38 +01:00
OidaTiftla
8c4ab9d652 Simplify 2022-01-24 09:18:22 +01:00
OidaTiftla
f931e709e6 Add database patch 2022-01-24 09:18:12 +01:00
OidaTiftla
11e9eee09d Change seconds to minutes 2022-01-23 17:48:09 +01:00
OidaTiftla
65fc71e485 Revert version change 2022-01-23 17:36:48 +01:00
OidaTiftla
b69a8b8493 Fix formatting
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-23 17:35:53 +01:00
OidaTiftla
1ac904d6d6 Introduce resend interval if down 2022-01-23 15:22:57 +01:00
c0derMo
29df70949d Add ability to connect to daemon via http / tcp for windows compatibility 2022-01-22 01:57:37 +00:00
c0derMo
4818bb67d6 Added trailing comma, fixed spelling & translation 2022-01-14 09:09:37 +00:00
c0derMo
9619d31a05 Adding docker container ability to readme 2022-01-13 18:33:01 +00:00
c0derMo
c5cc42272f Fixing the editing of docker container & adding english translation 2022-01-13 18:28:45 +00:00
c0derMo
b0259b5592 Added docker container monitor 2022-01-13 16:17:07 +00:00
108 changed files with 10765 additions and 8919 deletions

View File

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

View File

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

View File

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

24
.github/workflows/stale-bot.yml vendored Normal file
View File

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

3
.gitignore vendored
View File

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

View File

@@ -8,6 +8,7 @@
"declaration-empty-line-before": null,
"alpha-value-notation": "number",
"color-function-notation": "legacy",
"shorthand-property-no-redundant-values": null
"shorthand-property-no-redundant-values": null,
"color-hex-length": null,
}
}

View File

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

View File

@@ -23,7 +23,7 @@ VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollec
## ⭐ Features
* Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server.
* Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server / Docker Containers.
* Fancy, Reactive, Fast UI/UX.
* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications).
* 20 second intervals.
@@ -106,7 +106,7 @@ https://github.com/louislam/uptime-kuma/milestones
Project Plan:
https://github.com/louislam/uptime-kuma/projects/1
https://github.com/users/louislam/projects/4/views/1
## ❤️ Sponsors
@@ -151,13 +151,20 @@ You can discuss or ask for help in [issues](https://github.com/louislam/uptime-k
### Subreddit
My Reddit account: louislamlam
My Reddit account: [u/louislamlam](https://reddit.com/u/louislamlam).
You can mention me if you ask a question on Reddit.
https://www.reddit.com/r/UptimeKuma/
[r/Uptime kuma](https://www.reddit.com/r/UptimeKuma/)
## Contribute
### Beta Version
### Test Pull Requests
There are a lot of pull requests right now, but I don't have time to test them all.
If you want to help, you can check this:
https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests
### Test Beta Version
Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases
@@ -169,5 +176,5 @@ If you want to translate Uptime Kuma into your language, please read: https://gi
Feel free to correct my grammar in this README, source code, or wiki, as my mother language is not English and my grammar is not that great.
### Pull Requests
If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md
### Create Pull Requests
If you want to modify Uptime Kuma, please read this guide and follow the rules here: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md

View File

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

15
cypress.config.ts Normal file
View File

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

24
cypress/e2e/setup.cy.ts Normal file
View File

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

0
cypress/plugins/index.js Normal file
View File

View File

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

View File

View File

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

1
cypress/support/e2e.ts Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,5 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor_group
ADD send_url BOOLEAN DEFAULT 0 NOT NULL;
COMMIT;

View File

@@ -0,0 +1,18 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
CREATE TABLE docker_host (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
user_id INT NOT NULL,
docker_daemon VARCHAR(255),
docker_type VARCHAR(255),
name VARCHAR(255)
);
ALTER TABLE monitor
ADD docker_host INTEGER REFERENCES docker_host(id);
ALTER TABLE monitor
ADD docker_container VARCHAR(255);
COMMIT;

View File

@@ -0,0 +1,18 @@
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD radius_username VARCHAR(255);
ALTER TABLE monitor
ADD radius_password VARCHAR(255);
ALTER TABLE monitor
ADD radius_calling_station_id VARCHAR(50);
ALTER TABLE monitor
ADD radius_called_station_id VARCHAR(50);
ALTER TABLE monitor
ADD radius_secret VARCHAR(255);
COMMIT

View File

@@ -0,0 +1,10 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD resend_interval INTEGER default 0 not null;
ALTER TABLE heartbeat
ADD down_count INTEGER default 0 not null;
COMMIT;

View File

@@ -4,5 +4,5 @@ WORKDIR /app
# Install apprise, iputils for non-root ping, setpriv
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \
pip3 --no-cache-dir install apprise==0.9.8.3 && \
pip3 --no-cache-dir install apprise==1.0.0 && \
rm -rf /root/.cache

View File

@@ -11,7 +11,7 @@ WORKDIR /app
RUN apt update && \
apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \
sqlite3 iputils-ping util-linux dumb-init && \
pip3 --no-cache-dir install apprise==0.9.8.3 && \
pip3 --no-cache-dir install apprise==1.0.0 && \
rm -rf /var/lib/apt/lists/* && \
apt --yes autoremove

View File

@@ -1,4 +1,4 @@
# Simple docker-composer.yml
# Simple docker-compose.yml
# You can change your port or volume location
version: '3.3'

View File

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

33
extra/checkout-pr.js Normal file
View File

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

View File

@@ -41,7 +41,7 @@ function updateWiki(newVersion) {
function safeDelete(dir) {
if (fs.existsSync(dir)) {
fs.rmdirSync(dir, {
fs.rm(dir, {
recursive: true,
});
}

14417
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "uptime-kuma",
"version": "1.17.0",
"version": "1.18.2",
"license": "MIT",
"repository": {
"type": "git",
@@ -38,8 +38,9 @@
"build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push",
"build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push",
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"setup": "git checkout 1.17.0 && npm ci --production && npm run download-dist",
"setup": "git checkout 1.18.2 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js",
"mark-as-nightly": "node extra/mark-as-nightly.js",
"reset-password": "node extra/reset-password.js",
@@ -58,26 +59,21 @@
"release-final": "node extra/update-version.js && npm run build-docker && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js",
"release-beta": "node extra/beta/update-version.js && npm run build && node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:beta . --target release --push && node ./extra/press-any-key.js && npm run upload-artifacts",
"git-remove-tag": "git tag -d",
"build-dist-and-restart": "npm run build && npm run start-server-dev"
"build-dist-and-restart": "npm run build && npm run start-server-dev",
"start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev",
"cy:test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --e2e",
"cy:run": "npx cypress run --browser chrome --headless"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "~1.2.36",
"@fortawesome/free-regular-svg-icons": "~5.15.4",
"@fortawesome/free-solid-svg-icons": "~5.15.4",
"@fortawesome/vue-fontawesome": "~3.0.0-5",
"@louislam/sqlite3": "~15.0.6",
"@popperjs/core": "~2.10.2",
"args-parser": "~1.3.0",
"axios": "~0.26.1",
"axios-cached-dns-resolve": "^3.0.6",
"axios": "~0.27.0",
"axios-ntlm": "^1.3.0",
"badge-maker": "^3.3.1",
"bcryptjs": "~2.4.3",
"bootstrap": "5.1.3",
"bree": "~7.1.5",
"cacheable-lookup": "~6.0.4",
"chardet": "^1.3.0",
"chart.js": "~3.6.2",
"chartjs-adapter-dayjs": "~1.0.0",
"check-password-strength": "^2.0.5",
"cheerio": "^1.0.0-rc.10",
"chroma-js": "^2.1.2",
@@ -85,11 +81,9 @@
"compare-versions": "~3.6.0",
"compression": "^1.7.4",
"dayjs": "^1.11.0",
"esm-wallaby": "^3.2.26",
"express": "~4.17.3",
"express-basic-auth": "~1.2.1",
"express-static-gzip": "^2.1.7",
"favico.js": "^0.3.10",
"form-data": "~4.0.0",
"http-graceful-shutdown": "~3.1.7",
"http-proxy-agent": "^5.0.0",
@@ -101,24 +95,67 @@
"mqtt": "^4.2.8",
"mssql": "^8.1.0",
"node-cloudflared-tunnel": "~1.0.9",
"node-radius-client": "^1.0.0",
"nodemailer": "~6.6.5",
"notp": "~2.0.3",
"password-hash": "~1.2.2",
"postcss-rtlcss": "~3.4.1",
"postcss-scss": "~4.0.3",
"prismjs": "^1.27.0",
"pg": "^8.7.3",
"pg-connection-string": "^2.5.0",
"prom-client": "~13.2.0",
"prometheus-api-metrics": "~3.2.1",
"qrcode": "~1.5.0",
"redbean-node": "0.1.4",
"socket.io": "~4.4.1",
"socket.io-client": "~4.4.1",
"socks-proxy-agent": "^6.1.1",
"socks-proxy-agent": "6.1.1",
"tar": "^6.1.11",
"tcp-ping": "~0.1.1",
"thirty-two": "~1.0.2",
"thirty-two": "~1.0.2"
},
"devDependencies": {
"@actions/github": "~5.0.1",
"@babel/eslint-parser": "~7.17.0",
"@babel/preset-env": "^7.15.8",
"@fortawesome/fontawesome-svg-core": "~1.2.36",
"@fortawesome/free-regular-svg-icons": "~5.15.4",
"@fortawesome/free-solid-svg-icons": "~5.15.4",
"@fortawesome/vue-fontawesome": "~3.0.0-5",
"@popperjs/core": "~2.10.2",
"@types/bootstrap": "~5.1.9",
"@vitejs/plugin-legacy": "~2.1.0",
"@vitejs/plugin-vue": "~3.1.0",
"@vue/compiler-sfc": "~3.2.36",
"aedes": "^0.46.3",
"babel-plugin-rewire": "~1.2.0",
"bootstrap": "5.1.3",
"chart.js": "~3.6.2",
"chartjs-adapter-dayjs": "~1.0.0",
"concurrently": "^7.1.0",
"core-js": "~3.18.3",
"cross-env": "~7.0.3",
"cypress": "^10.1.0",
"delay": "^5.0.0",
"dns2": "~2.0.1",
"eslint": "~8.14.0",
"eslint-plugin-vue": "~8.7.1",
"favico.js": "^0.3.10",
"jest": "~27.2.5",
"jest-puppeteer": "~6.0.3",
"postcss-html": "~1.5.0",
"postcss-rtlcss": "~3.7.2",
"postcss-scss": "~4.0.4",
"prismjs": "^1.27.0",
"puppeteer": "~13.1.3",
"qrcode": "~1.5.0",
"rollup-plugin-visualizer": "^5.6.0",
"sass": "~1.42.1",
"stylelint": "~14.7.1",
"stylelint-config-standard": "~25.0.0",
"terser": "^5.15.0",
"timezones-list": "~3.0.1",
"typescript": "~4.4.4",
"v-pagination-3": "~0.1.7",
"vite": "~3.1.0",
"vite-plugin-compression": "^0.5.1",
"vue": "next",
"vue-chart-3": "3.0.9",
"vue-confirm-dialog": "~1.0.2",
@@ -130,38 +167,7 @@
"vue-qrcode": "~1.0.0",
"vue-router": "~4.0.14",
"vue-toastification": "~2.0.0-rc.5",
"vuedraggable": "~4.1.0"
},
"devDependencies": {
"@actions/github": "~5.0.1",
"@babel/eslint-parser": "~7.17.0",
"@babel/preset-env": "^7.15.8",
"@types/bootstrap": "~5.1.9",
"@vitejs/plugin-legacy": "~1.8.2",
"@vitejs/plugin-vue": "~2.3.3",
"@vue/compiler-sfc": "~3.2.36",
"aedes": "^0.46.3",
"babel-plugin-rewire": "~1.2.0",
"concurrently": "^7.1.0",
"core-js": "~3.18.3",
"cross-env": "~7.0.3",
"delay": "^5.0.0",
"dns2": "~2.0.1",
"eslint": "~8.14.0",
"eslint-plugin-vue": "~8.7.1",
"jest": "~27.2.5",
"jest-puppeteer": "~6.0.3",
"lru-cache": "^7.7.1",
"npm-check-updates": "^12.5.9",
"postcss-html": "^1.3.1",
"puppeteer": "~13.1.3",
"rollup-plugin-visualizer": "^5.6.0",
"sass": "~1.42.1",
"stylelint": "~14.7.1",
"stylelint-config-standard": "~25.0.0",
"typescript": "~4.4.4",
"vite": "~2.9.9",
"vite-plugin-compression": "^0.5.1",
"vuedraggable": "~4.1.0",
"wait-on": "^6.0.1"
}
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 893 B

View File

@@ -0,0 +1,54 @@
const https = require("https");
const http = require("http");
const CacheableLookup = require("cacheable-lookup");
class CacheableDnsHttpAgent {
static cacheable = new CacheableLookup();
static httpAgentList = {};
static httpsAgentList = {};
/**
* Register cacheable to global agents
*/
static registerGlobalAgent() {
this.cacheable.install(http.globalAgent);
this.cacheable.install(https.globalAgent);
}
static install(agent) {
this.cacheable.install(agent);
}
/**
* @var {https.AgentOptions} agentOptions
* @return {https.Agent}
*/
static getHttpsAgent(agentOptions) {
let key = JSON.stringify(agentOptions);
if (!(key in this.httpsAgentList)) {
this.httpsAgentList[key] = new https.Agent(agentOptions);
this.cacheable.install(this.httpsAgentList[key]);
}
return this.httpsAgentList[key];
}
/**
* @var {http.AgentOptions} agentOptions
* @return {https.Agents}
*/
static getHttpAgent(agentOptions) {
let key = JSON.stringify(agentOptions);
if (!(key in this.httpAgentList)) {
this.httpAgentList[key] = new http.Agent(agentOptions);
this.cacheable.install(this.httpAgentList[key]);
}
return this.httpAgentList[key];
}
}
module.exports = {
CacheableDnsHttpAgent,
};

View File

@@ -125,10 +125,35 @@ async function sendInfo(socket) {
});
}
/**
* Send list of docker hosts to client
* @param {Socket} socket Socket.io socket instance
* @returns {Promise<Bean[]>}
*/
async function sendDockerHostList(socket) {
const timeLogger = new TimeLogger();
let result = [];
let list = await R.find("docker_host", " user_id = ? ", [
socket.userID,
]);
for (let bean of list) {
result.push(bean.toJSON());
}
io.to(socket.userID).emit("dockerHostList", result);
timeLogger.print("Send Docker Host List");
return list;
}
module.exports = {
sendNotificationList,
sendImportantHeartbeatList,
sendHeartbeatList,
sendProxyList,
sendInfo,
sendDockerHostList
};

View File

@@ -53,13 +53,17 @@ class Database {
"patch-2fa-invalidate-used-token.sql": true,
"patch-notification_sent_history.sql": true,
"patch-monitor-basic-auth.sql": true,
"patch-add-docker-columns.sql": true,
"patch-status-page.sql": true,
"patch-proxy.sql": true,
"patch-monitor-expiry-notification.sql": true,
"patch-status-page-footer-css.sql": true,
"patch-added-mqtt-monitor.sql": true,
"patch-add-clickable-status-page-link.sql": true,
"patch-add-sqlserver-monitor.sql": true,
"patch-add-other-auth.sql": { parents: [ "patch-monitor-basic-auth.sql" ] },
"patch-add-radius-monitor.sql": true,
"patch-monitor-add-resend-interval.sql": true,
};
/**
@@ -146,6 +150,9 @@ class Database {
await R.exec("PRAGMA cache_size = -12000");
await R.exec("PRAGMA auto_vacuum = FULL");
// Avoid error "SQLITE_BUSY: database is locked" by allowing SQLITE to wait up to 5 seconds to do a write
await R.exec("PRAGMA busy_timeout = 5000");
// This ensures that an operating system crash or power failure will not corrupt the database.
// FULL synchronous is very safe, but it is also slower.
// Read more: https://sqlite.org/pragma.html#pragma_synchronous
@@ -177,7 +184,13 @@ class Database {
} else {
log.info("db", "Database patch is needed");
this.backup(version);
try {
this.backup(version);
} catch (e) {
log.error("db", e);
log.error("db", "Unable to create a backup before patching the database. Please make sure you have enough space and permission.");
process.exit(1);
}
// Try catch anything here, if gone wrong, restore the backup
try {
@@ -445,6 +458,23 @@ class Database {
this.backupWalPath = walPath + ".bak" + version;
fs.copyFileSync(walPath, this.backupWalPath);
}
// Double confirm if all files actually backup
if (!fs.existsSync(this.backupPath)) {
throw new Error("Backup failed! " + this.backupPath);
}
if (fs.existsSync(shmPath)) {
if (!fs.existsSync(this.backupShmPath)) {
throw new Error("Backup failed! " + this.backupShmPath);
}
}
if (fs.existsSync(walPath)) {
if (!fs.existsSync(this.backupWalPath)) {
throw new Error("Backup failed! " + this.backupWalPath);
}
}
}
}

118
server/docker.js Normal file
View File

@@ -0,0 +1,118 @@
const axios = require("axios");
const { R } = require("redbean-node");
const version = require("../package.json").version;
const https = require("https");
class DockerHost {
/**
* Save a docker host
* @param {Object} dockerHost Docker host to save
* @param {?number} dockerHostID ID of the docker host to update
* @param {number} userID ID of the user who adds the docker host
* @returns {Promise<Bean>}
*/
static async save(dockerHost, dockerHostID, userID) {
let bean;
if (dockerHostID) {
bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]);
if (!bean) {
throw new Error("docker host not found");
}
} else {
bean = R.dispense("docker_host");
}
bean.user_id = userID;
bean.docker_daemon = dockerHost.dockerDaemon;
bean.docker_type = dockerHost.dockerType;
bean.name = dockerHost.name;
await R.store(bean);
return bean;
}
/**
* Delete a Docker host
* @param {number} dockerHostID ID of the Docker host to delete
* @param {number} userID ID of the user who created the Docker host
* @returns {Promise<void>}
*/
static async delete(dockerHostID, userID) {
let bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]);
if (!bean) {
throw new Error("docker host not found");
}
// Delete removed proxy from monitors if exists
await R.exec("UPDATE monitor SET docker_host = null WHERE docker_host = ?", [ dockerHostID ]);
await R.trash(bean);
}
/**
* Fetches the amount of containers on the Docker host
* @param {Object} dockerHost Docker host to check for
* @returns {number} Total amount of containers on the host
*/
static async testDockerHost(dockerHost) {
const options = {
url: "/containers/json?all=true",
headers: {
"Accept": "*/*",
"User-Agent": "Uptime-Kuma/" + version
},
httpsAgent: new https.Agent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: false,
}),
};
if (dockerHost.dockerType === "socket") {
options.socketPath = dockerHost.dockerDaemon;
} else if (dockerHost.dockerType === "tcp") {
options.baseURL = DockerHost.patchDockerURL(dockerHost.dockerDaemon);
}
let res = await axios.request(options);
if (Array.isArray(res.data)) {
if (res.data.length > 1) {
if ("ImageID" in res.data[0]) {
return res.data.length;
} else {
throw new Error("Invalid Docker response, is it Docker really a daemon?");
}
} else {
return res.data.length;
}
} else {
throw new Error("Invalid Docker response, is it Docker really a daemon?");
}
}
/**
* Since axios 0.27.X, it does not accept `tcp://` protocol.
* Change it to `http://` on the fly in order to fix it. (https://github.com/louislam/uptime-kuma/issues/2165)
*/
static patchDockerURL(url) {
if (typeof url === "string") {
// Replace the first occurrence only with g
return url.replace(/tcp:\/\//g, "http://");
}
return url;
}
}
module.exports = {
DockerHost,
};

View File

@@ -0,0 +1,19 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
class DockerHost extends BeanModel {
/**
* Returns an object that ready to parse to JSON
* @returns {Object}
*/
toJSON() {
return {
id: this.id,
userID: this.user_id,
dockerDaemon: this.docker_daemon,
dockerType: this.docker_type,
name: this.name,
};
}
}
module.exports = DockerHost;

View File

@@ -31,7 +31,7 @@ class Group extends BeanModel {
*/
async getMonitorList() {
return R.convertToBeans("monitor", await R.getAll(`
SELECT monitor.* FROM monitor, monitor_group
SELECT monitor.*, monitor_group.send_url FROM monitor, monitor_group
WHERE monitor.id = monitor_group.monitor_id
AND group_id = ?
ORDER BY monitor_group.weight

View File

@@ -7,7 +7,7 @@ dayjs.extend(timezone);
const axios = require("axios");
const { Prometheus } = require("../prometheus");
const { log, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util");
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, mqttAsync, setSetting, httpNtlm } = require("../util-server");
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mqttAsync, setSetting, httpNtlm, radius } = require("../util-server");
const { R } = require("redbean-node");
const { BeanModel } = require("redbean-node/dist/bean-model");
const { Notification } = require("../notification");
@@ -16,12 +16,8 @@ const { demoMode } = require("../config");
const version = require("../../package.json").version;
const apicache = require("../modules/apicache");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const axiosCachedDnsResolve = require("esm-wallaby")(module)("axios-cached-dns-resolve");
// create an axios client instance with the cached DNS resolve interceptor
const axiosClient = axios.create();
axiosCachedDnsResolve.registerInterceptor(axiosClient);
const { CacheableDnsHttpAgent } = require("../cacheable-dns-http-agent");
const { DockerHost } = require("../docker");
/**
* status:
@@ -40,7 +36,13 @@ class Monitor extends BeanModel {
let obj = {
id: this.id,
name: this.name,
sendUrl: this.sendUrl,
};
if (this.sendUrl) {
obj.url = this.url;
}
if (showTags) {
obj.tags = await this.getTags();
}
@@ -78,6 +80,7 @@ class Monitor extends BeanModel {
type: this.type,
interval: this.interval,
retryInterval: this.retryInterval,
resendInterval: this.resendInterval,
keyword: this.keyword,
expiryNotification: this.isEnabledExpiryNotification(),
ignoreTls: this.getIgnoreTls(),
@@ -87,6 +90,9 @@ class Monitor extends BeanModel {
dns_resolve_type: this.dns_resolve_type,
dns_resolve_server: this.dns_resolve_server,
dns_last_result: this.dns_last_result,
pushToken: this.pushToken,
docker_container: this.docker_container,
docker_host: this.docker_host,
proxyId: this.proxy_id,
notificationIDList,
tags: tags,
@@ -99,6 +105,11 @@ class Monitor extends BeanModel {
authMethod: this.authMethod,
authWorkstation: this.authWorkstation,
authDomain: this.authDomain,
radiusUsername: this.radiusUsername,
radiusPassword: this.radiusPassword,
radiusCalledStationId: this.radiusCalledStationId,
radiusCallingStationId: this.radiusCallingStationId,
radiusSecret: this.radiusSecret,
};
if (includeSensitiveData) {
@@ -205,6 +216,7 @@ class Monitor extends BeanModel {
bean.monitor_id = this.id;
bean.time = R.isoDateTimeMillis(dayjs.utc());
bean.status = DOWN;
bean.downCount = previousBeat?.downCount || 0;
if (this.isUpsideDown()) {
bean.status = flipStatus(bean.status);
@@ -287,7 +299,7 @@ class Monitor extends BeanModel {
});
} else {
res = await axiosClient.request(options);
res = await axios.request(options);
}
bean.msg = `${res.status} - ${res.statusText}`;
@@ -434,16 +446,19 @@ class Monitor extends BeanModel {
throw new Error("Steam API Key not found");
}
let res = await axiosClient.get(steamApiUrl, {
let res = await axios.get(steamApiUrl, {
timeout: this.interval * 1000 * 0.8,
headers: {
"Accept": "*/*",
"User-Agent": "Uptime-Kuma/" + version,
},
httpsAgent: new https.Agent({
httpsAgent: CacheableDnsHttpAgent.getHttpsAgent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: !this.getIgnoreTls(),
}),
httpAgent: CacheableDnsHttpAgent.getHttpAgent({
maxCachedSessions: 0,
}),
maxRedirects: this.maxredirects,
validateStatus: (status) => {
return checkStatusCode(status, this.getAcceptedStatuscodes());
@@ -464,6 +479,35 @@ class Monitor extends BeanModel {
} else {
throw new Error("Server not found on Steam");
}
} else if (this.type === "docker") {
log.debug(`[${this.name}] Prepare Options for Axios`);
const dockerHost = await R.load("docker_host", this.docker_host);
const options = {
url: `/containers/${this.docker_container}/json`,
headers: {
"Accept": "*/*",
"User-Agent": "Uptime-Kuma/" + version,
},
httpsAgent: new https.Agent({
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: ! this.getIgnoreTls(),
}),
};
if (dockerHost._dockerType === "socket") {
options.socketPath = dockerHost._dockerDaemon;
} else if (dockerHost._dockerType === "tcp") {
options.baseURL = DockerHost.patchDockerURL(dockerHost._dockerDaemon);
}
log.debug(`[${this.name}] Axios Request`);
let res = await axios.request(options);
if (res.data.State.Running) {
bean.status = UP;
bean.msg = "";
}
} else if (this.type === "mqtt") {
bean.msg = await mqttAsync(this.hostname, this.mqttTopic, this.mqttSuccessMessage, {
port: this.port,
@@ -480,6 +524,38 @@ class Monitor extends BeanModel {
bean.msg = "";
bean.status = UP;
bean.ping = dayjs().valueOf() - startTime;
} else if (this.type === "postgres") {
let startTime = dayjs().valueOf();
await postgresQuery(this.databaseConnectionString, this.databaseQuery);
bean.msg = "";
bean.status = UP;
bean.ping = dayjs().valueOf() - startTime;
} else if (this.type === "radius") {
let startTime = dayjs().valueOf();
try {
const resp = await radius(
this.hostname,
this.radiusUsername,
this.radiusPassword,
this.radiusCalledStationId,
this.radiusCallingStationId,
this.radiusSecret
);
if (resp.code) {
bean.msg = resp.code;
}
bean.status = UP;
} catch (error) {
bean.status = DOWN;
if (error.response?.code) {
bean.msg = error.response.code;
} else {
bean.msg = error.message;
}
}
bean.ping = dayjs().valueOf() - startTime;
} else {
bean.msg = "Unknown Monitor Type";
bean.status = PENDING;
@@ -521,12 +597,27 @@ class Monitor extends BeanModel {
log.debug("monitor", `[${this.name}] sendNotification`);
await Monitor.sendNotification(isFirstBeat, this, bean);
// Reset down count
bean.downCount = 0;
// Clear Status Page Cache
log.debug("monitor", `[${this.name}] apicache clear`);
apicache.clear();
} else {
bean.important = false;
if (bean.status === DOWN && this.resendInterval > 0) {
++bean.downCount;
if (bean.downCount >= this.resendInterval) {
// Send notification again, because we are still DOWN
log.debug("monitor", `[${this.name}] sendNotification again: Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`);
await Monitor.sendNotification(isFirstBeat, this, bean);
// Reset down count
bean.downCount = 0;
}
}
}
if (bean.status === UP) {
@@ -537,7 +628,7 @@ class Monitor extends BeanModel {
}
log.warn("monitor", `Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`);
} else {
log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`);
log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type} | Down Count: ${bean.downCount} | Resend Interval: ${this.resendInterval}`);
}
log.debug("monitor", `[${this.name}] Send to socket`);

View File

@@ -45,6 +45,8 @@ class StatusPage extends BeanModel {
$("link[rel=icon]")
.attr("href", statusPage.icon)
.removeAttr("type");
$("link[rel=apple-touch-icon]").remove();
}
const head = $("head");
@@ -61,6 +63,9 @@ class StatusPage extends BeanModel {
</script>
`);
// manifest.json
$("link[rel=manifest]").attr("href", `/api/status-page/${statusPage.slug}/manifest.json`);
return $.root().html();
}

View File

@@ -0,0 +1,50 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { setting } = require("../util-server");
const { getMonitorRelativeURL, UP, DOWN } = require("../../src/util");
class AlertNow extends NotificationProvider {
name = "AlertNow";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let textMsg = "";
let status = "open";
let eventType = "ERROR";
let eventId = new Date().toISOString().slice(0, 10).replace(/-/g, "");
if (heartbeatJSON && heartbeatJSON.status === UP) {
textMsg = `[${heartbeatJSON.name}] ✅ Application is back online`;
status = "close";
eventType = "INFO";
eventId += `_${heartbeatJSON.name.replace(/\s/g, "")}`;
} else if (heartbeatJSON && heartbeatJSON.status === DOWN) {
textMsg = `[${heartbeatJSON.name}] 🔴 Application went down`;
}
textMsg += ` - ${msg}`;
const baseURL = await setting("primaryBaseURL");
if (baseURL && monitorJSON) {
textMsg += ` >> ${baseURL + getMonitorRelativeURL(monitorJSON.id)}`;
}
const data = {
"summary": textMsg,
"status": status,
"event_type": eventType,
"event_id": eventId,
};
await axios.post(notification.alertNowWebhookURL, data);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = AlertNow;

View File

@@ -12,9 +12,7 @@ const { default: axios } = require("axios");
// bark is an APN bridge that sends notifications to Apple devices.
const barkNotificationGroup = "UptimeKuma";
const barkNotificationAvatar = "https://github.com/louislam/uptime-kuma/raw/master/public/icon.png";
const barkNotificationSound = "telegraph";
const successMessage = "Successes!";
class Bark extends NotificationProvider {
@@ -30,17 +28,17 @@ class Bark extends NotificationProvider {
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) {
let title = "UptimeKuma Monitor Up";
return await this.postNotification(title, msg, barkEndpoint);
return await this.postNotification(notification, title, msg, barkEndpoint);
}
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
let title = "UptimeKuma Monitor Down";
return await this.postNotification(title, msg, barkEndpoint);
return await this.postNotification(notification, title, msg, barkEndpoint);
}
if (msg != null) {
let title = "UptimeKuma Message";
return await this.postNotification(title, msg, barkEndpoint);
return await this.postNotification(notification, title, msg, barkEndpoint);
}
}
@@ -50,13 +48,23 @@ class Bark extends NotificationProvider {
* @param {string} postUrl URL to append parameters to
* @returns {string}
*/
appendAdditionalParameters(postUrl) {
// grouping all our notifications
postUrl += "?group=" + barkNotificationGroup;
appendAdditionalParameters(notification, postUrl) {
// set icon to uptime kuma icon, 11kb should be fine
postUrl += "&icon=" + barkNotificationAvatar;
postUrl += "?icon=" + barkNotificationAvatar;
// grouping all our notifications
if (notification.barkGroup != null) {
postUrl += "&group=" + notification.barkGroup;
} else {
// default name
postUrl += "&group=" + "UptimeKuma";
}
// picked a sound, this should follow system's mute status when arrival
postUrl += "&sound=" + barkNotificationSound;
if (notification.barkSound != null) {
postUrl += "&sound=" + notification.barkSound;
} else {
// default sound
postUrl += "&sound=" + "telegraph";
}
return postUrl;
}
@@ -81,12 +89,12 @@ class Bark extends NotificationProvider {
* @param {string} endpoint Endpoint to send request to
* @returns {string}
*/
async postNotification(title, subtitle, endpoint) {
async postNotification(notification, title, subtitle, endpoint) {
// url encode title and subtitle
title = encodeURIComponent(title);
subtitle = encodeURIComponent(subtitle);
let postUrl = endpoint + "/" + title + "/" + subtitle;
postUrl = this.appendAdditionalParameters(postUrl);
postUrl = this.appendAdditionalParameters(notification, postUrl);
let result = await axios.get(postUrl);
this.checkResult(result);
if (result.statusText != null) {

View File

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

View File

@@ -0,0 +1,38 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const defaultNotificationService = "notify";
class HomeAssistant extends NotificationProvider {
name = "HomeAssistant";
async send(notification, message, monitor = null, heartbeat = null) {
const notificationService = notification?.notificationService || defaultNotificationService;
try {
await axios.post(
`${notification.homeAssistantUrl}/api/services/notify/${notificationService}`,
{
title: "Uptime Kuma",
message,
...(notificationService !== "persistent_notification" && { data: {
name: monitor?.name,
status: heartbeat?.status,
} }),
},
{
headers: {
Authorization: `Bearer ${notification.longLivedAccessToken}`,
"Content-Type": "application/json",
},
}
);
return "Sent Successfully.";
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = HomeAssistant;

View File

@@ -0,0 +1,43 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const qs = require("qs");
const { DOWN, UP } = require("../../src/util");
class LineNotify extends NotificationProvider {
name = "LineNotify";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let lineAPIUrl = "https://notify-api.line.me/api/notify";
let config = {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Bearer " + notification.lineNotifyAccessToken
}
};
if (heartbeatJSON == null) {
let testMessage = {
"message": msg,
};
await axios.post(lineAPIUrl, qs.stringify(testMessage), config);
} else if (heartbeatJSON["status"] === DOWN) {
let downMessage = {
"message": "\n[🔴 Down]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
};
await axios.post(lineAPIUrl, qs.stringify(downMessage), config);
} else if (heartbeatJSON["status"] === UP) {
let upMessage = {
"message": "\n[✅ Up]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
};
await axios.post(lineAPIUrl, qs.stringify(upMessage), config);
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = LineNotify;

View File

@@ -8,12 +8,19 @@ class Ntfy extends NotificationProvider {
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
await axios.post(`${notification.ntfyserverurl}`, {
let headers = {};
if (notification.ntfyusername.length > 0) {
headers = {
"Authorization": "Basic " + Buffer.from(notification.ntfyusername + ":" + notification.ntfypassword).toString("base64"),
};
}
let data = {
"topic": notification.ntfytopic,
"message": msg,
"priority": notification.ntfyPriority || 4,
"title": "Uptime-Kuma",
});
};
await axios.post(`${notification.ntfyserverurl}`, data, { headers: headers });
return okMsg;

View File

@@ -10,7 +10,7 @@ class Octopush extends NotificationProvider {
try {
// Default - V2
if (notification.octopushVersion === 2 || !notification.octopushVersion) {
if (notification.octopushVersion === "2" || !notification.octopushVersion) {
let config = {
headers: {
"api-key": notification.octopushAPIKey,
@@ -31,7 +31,7 @@ class Octopush extends NotificationProvider {
"sender": notification.octopushSenderName
};
await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config);
} else if (notification.octopushVersion === 1) {
} else if (notification.octopushVersion === "1") {
let data = {
"user_login": notification.octopushDMLogin,
"api_key": notification.octopushDMAPIKey,
@@ -49,7 +49,15 @@ class Octopush extends NotificationProvider {
},
params: data
};
await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config);
// V1 API returns 200 even on error so we must check
// response data
let response = await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config);
if ("error_code" in response.data) {
if (response.data.error_code !== "000") {
this.throwGeneralAxiosError(`Octopush error ${JSON.stringify(response.data)}`);
}
}
} else {
throw new Error("Unknown Octopush version!");
}

View File

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

View File

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

View File

@@ -0,0 +1,76 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { DOWN } = require("../../src/util");
class Squadcast extends NotificationProvider {
name = "squadcast";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let config = {};
let data = {
message: msg,
description: "",
tags: {},
heartbeat: heartbeatJSON,
source: "uptime-kuma"
};
if (heartbeatJSON !== null) {
data.description = heartbeatJSON["msg"];
data.event_id = heartbeatJSON["monitorID"];
if (heartbeatJSON["status"] === DOWN) {
data.message = `${monitorJSON["name"]} is DOWN`;
data.status = "trigger";
} else {
data.message = `${monitorJSON["name"]} is UP`;
data.status = "resolve";
}
let address;
switch (monitorJSON["type"]) {
case "ping":
address = monitorJSON["hostname"];
break;
case "port":
case "dns":
case "steam":
address = monitorJSON["hostname"];
if (monitorJSON["port"]) {
address += ":" + monitorJSON["port"];
}
break;
default:
address = monitorJSON["url"];
break;
}
data.tags["AlertAddress"] = address;
monitorJSON["tags"].forEach(tag => {
data.tags[tag["name"]] = {
value: tag["value"]
};
if (tag["color"] !== null) {
data.tags[tag["name"]]["color"] = tag["color"];
}
});
}
await axios.post(notification.squadcastWebhookURL, data, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = Squadcast;

View File

@@ -63,7 +63,7 @@ class Teams extends NotificationProvider {
});
}
if (monitorUrl) {
if (monitorUrl && monitorUrl !== "https://") {
facts.push({
name: "URL",
value: monitorUrl,
@@ -127,13 +127,17 @@ class Teams extends NotificationProvider {
let url;
if (monitorJSON["type"] === "port") {
url = monitorJSON["hostname"];
if (monitorJSON["port"]) {
url += ":" + monitorJSON["port"];
}
} else {
url = monitorJSON["url"];
switch (monitorJSON["type"]) {
case "http":
case "keywork":
url = monitorJSON["url"];
break;
case "docker":
url = monitorJSON["docker_host"];
break;
default:
url = monitorJSON["hostname"];
break;
}
const payload = this._notificationPayloadFactory({

View File

@@ -1,40 +1,47 @@
const { R } = require("redbean-node");
const { log } = require("../src/util");
const Alerta = require("./notification-providers/alerta");
const AlertNow = require("./notification-providers/alertnow");
const AliyunSms = require("./notification-providers/aliyun-sms");
const Apprise = require("./notification-providers/apprise");
const Discord = require("./notification-providers/discord");
const Gotify = require("./notification-providers/gotify");
const Ntfy = require("./notification-providers/ntfy");
const Line = require("./notification-providers/line");
const LunaSea = require("./notification-providers/lunasea");
const Mattermost = require("./notification-providers/mattermost");
const Matrix = require("./notification-providers/matrix");
const Octopush = require("./notification-providers/octopush");
const PromoSMS = require("./notification-providers/promosms");
const Bark = require("./notification-providers/bark");
const ClickSendSMS = require("./notification-providers/clicksendsms");
const DingDing = require("./notification-providers/dingding");
const Discord = require("./notification-providers/discord");
const Feishu = require("./notification-providers/feishu");
const GoogleChat = require("./notification-providers/google-chat");
const Gorush = require("./notification-providers/gorush");
const Gotify = require("./notification-providers/gotify");
const HomeAssistant = require("./notification-providers/home-assistant");
const Line = require("./notification-providers/line");
const LineNotify = require("./notification-providers/linenotify");
const LunaSea = require("./notification-providers/lunasea");
const Matrix = require("./notification-providers/matrix");
const Mattermost = require("./notification-providers/mattermost");
const Ntfy = require("./notification-providers/ntfy");
const Octopush = require("./notification-providers/octopush");
const OneBot = require("./notification-providers/onebot");
const PagerDuty = require("./notification-providers/pagerduty");
const PromoSMS = require("./notification-providers/promosms");
const Pushbullet = require("./notification-providers/pushbullet");
const PushDeer = require("./notification-providers/pushdeer");
const Pushover = require("./notification-providers/pushover");
const Pushy = require("./notification-providers/pushy");
const TechulusPush = require("./notification-providers/techulus-push");
const RocketChat = require("./notification-providers/rocket-chat");
const SerwerSMS = require("./notification-providers/serwersms");
const Signal = require("./notification-providers/signal");
const Slack = require("./notification-providers/slack");
const SMTP = require("./notification-providers/smtp");
const Squadcast = require("./notification-providers/squadcast");
const Stackfield = require("./notification-providers/stackfield");
const Teams = require("./notification-providers/teams");
const TechulusPush = require("./notification-providers/techulus-push");
const Telegram = require("./notification-providers/telegram");
const Webhook = require("./notification-providers/webhook");
const Feishu = require("./notification-providers/feishu");
const AliyunSms = require("./notification-providers/aliyun-sms");
const DingDing = require("./notification-providers/dingding");
const Bark = require("./notification-providers/bark");
const { log } = require("../src/util");
const SerwerSMS = require("./notification-providers/serwersms");
const Stackfield = require("./notification-providers/stackfield");
const WeCom = require("./notification-providers/wecom");
const GoogleChat = require("./notification-providers/google-chat");
const PagerDuty = require("./notification-providers/pagerduty");
const Gorush = require("./notification-providers/gorush");
const Alerta = require("./notification-providers/alerta");
const OneBot = require("./notification-providers/onebot");
const PushDeer = require("./notification-providers/pushdeer");
const GoAlert = require("./notification-providers/goalert");
const SMSManager = require("./notification-providers/smsmanager");
const ServerChan = require("./notification-providers/serverchan");
class Notification {
@@ -47,41 +54,48 @@ class Notification {
this.providerList = {};
const list = [
new Apprise(),
new Alerta(),
new AlertNow(),
new AliyunSms(),
new Apprise(),
new Bark(),
new ClickSendSMS(),
new DingDing(),
new Discord(),
new Teams(),
new Gotify(),
new Ntfy(),
new Line(),
new LunaSea(),
new Feishu(),
new Mattermost(),
new GoogleChat(),
new Gorush(),
new Gotify(),
new HomeAssistant(),
new Line(),
new LineNotify(),
new LunaSea(),
new Matrix(),
new Mattermost(),
new Ntfy(),
new Octopush(),
new OneBot(),
new PagerDuty(),
new PromoSMS(),
new ClickSendSMS(),
new Pushbullet(),
new PushDeer(),
new Pushover(),
new Pushy(),
new TechulusPush(),
new RocketChat(),
new ServerChan(),
new SerwerSMS(),
new Signal(),
new SMSManager(),
new Slack(),
new SMTP(),
new Squadcast(),
new Stackfield(),
new Teams(),
new TechulusPush(),
new Telegram(),
new Webhook(),
new Bark(),
new SerwerSMS(),
new Stackfield(),
new WeCom(),
new GoogleChat(),
new PagerDuty(),
new Gorush(),
new Alerta(),
new OneBot(),
new PushDeer(),
new GoAlert(),
];
for (let item of list) {

View File

@@ -136,6 +136,7 @@ router.get("/api/badge/:id/status", cache("5 minutes"), async (request, response
const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId);
const state = overrideValue !== undefined ? overrideValue : heartbeat.status === 1;
badgeValues.label = label ? label : "";
badgeValues.color = state ? upColor : downColor;
badgeValues.message = label ?? state ? upLabel : downLabel;
}

View File

@@ -107,4 +107,42 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
}
});
// Status page's manifest.json
router.get("/api/status-page/:slug/manifest.json", cache("1440 minutes"), async (request, response) => {
allowDevAllOrigin(response);
let slug = request.params.slug;
try {
// Get Status Page
let statusPage = await R.findOne("status_page", " slug = ? ", [
slug
]);
if (!statusPage) {
response.statusCode = 404;
response.json({
msg: "Not Found"
});
return;
}
// Response
response.json({
"name": statusPage.title,
"start_url": "/status/" + statusPage.slug,
"display": "standalone",
"icons": [
{
"src": statusPage.icon,
"sizes": "128x128",
"type": "image/png"
}
]
});
} catch (error) {
send403(response, error.message);
}
});
module.exports = router;

View File

@@ -61,7 +61,7 @@ log.info("server", "Importing this project modules");
log.debug("server", "Importing Monitor");
const Monitor = require("./model/monitor");
log.debug("server", "Importing Settings");
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword } = require("./util-server");
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests } = require("./util-server");
log.debug("server", "Importing Notification");
const { Notification } = require("./notification");
@@ -112,19 +112,21 @@ const twoFAVerifyOptions = {
* @type {boolean}
*/
const testMode = !!args["test"] || false;
const e2eTestMode = !!args["e2e"] || false;
if (config.demoMode) {
log.info("server", "==== Demo Mode ====");
}
// Must be after io instantiation
const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList } = require("./client");
const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList, sendDockerHostList } = require("./client");
const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler");
const databaseSocketHandler = require("./socket-handlers/database-socket-handler");
const TwoFA = require("./2fa");
const StatusPage = require("./model/status_page");
const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudflaredStop } = require("./socket-handlers/cloudflared-socket-handler");
const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler");
const { dockerSocketHandler } = require("./socket-handlers/docker-socket-handler");
app.use(express.json());
@@ -164,12 +166,20 @@ let needSetup = false;
// Entry Page
app.get("/", async (request, response) => {
log.debug("entry", `Request Domain: ${request.hostname}`);
let hostname = request.hostname;
if (await setting("trustProxy")) {
const proxy = request.headers["x-forwarded-host"];
if (proxy) {
hostname = proxy;
}
}
if (request.hostname in StatusPage.domainMappingList) {
log.debug("entry", `Request Domain: ${hostname}`);
if (hostname in StatusPage.domainMappingList) {
log.debug("entry", "This is a status page domain");
let slug = StatusPage.domainMappingList[request.hostname];
let slug = StatusPage.domainMappingList[hostname];
await StatusPage.handleStatusPageResponse(response, server.indexHTML, slug);
} else if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) {
@@ -246,7 +256,9 @@ let needSetup = false;
// ***************************
socket.on("loginByToken", async (token, callback) => {
log.info("auth", `Login by token. IP=${getClientIp(socket)}`);
const clientIP = await server.getClientIP(socket);
log.info("auth", `Login by token. IP=${clientIP}`);
try {
let decoded = jwt.verify(token, jwtSecret);
@@ -262,14 +274,14 @@ let needSetup = false;
afterLogin(socket, user);
log.debug("auth", "afterLogin ok");
log.info("auth", `Successfully logged in user ${decoded.username}. IP=${getClientIp(socket)}`);
log.info("auth", `Successfully logged in user ${decoded.username}. IP=${clientIP}`);
callback({
ok: true,
});
} else {
log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${getClientIp(socket)}`);
log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${clientIP}`);
callback({
ok: false,
@@ -278,7 +290,7 @@ let needSetup = false;
}
} catch (error) {
log.error("auth", `Invalid token. IP=${getClientIp(socket)}`);
log.error("auth", `Invalid token. IP=${clientIP}`);
callback({
ok: false,
@@ -289,7 +301,9 @@ let needSetup = false;
});
socket.on("login", async (data, callback) => {
log.info("auth", `Login by username + password. IP=${getClientIp(socket)}`);
const clientIP = await server.getClientIP(socket);
log.info("auth", `Login by username + password. IP=${clientIP}`);
// Checking
if (typeof callback !== "function") {
@@ -302,7 +316,7 @@ let needSetup = false;
// Login Rate Limit
if (! await loginRateLimiter.pass(callback)) {
log.info("auth", `Too many failed requests for user ${data.username}. IP=${getClientIp(socket)}`);
log.info("auth", `Too many failed requests for user ${data.username}. IP=${clientIP}`);
return;
}
@@ -312,7 +326,7 @@ let needSetup = false;
if (user.twofa_status === 0) {
afterLogin(socket, user);
log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`);
log.info("auth", `Successfully logged in user ${data.username}. IP=${clientIP}`);
callback({
ok: true,
@@ -324,7 +338,7 @@ let needSetup = false;
if (user.twofa_status === 1 && !data.token) {
log.info("auth", `2FA token required for user ${data.username}. IP=${getClientIp(socket)}`);
log.info("auth", `2FA token required for user ${data.username}. IP=${clientIP}`);
callback({
tokenRequired: true,
@@ -342,7 +356,7 @@ let needSetup = false;
socket.userID,
]);
log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`);
log.info("auth", `Successfully logged in user ${data.username}. IP=${clientIP}`);
callback({
ok: true,
@@ -352,7 +366,7 @@ let needSetup = false;
});
} else {
log.warn("auth", `Invalid token provided for user ${data.username}. IP=${getClientIp(socket)}`);
log.warn("auth", `Invalid token provided for user ${data.username}. IP=${clientIP}`);
callback({
ok: false,
@@ -362,7 +376,7 @@ let needSetup = false;
}
} else {
log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${getClientIp(socket)}`);
log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${clientIP}`);
callback({
ok: false,
@@ -434,6 +448,8 @@ let needSetup = false;
});
socket.on("save2FA", async (currentPassword, callback) => {
const clientIP = await server.getClientIP(socket);
try {
if (! await twoFaRateLimiter.pass(callback)) {
return;
@@ -446,7 +462,7 @@ let needSetup = false;
socket.userID,
]);
log.info("auth", `Saved 2FA token. IP=${getClientIp(socket)}`);
log.info("auth", `Saved 2FA token. IP=${clientIP}`);
callback({
ok: true,
@@ -454,7 +470,7 @@ let needSetup = false;
});
} catch (error) {
log.error("auth", `Error changing 2FA token. IP=${getClientIp(socket)}`);
log.error("auth", `Error changing 2FA token. IP=${clientIP}`);
callback({
ok: false,
@@ -464,6 +480,8 @@ let needSetup = false;
});
socket.on("disable2FA", async (currentPassword, callback) => {
const clientIP = await server.getClientIP(socket);
try {
if (! await twoFaRateLimiter.pass(callback)) {
return;
@@ -473,7 +491,7 @@ let needSetup = false;
await doubleCheckPassword(socket, currentPassword);
await TwoFA.disable2FA(socket.userID);
log.info("auth", `Disabled 2FA token. IP=${getClientIp(socket)}`);
log.info("auth", `Disabled 2FA token. IP=${clientIP}`);
callback({
ok: true,
@@ -481,7 +499,7 @@ let needSetup = false;
});
} catch (error) {
log.error("auth", `Error disabling 2FA token. IP=${getClientIp(socket)}`);
log.error("auth", `Error disabling 2FA token. IP=${clientIP}`);
callback({
ok: false,
@@ -652,6 +670,7 @@ let needSetup = false;
bean.basic_auth_pass = monitor.basic_auth_pass;
bean.interval = monitor.interval;
bean.retryInterval = monitor.retryInterval;
bean.resendInterval = monitor.resendInterval;
bean.hostname = monitor.hostname;
bean.maxretries = monitor.maxretries;
bean.port = parseInt(monitor.port);
@@ -664,6 +683,8 @@ let needSetup = false;
bean.dns_resolve_type = monitor.dns_resolve_type;
bean.dns_resolve_server = monitor.dns_resolve_server;
bean.pushToken = monitor.pushToken;
bean.docker_container = monitor.docker_container;
bean.docker_host = monitor.docker_host;
bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null;
bean.mqttUsername = monitor.mqttUsername;
bean.mqttPassword = monitor.mqttPassword;
@@ -674,6 +695,11 @@ let needSetup = false;
bean.authMethod = monitor.authMethod;
bean.authWorkstation = monitor.authWorkstation;
bean.authDomain = monitor.authDomain;
bean.radiusUsername = monitor.radiusUsername;
bean.radiusPassword = monitor.radiusPassword;
bean.radiusCalledStationId = monitor.radiusCalledStationId;
bean.radiusCallingStationId = monitor.radiusCallingStationId;
bean.radiusSecret = monitor.radiusSecret;
await R.store(bean);
@@ -1254,6 +1280,7 @@ let needSetup = false;
authDomain: monitorListData[i].authDomain,
interval: monitorListData[i].interval,
retryInterval: retryInterval,
resendInterval: monitorListData[i].resendInterval || 0,
hostname: monitorListData[i].hostname,
maxretries: monitorListData[i].maxretries,
port: monitorListData[i].port,
@@ -1422,6 +1449,7 @@ let needSetup = false;
cloudflaredSocketHandler(socket);
databaseSocketHandler(socket);
proxySocketHandler(socket);
dockerSocketHandler(socket);
log.debug("server", "added all socket handlers");
@@ -1459,6 +1487,10 @@ let needSetup = false;
if (testMode) {
startUnitTest();
}
if (e2eTestMode) {
startE2eTests();
}
});
initBackgroundJobs(args);
@@ -1522,6 +1554,7 @@ async function afterLogin(socket, user) {
let monitorList = await server.sendMonitorList(socket);
sendNotificationList(socket);
sendProxyList(socket);
sendDockerHostList(socket);
await sleep(500);
@@ -1676,10 +1709,6 @@ async function shutdownFunction(signal) {
await cloudflaredStop();
}
function getClientIp(socket) {
return socket.client.conn.remoteAddress.replace(/^.*:/, "");
}
/** Final function called before application exits */
function finalFunction() {
log.info("server", "Graceful shutdown successful!");

165
server/settings.js Normal file
View File

@@ -0,0 +1,165 @@
const { R } = require("redbean-node");
const { log } = require("../src/util");
class Settings {
/**
* Example:
* {
* key1: {
* value: "value2",
* timestamp: 12345678
* },
* key2: {
* value: 2,
* timestamp: 12345678
* },
* }
* @type {{}}
*/
static cacheList = {
};
static cacheCleaner = null;
/**
* Retrieve value of setting based on key
* @param {string} key Key of setting to retrieve
* @returns {Promise<any>} Value
*/
static async get(key) {
// Start cache clear if not started yet
if (!Settings.cacheCleaner) {
Settings.cacheCleaner = setInterval(() => {
log.debug("settings", "Cache Cleaner is just started.");
for (key in Settings.cacheList) {
if (Date.now() - Settings.cacheList[key].timestamp > 60 * 1000) {
log.debug("settings", "Cache Cleaner deleted: " + key);
delete Settings.cacheList[key];
}
}
}, 60 * 1000);
}
// Query from cache
if (key in Settings.cacheList) {
const v = Settings.cacheList[key].value;
log.debug("settings", `Get Setting (cache): ${key}: ${v}`);
return v;
}
let value = await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [
key,
]);
try {
const v = JSON.parse(value);
log.debug("settings", `Get Setting: ${key}: ${v}`);
Settings.cacheList[key] = {
value: v,
timestamp: Date.now()
};
return v;
} catch (e) {
return value;
}
}
/**
* Sets the specified setting to specified value
* @param {string} key Key of setting to set
* @param {any} value Value to set to
* @param {?string} type Type of setting
* @returns {Promise<void>}
*/
static async set(key, value, type = null) {
let bean = await R.findOne("setting", " `key` = ? ", [
key,
]);
if (!bean) {
bean = R.dispense("setting");
bean.key = key;
}
bean.type = type;
bean.value = JSON.stringify(value);
await R.store(bean);
Settings.deleteCache([ key ]);
}
/**
* Get settings based on type
* @param {string} type The type of setting
* @returns {Promise<Bean>}
*/
static async getSettings(type) {
let list = await R.getAll("SELECT `key`, `value` FROM setting WHERE `type` = ? ", [
type,
]);
let result = {};
for (let row of list) {
try {
result[row.key] = JSON.parse(row.value);
} catch (e) {
result[row.key] = row.value;
}
}
return result;
}
/**
* Set settings based on type
* @param {string} type Type of settings to set
* @param {Object} data Values of settings
* @returns {Promise<void>}
*/
static async setSettings(type, data) {
let keyList = Object.keys(data);
let promiseList = [];
for (let key of keyList) {
let bean = await R.findOne("setting", " `key` = ? ", [
key
]);
if (bean == null) {
bean = R.dispense("setting");
bean.type = type;
bean.key = key;
}
if (bean.type === type) {
bean.value = JSON.stringify(data[key]);
promiseList.push(R.store(bean));
}
}
await Promise.all(promiseList);
Settings.deleteCache(keyList);
}
/**
*
* @param {string[]} keyList
*/
static deleteCache(keyList) {
for (let key of keyList) {
delete Settings.cacheList[key];
}
}
}
module.exports = {
Settings,
};

View File

@@ -0,0 +1,79 @@
const { sendDockerHostList } = require("../client");
const { checkLogin } = require("../util-server");
const { DockerHost } = require("../docker");
const { log } = require("../../src/util");
/**
* Handlers for docker hosts
* @param {Socket} socket Socket.io instance
*/
module.exports.dockerSocketHandler = (socket) => {
socket.on("addDockerHost", async (dockerHost, dockerHostID, callback) => {
try {
checkLogin(socket);
let dockerHostBean = await DockerHost.save(dockerHost, dockerHostID, socket.userID);
await sendDockerHostList(socket);
callback({
ok: true,
msg: "Saved",
id: dockerHostBean.id,
});
} catch (e) {
callback({
ok: false,
msg: e.message,
});
}
});
socket.on("deleteDockerHost", async (dockerHostID, callback) => {
try {
checkLogin(socket);
await DockerHost.delete(dockerHostID, socket.userID);
await sendDockerHostList(socket);
callback({
ok: true,
msg: "Deleted",
});
} catch (e) {
callback({
ok: false,
msg: e.message,
});
}
});
socket.on("testDockerHost", async (dockerHost, callback) => {
try {
checkLogin(socket);
let amount = await DockerHost.testDockerHost(dockerHost);
let msg;
if (amount >= 1) {
msg = "Connected Successfully. Amount of containers: " + amount;
} else {
msg = "Connected Successfully, but there are no containers?";
}
callback({
ok: true,
msg,
});
} catch (e) {
log.error("docker", e);
callback({
ok: false,
msg: e.message,
});
}
});
};

View File

@@ -202,6 +202,11 @@ module.exports.statusPageSocketHandler = (socket) => {
relationBean.weight = monitorOrder++;
relationBean.group_id = groupBean.id;
relationBean.monitor_id = monitor.id;
if (monitor.sendUrl !== undefined) {
relationBean.send_url = monitor.sendUrl;
}
await R.store(relationBean);
}

View File

@@ -7,6 +7,8 @@ const { R } = require("redbean-node");
const { log } = require("../src/util");
const Database = require("./database");
const util = require("util");
const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent");
const { Settings } = require("./settings");
/**
* `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue.
@@ -49,7 +51,6 @@ class UptimeKumaServer {
log.info("server", "Creating express and socket.io instance");
this.app = express();
if (sslKey && sslCert) {
log.info("server", "Server Type: HTTPS");
this.httpServer = https.createServer({
@@ -71,6 +72,8 @@ class UptimeKumaServer {
}
}
CacheableDnsHttpAgent.registerGlobalAgent();
this.io = new Server(this.httpServer);
}
@@ -126,6 +129,22 @@ class UptimeKumaServer {
errorLogStream.end();
}
async getClientIP(socket) {
let clientIP = socket.client.conn.remoteAddress;
if (clientIP === undefined) {
clientIP = "";
}
if (await Settings.get("trustProxy")) {
return socket.client.conn.request.headers["x-forwarded-for"]
|| socket.client.conn.request.headers["x-real-ip"]
|| clientIP.replace(/^.*:/, "");
} else {
return clientIP.replace(/^.*:/, "");
}
}
}
module.exports = {

View File

@@ -11,7 +11,16 @@ const mqtt = require("mqtt");
const chroma = require("chroma-js");
const { badgeConstants } = require("./config");
const mssql = require("mssql");
const { Client } = require("pg");
const postgresConParse = require("pg-connection-string").parse;
const { NtlmClient } = require("axios-ntlm");
const { Settings } = require("./settings");
const radiusClient = require("node-radius-client");
const {
dictionaries: {
rfc2865: { file, attributes },
},
} = require("node-radius-utils");
// From ping-lite
exports.WIN = /^win/.test(process.platform);
@@ -237,10 +246,6 @@ exports.dnsResolve = function (hostname, resolverServer, resolverPort, rrtype) {
*/
exports.mssqlQuery = function (connectionString, query) {
return new Promise((resolve, reject) => {
mssql.on("error", err => {
reject(err);
});
mssql.connect(connectionString).then(pool => {
return pool.request()
.query(query);
@@ -254,23 +259,70 @@ exports.mssqlQuery = function (connectionString, query) {
});
};
/**
* Run a query on Postgres
* @param {string} connectionString The database connection string
* @param {string} query The query to validate the database with
* @returns {Promise<(string[]|Object[]|Object)>}
*/
exports.postgresQuery = function (connectionString, query) {
return new Promise((resolve, reject) => {
const config = postgresConParse(connectionString);
if (config.password === "") {
// See https://github.com/brianc/node-postgres/issues/1927
return reject(new Error("Password is undefined."));
}
const client = new Client({ connectionString });
client.connect();
return client.query(query)
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
})
.finally(() => {
client.end();
});
});
};
exports.radius = function (
hostname,
username,
password,
calledStationId,
callingStationId,
secret,
) {
const client = new radiusClient({
host: hostname,
dictionaries: [ file ],
});
return client.accessRequest({
secret: secret,
attributes: [
[ attributes.USER_NAME, username ],
[ attributes.USER_PASSWORD, password ],
[ attributes.CALLING_STATION_ID, callingStationId ],
[ attributes.CALLED_STATION_ID, calledStationId ],
],
});
};
/**
* Retrieve value of setting based on key
* @param {string} key Key of setting to retrieve
* @returns {Promise<any>} Value
* @deprecated Use await Settings.get(key)
*/
exports.setting = async function (key) {
let value = await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [
key,
]);
try {
const v = JSON.parse(value);
log.debug("util", `Get Setting: ${key}: ${v}`);
return v;
} catch (e) {
return value;
}
return await Settings.get(key);
};
/**
@@ -281,70 +333,26 @@ exports.setting = async function (key) {
* @returns {Promise<void>}
*/
exports.setSetting = async function (key, value, type = null) {
let bean = await R.findOne("setting", " `key` = ? ", [
key,
]);
if (!bean) {
bean = R.dispense("setting");
bean.key = key;
}
bean.type = type;
bean.value = JSON.stringify(value);
await R.store(bean);
await Settings.set(key, value, type);
};
/**
* Get settings based on type
* @param {?string} type The type of setting
* @param {string} type The type of setting
* @returns {Promise<Bean>}
*/
exports.getSettings = async function (type) {
let list = await R.getAll("SELECT `key`, `value` FROM setting WHERE `type` = ? ", [
type,
]);
let result = {};
for (let row of list) {
try {
result[row.key] = JSON.parse(row.value);
} catch (e) {
result[row.key] = row.value;
}
}
return result;
return await Settings.getSettings(type);
};
/**
* Set settings based on type
* @param {?string} type Type of settings to set
* @param {string} type Type of settings to set
* @param {Object} data Values of settings
* @returns {Promise<void>}
*/
exports.setSettings = async function (type, data) {
let keyList = Object.keys(data);
let promiseList = [];
for (let key of keyList) {
let bean = await R.findOne("setting", " `key` = ? ", [
key
]);
if (bean == null) {
bean = R.dispense("setting");
bean.type = type;
bean.key = key;
}
if (bean.type === type) {
bean.value = JSON.stringify(data[key]);
promiseList.push(R.store(bean));
}
}
await Promise.all(promiseList);
await Settings.setSettings(type, data);
};
// ssl-checker by @dyaa
@@ -437,7 +445,7 @@ exports.checkCertificate = function (res) {
/**
* Check if the provided status code is within the accepted ranges
* @param {string} status The status code to check
* @param {number} status The status code to check
* @param {string[]} acceptedCodes An array of accepted status codes
* @returns {boolean} True if status code within range, false otherwise
* @throws {Error} Will throw an error if the provided status code is not a valid range string or code string
@@ -565,6 +573,26 @@ exports.startUnitTest = async () => {
});
};
/** Start end-to-end tests */
exports.startE2eTests = async () => {
console.log("Starting unit test...");
const npm = /^win/.test(process.platform) ? "npm.cmd" : "npm";
const child = childProcess.spawn(npm, [ "run", "cy:run" ]);
child.stdout.on("data", (data) => {
console.log(data.toString());
});
child.stderr.on("data", (data) => {
console.log(data.toString());
});
child.on("close", function (code) {
console.log("Jest exit code: " + code);
process.exit(code);
});
};
/**
* Convert unknown string to UTF8
* @param {Uint8Array} body Buffer

View File

@@ -382,7 +382,7 @@ optgroup {
overflow-y: auto;
height: calc(100% - 65px);
}
@media (max-width: 770px) {
&.scrollbar {
height: calc(100% - 40px);
@@ -403,7 +403,6 @@ optgroup {
.info {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&:hover {

View File

@@ -0,0 +1,178 @@
<template>
<form @submit.prevent="submit">
<div ref="modal" class="modal fade" tabindex="-1" data-bs-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 id="exampleModalLabel" class="modal-title">
{{ $t("Setup Docker Host") }}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" />
</div>
<div class="modal-body">
<div class="mb-3">
<label for="docker-name" class="form-label">{{ $t("Friendly Name") }}</label>
<input id="docker-name" v-model="dockerHost.name" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="docker-type" class="form-label">{{ $t("Connection Type") }}</label>
<select id="docker-type" v-model="dockerHost.dockerType" class="form-select">
<option v-for="type in connectionTypes" :key="type" :value="type">{{ $t(type) }}</option>
</select>
</div>
<div class="mb-3">
<label for="docker-daemon" class="form-label">{{ $t("Docker Daemon") }}</label>
<input id="docker-daemon" v-model="dockerHost.dockerDaemon" type="text" class="form-control" required>
<div class="form-text">
{{ $t("Examples") }}:
<ul>
<li>/var/run/docker.sock</li>
<li>http://localhost:2375</li>
<li>https://localhost:2376 (TLS)</li>
</ul>
</div>
</div>
</div>
<div class="modal-footer">
<button v-if="id" type="button" class="btn btn-danger" :disabled="processing" @click="deleteConfirm">
{{ $t("Delete") }}
</button>
<button type="button" class="btn btn-warning" :disabled="processing" @click="test">
{{ $t("Test") }}
</button>
<button type="submit" class="btn btn-primary" :disabled="processing">
<div v-if="processing" class="spinner-border spinner-border-sm me-1"></div>
{{ $t("Save") }}
</button>
</div>
</div>
</div>
</div>
</form>
<Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="deleteDockerHost">
{{ $t("deleteDockerHostMsg") }}
</Confirm>
</template>
<script lang="ts">
import { Modal } from "bootstrap";
import Confirm from "./Confirm.vue";
import { useToast } from "vue-toastification";
const toast = useToast();
export default {
components: {
Confirm,
},
props: {},
emits: [ "added" ],
data() {
return {
model: null,
processing: false,
id: null,
connectionTypes: [ "socket", "tcp" ],
dockerHost: {
name: "",
dockerDaemon: "",
dockerType: "",
// Do not set default value here, please scroll to show()
}
};
},
mounted() {
this.modal = new Modal(this.$refs.modal);
},
methods: {
deleteConfirm() {
this.modal.hide();
this.$refs.confirmDelete.show();
},
show(dockerHostID) {
if (dockerHostID) {
let found = false;
this.id = dockerHostID;
for (let n of this.$root.dockerHostList) {
if (n.id === dockerHostID) {
this.dockerHost = n;
found = true;
break;
}
}
if (!found) {
toast.error("Docker Host not found!");
}
} else {
this.id = null;
this.dockerHost = {
name: "",
dockerType: "socket",
dockerDaemon: "/var/run/docker.sock",
};
}
this.modal.show();
},
submit() {
this.processing = true;
this.$root.getSocket().emit("addDockerHost", this.dockerHost, this.id, (res) => {
this.$root.toastRes(res);
this.processing = false;
if (res.ok) {
this.modal.hide();
// Emit added event, doesn't emit edit.
if (! this.id) {
this.$emit("added", res.id);
}
}
});
},
test() {
this.processing = true;
this.$root.getSocket().emit("testDockerHost", this.dockerHost, (res) => {
this.$root.toastRes(res);
this.processing = false;
});
},
deleteDockerHost() {
this.processing = true;
this.$root.getSocket().emit("deleteDockerHost", this.id, (res) => {
this.$root.toastRes(res);
this.processing = false;
if (res.ok) {
this.modal.hide();
}
});
},
},
};
</script>
<style lang="scss" scoped>
@import "../assets/vars.scss";
.dark {
.modal-dialog .form-text, .modal-dialog p {
color: $dark-font-color;
}
}
</style>

View File

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

View File

@@ -39,7 +39,28 @@
<font-awesome-icon v-if="editMode" icon="times" class="action remove me-3" @click="removeMonitor(group.index, monitor.index)" />
<Uptime :monitor="monitor.element" type="24" :pill="true" />
{{ monitor.element.name }}
<a
v-if="showLink(monitor)"
:href="monitor.element.url"
class="item-name"
target="_blank"
rel="noopener noreferrer"
>
{{ monitor.element.name }}
</a>
<p v-else class="item-name"> {{ monitor.element.name }} </p>
<span
v-if="showLink(monitor, true)"
title="Toggle Clickable Link"
>
<font-awesome-icon
v-if="editMode"
:class="{'link-active': monitor.element.sendUrl, 'btn-link': true}"
icon="link" class="action me-3"
@click="toggleLink(group.index, monitor.index)"
/>
</span>
</div>
<div v-if="showTags" class="tags">
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
@@ -113,6 +134,33 @@ export default {
removeMonitor(groupIndex, index) {
this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1);
},
/**
* Toggle the value of sendUrl
* @param {number} groupIndex Index of group monitor is member of
* @param {number} index Index of monitor within group
*/
toggleLink(groupIndex, index) {
this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl = !this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl;
},
/**
* Should a link to the monitor be shown?
* Attempts to guess if a link should be shown based upon if
* sendUrl is set and if the URL is default or not.
* @param {Object} monitor Monitor to check
* @param {boolean} [ignoreSendUrl=false] Should the presence of the sendUrl
* property be ignored. This will only work in edit mode.
* @returns {boolean}
*/
showLink(monitor, ignoreSendUrl = false) {
// We must check if there are any elements in monitorList to
// prevent undefined errors if it hasn't been loaded yet
if (this.$parent.editMode && ignoreSendUrl && Object.keys(this.$root.monitorList).length) {
return this.$root.monitorList[monitor.element.id].type === "http" || this.$root.monitorList[monitor.element.id].type === "keyword";
}
return monitor.element.sendUrl && monitor.element.url && monitor.element.url !== "https://" && !this.editMode;
},
}
};
</script>
@@ -131,6 +179,22 @@ export default {
min-height: 46px;
}
.item-name {
padding-left: 5px;
padding-right: 5px;
margin: 0;
display: inline-block;
}
.btn-link {
color: #bbbbbb;
margin-left: 5px;
}
.link-active {
color: $primary;
}
.flip-list-move {
transition: transform 0.5s;
}

View File

@@ -0,0 +1,13 @@
<template>
<div class="mb-3">
<label for="alertnow-webhook-url" class="form-label">{{ $t("Webhook URL") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="alertnow-webhook-url" v-model="$parent.notification.alertNowWebhookURL" type="text" class="form-control" required>
<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://service.opsnow.com/docs/alertnow/en/user-guide-alertnow-en.html#standard" target="_blank">{{ $t("here") }}</a>
</i18n-t>
</div>
</div>
</template>

View File

@@ -2,9 +2,6 @@
<div class="mb-3">
<label for="Bark Endpoint" class="form-label">{{ $t("Bark Endpoint") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="Bark Endpoint" v-model="$parent.notification.barkEndpoint" type="text" class="form-control" required>
<div class="form-text">
<p><span style="color: red;"><sup>*</sup></span>{{ $t("Required") }}</p>
</div>
<i18n-t tag="div" keypath="wayToGetTeamsURL" class="form-text">
<a
href="https://github.com/Finb/Bark"
@@ -12,4 +9,45 @@
>{{ $t("here") }}</a>
</i18n-t>
</div>
<div class="mb-3">
<label for="Bark Group" class="form-label">{{ $t("Bark Group") }}</label>
<input id="Bark Group" v-model="$parent.notification.barkGroup" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="Bark Sound" class="form-label">{{ $t("Bark Sound") }}</label>
<select id="Bark Sound" v-model="$parent.notification.barkSound" class="form-select" required>
<option value="alarm">alarm</option>
<option value="anticipate">anticipate</option>
<option value="bell">bell</option>
<option value="birdsong">birdsong</option>
<option value="bloom">bloom</option>
<option value="calypso">calypso</option>
<option value="chime">chime</option>
<option value="choo">choo</option>
<option value="descent">descent</option>
<option value="electronic">electronic</option>
<option value="fanfare">fanfare</option>
<option value="glass">glass</option>
<option value="gotosleep">gotosleep</option>
<option value="healthnotification">healthnotification</option>
<option value="horn">horn</option>
<option value="ladder">ladder</option>
<option value="mailsent">mailsent</option>
<option value="minuet">minuet</option>
<option value="multiwayinvitation">multiwayinvitation</option>
<option value="newmail">newmail</option>
<option value="newsflash">newsflash</option>
<option value="noir">noir</option>
<option value="paymentsuccess">paymentsuccess</option>
<option value="shake">shake</option>
<option value="sherwoodforest">sherwoodforest</option>
<option value="silence">silence</option>
<option value="spell">spell</option>
<option value="suspense">suspense</option>
<option value="telegraph">telegraph</option>
<option value="tiptoes">tiptoes</option>
<option value="typewriters">typewriters</option>
<option value="update">update</option>
</select>
</div>
</template>

View File

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

View File

@@ -0,0 +1,40 @@
<template>
<div class="mb-3">
<label for="homeAssistantUrl" class="form-label">{{ $t("Home Assistant URL") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="homeAssistantUrl" v-model="$parent.notification.homeAssistantUrl" type="url" class="form-control" required>
</div>
<div class="mb-3">
<label for="longLivedAccessToken" class="form-label">{{ $t("Long-Lived Access Token") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="longLivedAccessToken" v-model="$parent.notification.longLivedAccessToken" type="text" class="form-control" required>
<div class="form-text">
<p>{{ $t("Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ") }}</p>
</div>
</div>
<div class="mb-3">
<label for="notificationService" class="form-label">{{ $t("Notification Service") }}</label>
<input id="notificationService" v-model="$parent.notification.notificationService" type="text" :placeholder="$t('default: notify all devices')" class="form-control">
<div class="form-text">
<p>{{ $t("A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.") }}</p>
<p>{{ $t("Automations can optionally be triggered in Home Assistant:") }}</p>
<p>
{{ $t("Trigger type:") }} <code>Event</code><br />
{{ $t("Event type:") }} <code>call_service</code><br />
{{ $t("Event data:") }}
</p>
<pre>domain: notify
service: mobile_app_my_phone # change to your device name
service_data:
title: Uptime Kuma
data:
status: 0 # 0=down 1=up
# name: Optional Uptime Kuma Monitor Name to filter by</pre>
<p>
{{ $t("Then choose an action, for example switch the scene to where an RGB light is red.") }}
</p>
</div>
</div>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<div class="mb-3">
<label for="line-notify-access-token" class="form-label">{{ $t("Access Token") }}</label>
<input id="line-notify-access-token" v-model="$parent.notification.lineNotifyAccessToken" type="text" class="form-control" :required="true">
</div>
<i18n-t tag="div" keypath="wayToGetLineNotifyToken" class="form-text" style="margin-top: 8px;">
<a href="https://notify-bot.line.me/" target="_blank">https://notify-bot.line.me/</a>
</i18n-t>
</template>

View File

@@ -11,15 +11,31 @@
<input id="ntfy-server-url" v-model="$parent.notification.ntfyserverurl" type="text" class="form-control" required>
</div>
</div>
<div class="mb-3">
<label for="ntfy-priority" class="form-label">{{ $t("Priority") }}</label>
<input id="ntfy-priority" v-model="$parent.notification.ntfyPriority" type="number" class="form-control" required min="1" max="5" step="1">
</div>
<div class="mb-3">
<label for="ntfy-username" class="form-label">{{ $t("Username") }} ({{ $t("Optional") }})</label>
<div class="input-group mb-3">
<input id="ntfy-username" v-model="$parent.notification.ntfyusername" type="text" class="form-control" required>
</div>
</div>
<div class="mb-3">
<label for="ntfy-password" class="form-label">{{ $t("Password") }} ({{ $t("Optional") }})</label>
<div class="input-group mb-3">
<HiddenInput id="ntfy-password" v-model="$parent.notification.ntfypassword" autocomplete="new-password"></HiddenInput>
</div>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
mounted() {
if (typeof this.$parent.notification.ntfyPriority === "undefined") {
this.$parent.notification.ntfyserverurl = "https://ntfy.sh";

View File

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

View File

@@ -0,0 +1,16 @@
<template>
<div class="mb-3">
<label for="serverchan-sendkey" class="form-label">{{ $t("SendKey") }}</label>
<HiddenInput id="serverchan-sendkey" v-model="$parent.notification.serverChanSendKey" :required="true" autocomplete="one-time-code"></HiddenInput>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

View File

@@ -0,0 +1,6 @@
<template>
<div class="mb-3">
<label for="webhook-url" class="form-label">{{ $t("Post URL") }}</label>
<input id="webhook-url" v-model="$parent.notification.squadcastWebhookURL" type="url" pattern="https?://.+" class="form-control" required>
</div>
</template>

View File

@@ -1,38 +1,45 @@
import STMP from "./SMTP.vue";
import Telegram from "./Telegram.vue";
import Alerta from "./Alerta.vue";
import AlertNow from "./AlertNow.vue";
import AliyunSMS from "./AliyunSms.vue";
import Apprise from "./Apprise.vue";
import Bark from "./Bark.vue";
import ClickSendSMS from "./ClickSendSMS.vue";
import DingDing from "./DingDing.vue";
import Discord from "./Discord.vue";
import Webhook from "./Webhook.vue";
import Signal from "./Signal.vue";
import Feishu from "./Feishu.vue";
import GoogleChat from "./GoogleChat.vue";
import Gorush from "./Gorush.vue";
import Gotify from "./Gotify.vue";
import HomeAssistant from "./HomeAssistant.vue";
import Line from "./Line.vue";
import LineNotify from "./LineNotify.vue";
import LunaSea from "./LunaSea.vue";
import Matrix from "./Matrix.vue";
import Mattermost from "./Mattermost.vue";
import Ntfy from "./Ntfy.vue";
import Slack from "./Slack.vue";
import RocketChat from "./RocketChat.vue";
import Teams from "./Teams.vue";
import Octopush from "./Octopush.vue";
import OneBot from "./OneBot.vue";
import PagerDuty from "./PagerDuty.vue";
import PromoSMS from "./PromoSMS.vue";
import Pushbullet from "./Pushbullet.vue";
import PushDeer from "./PushDeer.vue";
import Pushover from "./Pushover.vue";
import Pushy from "./Pushy.vue";
import TechulusPush from "./TechulusPush.vue";
import Octopush from "./Octopush.vue";
import PromoSMS from "./PromoSMS.vue";
import ClickSendSMS from "./ClickSendSMS.vue";
import LunaSea from "./LunaSea.vue";
import Feishu from "./Feishu.vue";
import Apprise from "./Apprise.vue";
import Pushbullet from "./Pushbullet.vue";
import Line from "./Line.vue";
import Mattermost from "./Mattermost.vue";
import Matrix from "./Matrix.vue";
import AliyunSMS from "./AliyunSms.vue";
import DingDing from "./DingDing.vue";
import Bark from "./Bark.vue";
import RocketChat from "./RocketChat.vue";
import ServerChan from "./ServerChan.vue";
import SerwerSMS from "./SerwerSMS.vue";
import Signal from "./Signal.vue";
import SMSManager from "./SMSManager.vue";
import Slack from "./Slack.vue";
import Squadcast from "./Squadcast.vue";
import Stackfield from "./Stackfield.vue";
import STMP from "./SMTP.vue";
import Teams from "./Teams.vue";
import TechulusPush from "./TechulusPush.vue";
import Telegram from "./Telegram.vue";
import Webhook from "./Webhook.vue";
import WeCom from "./WeCom.vue";
import GoogleChat from "./GoogleChat.vue";
import PagerDuty from "./PagerDuty.vue";
import Gorush from "./Gorush.vue";
import Alerta from "./Alerta.vue";
import OneBot from "./OneBot.vue";
import PushDeer from "./PushDeer.vue";
import GoAlert from "./GoAlert.vue";
/**
* Manage all notification form.
@@ -40,41 +47,48 @@ import PushDeer from "./PushDeer.vue";
* @type { Record<string, any> }
*/
const NotificationFormList = {
"telegram": Telegram,
"webhook": Webhook,
"smtp": STMP,
"discord": Discord,
"teams": Teams,
"signal": Signal,
"gotify": Gotify,
"ntfy": Ntfy,
"slack": Slack,
"rocket.chat": RocketChat,
"pushover": Pushover,
"pushy": Pushy,
"PushByTechulus": TechulusPush,
"octopush": Octopush,
"promosms": PromoSMS,
"clicksendsms": ClickSendSMS,
"lunasea": LunaSea,
"Feishu": Feishu,
"alerta": Alerta,
"AlertNow": AlertNow,
"AliyunSMS": AliyunSMS,
"apprise": Apprise,
"pushbullet": Pushbullet,
"line": Line,
"mattermost": Mattermost,
"matrix": Matrix,
"DingDing": DingDing,
"Bark": Bark,
"serwersms": SerwerSMS,
"stackfield": Stackfield,
"WeCom": WeCom,
"clicksendsms": ClickSendSMS,
"DingDing": DingDing,
"discord": Discord,
"Feishu": Feishu,
"GoogleChat": GoogleChat,
"PagerDuty": PagerDuty,
"gorush": Gorush,
"alerta": Alerta,
"gotify": Gotify,
"HomeAssistant": HomeAssistant,
"line": Line,
"LineNotify": LineNotify,
"lunasea": LunaSea,
"matrix": Matrix,
"mattermost": Mattermost,
"ntfy": Ntfy,
"octopush": Octopush,
"OneBot": OneBot,
"PagerDuty": PagerDuty,
"promosms": PromoSMS,
"pushbullet": Pushbullet,
"PushByTechulus": TechulusPush,
"PushDeer": PushDeer,
"pushover": Pushover,
"pushy": Pushy,
"rocket.chat": RocketChat,
"serwersms": SerwerSMS,
"signal": Signal,
"SMSManager": SMSManager,
"slack": Slack,
"squadcast": Squadcast,
"smtp": STMP,
"stackfield": Stackfield,
"teams": Teams,
"telegram": Telegram,
"webhook": Webhook,
"WeCom": WeCom,
"GoAlert": GoAlert,
"ServerChan": ServerChan,
};
export default NotificationFormList;

View File

@@ -4,6 +4,11 @@
<object class="my-4" width="200" height="200" data="/icon.svg" />
<div class="fs-4 fw-bold">Uptime Kuma</div>
<div>{{ $t("Version") }}: {{ $root.info.version }}</div>
<div class="frontend-version">{{ $t("Frontend Version") }}: {{ $root.frontendVersion }}</div>
<div v-if="!$root.isFrontendBackendVersionMatched" class="alert alert-warning mt-4" role="alert">
{{ $t("Frontend Version do not match backend version!") }}
</div>
<div class="my-3 update-link"><a href="https://github.com/louislam/uptime-kuma/releases" target="_blank" rel="noopener">{{ $t("Check Update On GitHub") }}</a></div>
@@ -46,6 +51,16 @@ export default {
}
.update-link {
font-size: 0.9em;
font-size: 0.8em;
}
.frontend-version {
font-size: 0.9em;
color: #cccccc;
.dark & {
color: #333333;
}
}
</style>

View File

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

View File

@@ -0,0 +1,48 @@
<template>
<div>
<div class="dockerHost-list my-4">
<p v-if="$root.dockerHostList.length === 0">
{{ $t("Not available, please setup.") }}
</p>
<ul class="list-group mb-3" style="border-radius: 1rem;">
<li v-for="(dockerHost, index) in $root.dockerHostList" :key="index" class="list-group-item">
{{ dockerHost.name }}<br>
<a href="#" @click="$refs.dockerHostDialog.show(dockerHost.id)">{{ $t("Edit") }}</a>
</li>
</ul>
<button class="btn btn-primary me-2" type="button" @click="$refs.dockerHostDialog.show()">
{{ $t("Setup Docker Host") }}
</button>
</div>
<DockerHostDialog ref="dockerHostDialog" />
</div>
</template>
<script>
import DockerHostDialog from "../../components/DockerHostDialog.vue";
export default {
components: {
DockerHostDialog,
},
data() {
return {};
},
computed: {
settings() {
return this.$parent.$parent.$parent.settings;
},
saveSettings() {
return this.$parent.$parent.$parent.saveSettings;
},
settingsLoaded() {
return this.$parent.$parent.$parent.settingsLoaded;
},
}
};
</script>

View File

@@ -91,6 +91,51 @@
{{ $t("For example: nginx, Apache and Traefik.") }} <br />
{{ $t("Please read") }} <a href="https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy" target="_blank">https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy</a>.
</div>
<h4 class="my-4">{{ $t("HTTP Headers") }}</h4>
<div class="my-3">
<label class="form-label">
{{ $t("Trust Proxy") }}
</label>
<div class="form-check">
<input
id="trustProxyYes"
v-model="settings.trustProxy"
class="form-check-input"
type="radio"
name="trustProxyYes"
:value="true"
required
/>
<label class="form-check-label" for="trustProxyYes">
{{ $t("Yes") }}
</label>
</div>
<div class="form-check">
<input
id="trustProxyNo"
v-model="settings.trustProxy"
class="form-check-input"
type="radio"
name="flexRadioDefault"
:value="false"
required
/>
<label class="form-check-label" for="trustProxyNo">
{{ $t("No") }}
</label>
</div>
<div class="form-text">
{{ $t("trustProxyDescription") }}
</div>
</div>
<div>
<button class="btn btn-primary" type="submit" @click="saveSettings()">
{{ $t("Save") }}
</button>
</div>
</div>
</template>
@@ -113,6 +158,12 @@ export default {
settings() {
return this.$parent.$parent.$parent.settings;
},
saveSettings() {
return this.$parent.$parent.$parent.saveSettings;
},
settingsLoaded() {
return this.$parent.$parent.$parent.settingsLoaded;
},
},
watch: {

View File

@@ -9,7 +9,9 @@ const languageList = {
"nl-NL": "Nederlands",
"nb-NO": "Norsk",
"es-ES": "Español",
"eu": "Euskara",
"fa": "Farsi",
"pt-PT": "Português (Portugal)",
"pt-BR": "Português (Brasileiro)",
"fr-FR": "Français (France)",
"hu": "Magyar",

View File

@@ -81,6 +81,7 @@ library.add(
faUndo,
faPlusCircle,
faAngleDown,
faLink,
);
export { FontAwesomeIcon };

View File

@@ -380,7 +380,7 @@ export default {
deleteProxyMsg: "Сигурни ли сте, че желаете да изтриете това прокси за всички монитори?",
proxyDescription: "За да функционират трябва да бъдат зададени към монитор.",
enableProxyDescription: "Това прокси няма да има ефект върху заявките за мониторинг, докато не бъде активирано. Може да контролирате временното деактивиране на проксито от всички монитори чрез статуса на активиране.",
setAsDefaultProxyDescription: "Това проки ще бъде включено по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
setAsDefaultProxyDescription: "Това прокси ще бъде включено по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
"Certificate Chain": "Верига на сертификата",
Valid: "Валиден",
Invalid: "Невалиден",
@@ -536,4 +536,50 @@ export default {
Domain: "Домейн",
Workstation: "Работна станция",
disableCloudflaredNoAuthMsg: "Тъй като сте в режим \"No Auth mode\", парола не се изисква.",
wayToGetLineNotifyToken: "Може да получите токен код за достъп от {0}",
resendEveryXTimes: "Изпращай повторно на всеки {0} пъти",
resendDisabled: "Повторното изпращане е изключено",
"Resend Notification if Down X times consequently": "Повторно изпращане на известие, ако е недостъпен X пъти последователно",
"Bark Group": "Bark група",
"Bark Sound": "Bark звук",
"HTTP Headers": "HTTP хедъри",
"Trust Proxy": "Trust Proxy",
HomeAssistant: "Home Assistant",
RadiusSecret: "Radius таен код",
RadiusSecretDescription: "Споделен таен код между клиент и сървър",
RadiusCalledStationId: "Повиквана станция ID",
RadiusCalledStationIdDescription: "Идентификатор на повикваното устройство",
RadiusCallingStationId: "Повикваща станция ID",
RadiusCallingStationIdDescription: "Идентификатор на повикващото устройство",
"Setup Docker Host": "Настройка на Docker хост",
"Connection Type": "Тип свързване",
"Docker Daemon": "Docker демон",
deleteDockerHostMsg: "Сигурни ли сте, че желаете да изтриете този Docker хост за всички монитори?",
socket: "Сокет",
tcp: "TCP / HTTP",
"Docker Container": "Docker контейнер",
"Container Name / ID": "Име на контейнер / ID",
"Docker Host": "Docker хост",
"Docker Hosts": "Docker хостове",
trustProxyDescription: "Trust 'X-Forwarded-*' headers. Ако искате да получавате правилния IP адрес на клиента, а Uptime Kuma е зад системи като Nginx или Apache, трябва да разрешите тази опция.",
Examples: "Примери",
"Home Assistant URL": "Home Assistant URL адрес",
"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 можете да създадете, като кликнете върху името на профила си (долу ляво) и превъртите до най-долу, след това кликнете върху Създаване на токен. ",
"Notification Service": "Услуга за известяване",
"default: notify all devices": "по подразбиране: извести всички устройства",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Списък с услугите за известяване може да бъде намерен в Home Assistant под \"Developer Tools > Services\", там потърсете \"notification\", за да намерите името на вашето устройство/телефон.",
"Automations can optionally be triggered in Home Assistant:": "Автоматизациите могат да се задействат при нужда в Home Assistant:",
"Trigger type:": "Задействане тип:",
"Event type:": "Събитие тип:",
"Event data:": "Събитие данни:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "След което изберете действие, например да превключите сцената, където RGB светлината е червена.",
"Frontend Version": "Фронтенд версия",
"Frontend Version do not match backend version!": "Фронтенд версията не съвпада с Бекенд версията!",
"Base URL": "Базов URL адрес",
goAlertInfo: "GoAlert е приложение с отворен код за планиране на повиквания, автоматизирани ескалации и известия (като SMS или гласови повиквания). Автоматично ангажирайте точния човек, по точния начин и в точното време! {0}",
goAlertIntegrationKeyInfo: "Вземете общ API интеграционен ключ за услугата във формат \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" обикновено стойността на параметъра token на копирания URL адрес.",
goAlert: "GoAlert",
backupOutdatedWarning: "Отпаднало: Тъй като са добавени много функции, тази опция за архивиране не е достатъчно поддържана и не може да генерира или възстанови пълен архив.",
backupRecommend: "Моля, архивирайте дяла или папката (./data/) директно вместо това.",
};

View File

@@ -2,18 +2,21 @@ export default {
languageName: "Czech",
checkEverySecond: "Kontrolovat každých {0} sekund",
retryCheckEverySecond: "Opakovat každých {0} sekund",
resendEveryXTimes: "Znovu zaslat {0}krát",
resendDisabled: "Opakované zasílání je vypnuté",
retriesDescription: "Maximální počet pokusů před označením služby jako nedostupné a odesláním oznámení",
ignoreTLSError: "Ignorovat TLS/SSL chyby na HTTPS stránkách",
upsideDownModeDescription: "Pomocí této možnosti změníte způsob vyhodnocování stavu. Pokud je služba dosažitelná, je NEDOSTUPNÁ.",
maxRedirectDescription: "Maximální počet přesměrování, která se mají následovat. Nastavením hodnoty 0 zakážete přesměrování.",
acceptedStatusCodesDescription: "Vyberte stavové kódy, které jsou považovány za úspěšnou odpověď.",
passwordNotMatchMsg: "Hesla se neshodují",
notificationDescription: "Pro zajištění funkčnosti oznámení je nutné je přiřadit dohledu.",
notificationDescription: "Pro zajištění funkčnosti oznámení je nutné jej přiřadit dohledu.",
keywordDescription: "Vyhledat klíčové slovo v prosté odpovědi HTML nebo JSON. Při hledání se rozlišuje velikost písmen.",
pauseDashboardHome: "Pozastavit",
deleteMonitorMsg: "Opravdu chcete odstranit tento dohled?",
deleteNotificationMsg: "Opravdu chcete odstranit toto oznámení pro všechny dohledy?",
resolverserverDescription: "Cloudflare je výchozí server. Resolver server můžete kdykoli změnit.",
dnsPortDescription: "Port DNS serveru. Standardně běží na portu 53. V případě potřeby jej můžete kdykoli změnit.",
resolverserverDescription: "Cloudflare je výchozí server. V případě potřeby můžete Resolver server kdykoli změnit.",
rrtypeDescription: "Vyberte typ záznamu o prostředku, který chcete monitorovat",
pauseMonitorMsg: "Opravdu chcete dohled pozastavit?",
enableDefaultNotificationDescription: "Toto oznámení bude standardně aktivní pro nové dohledy. V případě potřeby můžete oznámení stále zakázat na úrovni jednotlivých dohledů.",
@@ -44,10 +47,10 @@ export default {
Down: "Nedostupný",
Pending: "Čekám",
Unknown: "Neznámý",
Pause: "Pozastavit",
Pause: "Pozastaveno",
Name: "Název",
Status: "Stav",
DateTime: "DateTime",
DateTime: "Časové razítko",
Message: "Zpráva",
"No important events": "Žádné důležité události",
Resume: "Pokračovat",
@@ -70,10 +73,11 @@ export default {
Port: "Port",
"Heartbeat Interval": "Heartbeat interval",
Retries: "Počet pokusů",
"Heartbeat Retry Interval": "Interval opakování prezenčního signálu",
"Heartbeat Retry Interval": "Interval opakování heartbeatu",
"Resend Notification if Down X times consequently": "Znovu zaslat oznámení, pokud je služba nedostupná Xkrát za sebou",
Advanced: "Rozšířené",
"Upside Down Mode": "Inverzní režim",
"Max. Redirects": "Max. Přesměrování",
"Max. Redirects": "Max. přesměrování",
"Accepted Status Codes": "Akceptované stavové kódy",
"Push URL": "Push URL",
needPushEvery: "Tuto URL adresu byste měli volat každých {0} sekund.",
@@ -103,7 +107,7 @@ export default {
"disableauth.message1": "Opravdu chcete <strong>deaktivovat autentifikaci</strong>?",
"disableauth.message2": "Tato možnost je určena pro případy, kdy <strong>máte autentifikaci zajištěnou třetí stranou</strong> ještě před přístupem do Uptime Kuma, například prostřednictvím Cloudflare Access.",
"Please use this option carefully!": "Používejte ji prosím s rozmyslem.",
Logout: "Odhlášení",
Logout: "Odhlásit",
Leave: "Odejít",
"I understand, please disable": "Rozumím, chci ji deaktivovat",
Confirm: "Potvrzení",
@@ -128,7 +132,7 @@ export default {
"Export Backup": "Exportovat zálohu",
Export: "Exportovat",
Import: "Importovat",
respTime: "Odezva Čas (ms)",
respTime: "Doba odezvy (ms)",
notAvailableShort: "N/A",
"Default enabled": "Standardně povoleno",
"Apply on all existing monitors": "Použít pro všechny existující dohledy",
@@ -195,7 +199,7 @@ export default {
"Chat ID": "ID chatu",
supportTelegramChatID: "Podpora přímého chatu / skupiny / ID chatu kanálu",
wayToGetTelegramChatID: "ID chatu můžete získat tak, že robotovi zašlete zprávu a přejdete na tuto adresu URL, kde zobrazíte chat_id:",
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
"YOUR BOT TOKEN HERE": "SEM ZADEJTE TOKEN VAŠEHO CHATBOTA",
chatIDNotFound: "ID chatu nebylo nalezeno; nejprve tomuto robotovi zašlete zprávu",
webhook: "Webhook",
"Post URL": "URL adresa příspěvku",
@@ -241,6 +245,7 @@ export default {
"rocket.chat": "Rocket.Chat",
pushover: "Pushover",
pushy: "Pushy",
PushByTechulus: "Push by Techulus",
octopush: "Octopush",
promosms: "PromoSMS",
clicksendsms: "ClickSend SMS",
@@ -301,15 +306,19 @@ export default {
Body: "Tělo",
Headers: "Hlavičky",
PushUrl: "Push URL",
HeadersInvalidFormat: "The request headers are not valid JSON: ",
BodyInvalidFormat: "The request body is not valid JSON: ",
HeadersInvalidFormat: "Hlaviča žádosti není platný JSON: ",
BodyInvalidFormat: "Text žádosti není platný JSON: ",
"Monitor History": "Historie dohledu",
clearDataOlderThan: "Historie dohledu bude uchovávána po dobu {0} dní.",
PasswordsDoNotMatch: "Hesla se neshodují.",
records: "záznamů",
"One record": "Jeden záznam",
steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ",
steamApiKeyDescription: "Pro monitorování Steam Game Serveru je nutné zadat Steam Web-API klíč. Svůj API klíč získáte na následující stránce: ",
"Current User": "Aktuálně přihlášený uživatel",
topic: "Topic",
topicExplanation: "MQTT topic, který chcete sledovat",
successMessage: "Zpráva o úspěchu",
successMessageExplanation: "MQTT zpráva považovaná za úspěšnou",
recent: "Poslední",
Done: "Hotovo",
Info: "Informace",
@@ -318,7 +327,7 @@ export default {
"Shrink Database": "Zmenšit databázi",
"Pick a RR-Type...": "Vyberte typ záznamu o prostředku…",
"Pick Accepted Status Codes...": "Vyberte stavové kódy, které chcete akceptovat…",
Default: "Standardní",
Default: "Výchozí",
"HTTP Options": "Možnosti protokolu HTTP",
"Create Incident": "Vytvořit incident",
Title: "Předmět",
@@ -327,6 +336,8 @@ export default {
info: "informace",
warning: "upozornění",
danger: "riziko",
error: "chyba",
critical: "kritické",
primary: "primární",
light: "světlý",
dark: "tmavý",
@@ -336,7 +347,7 @@ export default {
"Last Updated": "Poslední aktualizace",
Unpin: "Odepnout",
"Switch to Light Theme": "Přepnout na světlý motiv",
"Switch to Dark Theme": "Přepnutí na tmavý motiv",
"Switch to Dark Theme": "Přepnout na tmavý motiv",
"Show Tags": "Zobrazit štítky",
"Hide Tags": "Skrýt štítky",
Description: "Popis",
@@ -355,13 +366,220 @@ export default {
serwersmsPhoneNumber: "Telefonní číslo",
serwersmsSenderName: "Odesílatel SMS (registrováno prostřednictvím zákaznického portálu)",
"stackfield": "Stackfield",
Customize: "Přizpůsobit",
"Custom Footer": "Vlastní patička",
"Custom CSS": "Vlastní CSS",
smtpDkimSettings: "Nastavení DKIM",
smtpDkimDesc: "Informace o použití naleznete v {0} Nodemailer DKIM.",
documentation: "dokumentaci",
smtpDkimDomain: "Název domény",
smtpDkimKeySelector: "Selector klíče",
smtpDkimKeySelector: "Selektor klíče",
smtpDkimPrivateKey: "Privátní klíč",
smtpDkimHashAlgo: "Hashovací algoritmus (volitelné)",
smtpDkimheaderFieldNames: "Podepisovat tyto hlavičky (volitelné)",
smtpDkimskipFields: "Nepodepisovat tyto hlavičky (volitelné)",
wayToGetPagerDutyKey: "Získat jej můžete v sekci Service -> Service Directory -> (vyberte službu) -> Integrations -> Add integration. Následně vyhledejte \"Events API V2\". Více informace naleznete na adrese {0}",
"Integration Key": "Integration Key",
"Integration URL": "Integration URL",
"Auto resolve or acknowledged": "Auto resolve or acknowledged",
"do nothing": "do nothing",
"auto acknowledged": "auto acknowledged",
"auto resolve": "auto resolve",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "API Endpoint",
alertaEnvironment: "Prostředí",
alertaApiKey: "API Key",
alertaAlertState: "Stav upozornění",
alertaRecoverState: "Stav obnovení",
deleteStatusPageMsg: "Opravdu chcete odstranit tuto stavovou stránku?",
Proxies: "Proxy",
default: "Výchozí",
enabled: "Zapnuto",
setAsDefault: "Nastavit jako výchozí",
deleteProxyMsg: "Opravdu chcete odstranit tuto proxy ze všech dohledů?",
proxyDescription: "Pro zajištění funkčnosti musí být proxy přiřazena dohledům.",
enableProxyDescription: "Tato proxy neovlivní žádosti dohledu do doby, než ji aktivujete. Změnou tohoto nastavení dočasně zakážete použití proxy ve všech dohledech.",
setAsDefaultProxyDescription: "Tato proxy se použije pro všechny nové dohledy. V případě potřeby můžete její využívání zakázat v konkrétním dohledu.",
"Certificate Chain": "Řetězec certifikátu",
Valid: "Platný",
Invalid: "Neplatný",
AccessKeyId: "AccessKey ID",
SecretAccessKey: "AccessKey Secret",
PhoneNumbers: "PhoneNumbers",
TemplateCode: "TemplateCode",
SignName: "SignName",
"Sms template must contain parameters: ": "Sms template must contain parameters: ",
"Bark Endpoint": "Bark Endpoint",
"Bark Group": "Bark Group",
"Bark Sound": "Bark Sound",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "Z důvodu bezpečnosti použijte secret key",
"Device Token": "Token zařízení",
Platform: "Platforma",
iOS: "iOS",
Android: "Android",
Huawei: "Huawei",
High: "Vysoký",
Retry: "Opakovat",
Topic: "Topic",
"WeCom Bot Key": "WeCom Bot Key",
"Setup Proxy": "Nastavit proxy",
"Proxy Protocol": "Protokol proxy",
"Proxy Server": "Proxy Server",
"Proxy server has authentication": "Proxy server vyžaduje ověření",
User: "Uživatel",
Installed: "Nainstalováno",
"Not installed": "Nenainstalováno",
Running: "Běží",
"Not running": "Neběží",
"Remove Token": "Odstranit token",
Start: "Spustit",
Stop: "Zastavit",
"Uptime Kuma": "Uptime Kuma",
"Add New Status Page": "Přidat novou stavovou stránku",
Slug: "Slug",
"Accept characters:": "Přípustné znaky:",
startOrEndWithOnly: "Počáteční a koncový znak může být pouze {0}",
"No consecutive dashes": "Nesmí se opakovat pomlčky",
Next: "Další",
"The slug is already taken. Please choose another slug.": "Slug s tímto názvem již existuje. Prosím, zadejte jiný název.",
"No Proxy": "Žádná proxy",
Authentication: "Ověření",
"HTTP Basic Auth": "HTTP Basic ověření",
"New Status Page": "Nová stavová stránka",
"Page Not Found": "Stránka nenalezena",
"Reverse Proxy": "Reverzní proxy",
Backup: "Záloha",
About: "O programu",
wayToGetCloudflaredURL: "(Stáhnout cloudflared z {0})",
cloudflareWebsite: "Webová stránka Cloudflare",
"Message:": "Zpráva:",
"Don't know how to get the token? Please read the guide:": "Nevíte jak získat? Prosím, přečtěte si tuto příručku:",
"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.": "Stávající připojení mohlo být ztraceno, pokud jste připojeni prostřednictvím Cloudflare tunelu. Opravdu jej chcete zastavit? Pro potvrzení zadejte své současné heslo.",
"HTTP Headers": "HTTP hlavičky",
"Trust Proxy": "Důvěryhodná proxy",
"Other Software": "Jiný software",
"For example: nginx, Apache and Traefik.": "Například nginx, Apache nebo Traefik.",
"Please read": "Prosím, přečtěte si informace na adrese",
"Subject:": "Předmět:",
"Valid To:": "Platnost do:",
"Days Remaining:": "Počet zbývajících dní:",
"Issuer:": "Vydavatel:",
"Fingerprint:": "Otisk:",
"No status pages": "Žádná stavová stránka",
"Domain Name Expiry Notification": "Oznámení na blížící se konec platnosti doménového jména",
Proxy: "Proxy",
"Date Created": "Datum vytvoření",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP adresa",
onebotMessageType: "Typ OneBot zprávy",
onebotGroupMessage: "Skupinová",
onebotPrivateMessage: "Soukromá",
onebotUserOrGroupId: "ID skupiny/uživatele",
onebotSafetyTips: "Z důvodu bezpečnosti je nutné zadat přístupový token",
"PushDeer Key": "PushDeer klíč",
"Footer Text": "Text v patičce",
"Show Powered By": "Zobrazit \"Poskytuje\"",
"Domain Names": "Názvy domén",
signedInDisp: "Přihlášen jako {0}",
signedInDispDisabled: "Ověření je vypnuté.",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "Sdílený tajný klíč mezi klientem a serverem",
RadiusCalledStationId: "ID volaného zařízení",
RadiusCalledStationIdDescription: "Identifikátor volaného zařízení",
RadiusCallingStationId: "ID volajícího zařízení",
RadiusCallingStationIdDescription: "Identifikátor volajícího zařízení",
"Certificate Expiry Notification": "Oznámení na blížící se konec platnosti certifikátu",
"API Username": "API Username",
"API Key": "API Key",
"Recipient Number": "Číslo příjemce",
"From Name/Number": "Jméno/číslo odesílatele",
"Leave blank to use a shared sender number.": "Ponechte prázdné, pokud chcete použít číslo sdíleného příjemce.",
"Octopush API Version": "Octopush API verze",
"Legacy Octopush-DM": "Legacy Octopush-DM",
endpoint: "endpoint",
octopushAPIKey: "\"API key\" ze sekce HTTP API credentials na nástěnce",
octopushLogin: "\"Login\" ze sekce HTTP API credentials na nástěnce",
promosmsLogin: "API Login Name",
promosmsPassword: "API Password",
"pushoversounds pushover": "Pushover (výchozí)",
"pushoversounds bike": "Bike",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic",
"pushoversounds falling": "Falling",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magic",
"pushoversounds mechanical": "Mechanical",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Siren",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (dlouhý)",
"pushoversounds climb": "Climb (dlouhý)",
"pushoversounds persistent": "Persistent (dlouhý)",
"pushoversounds echo": "Pushover Echo (dlouhý)",
"pushoversounds updown": "Up Down (dlouhý)",
"pushoversounds vibrate": "Pouze vibrace",
"pushoversounds none": "Žádný (ticho)",
pushyAPIKey: "Secret API Key",
pushyToken: "Token zařízení",
"Show update if available": "Upozornit na aktualizace, pokud jsou k dispozici",
"Also check beta release": "Kontrolovat také dostupnost beta verzí",
"Using a Reverse Proxy?": "Používáte reverzní proxy?",
"Check how to config it for WebSocket": "Zjistěte, jak ji nakonfigurovat pro WebSockety",
"Steam Game Server": "Steam Game Server",
"Most likely causes:": "Nejčastější důvody:",
"The resource is no longer available.": "Zdroj již není k dispozici.",
"There might be a typing error in the address.": "Při zadávání adresy jste udělali chybu.",
"What you can try:": "Co můžete vyzkoušet:",
"Retype the address.": "Znovu zadat adresu.",
"Go back to the previous page.": "Vrátit se na předchozí stránku.",
"Coming Soon": "Připravujeme",
wayToGetClickSendSMSToken: "API Username a API Key získáte na adrese {0} .",
"Connection String": "Connection String",
Query: "Dotaz",
settingsCertificateExpiry: "Platnost TLS certifikátu",
certificationExpiryDescription: "Aktivovat oznámení nad HTTPS dohledy, pokud platnost TLS certifikátu vyprší za:",
"Setup Docker Host": "Nastavit Docker hostitele",
"Connection Type": "Typ připojení",
"Docker Daemon": "Docker Daemon",
deleteDockerHostMsg: "Opravdu chcete odstranit tohoto docker hostitele ze všech dohledů?",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker kontejner",
"Container Name / ID": "ID / název kontejneru",
"Docker Host": "Docker hostitel",
"Docker Hosts": "Docker hostitelé",
"ntfy Topic": "ntfy Topic",
"Domain": "Doména",
"Workstation": "Pracovní stanice",
disableCloudflaredNoAuthMsg: "Používáte režim bez ověření, heslo není vyžadováno.",
trustProxyDescription: "Důvěřovat 'X-Forwarded-*' hlavičkám. Pokud chcete získat správnou IP adresu klientů a vaše instance Uptime Kuma je schována za Nginx nebo Apache, měli byste tuto možnost zapnout.",
wayToGetLineNotifyToken: "Přístupový token můžete získat na adrese {0}",
Examples: "Příklady",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token": "Dlouhodobý přístupový 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. ": "Pro vytvoření dlouhodobého přístupový tokenu klikněte na název svého profilu (v levém dolním rohu) a následně v dolní části stránky klikněte na tlačítko Create Token. ",
"Notification Service": "Oznamovací služba",
"default: notify all devices": "výchozí: upozornit všechny zařízení",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Seznam dostupných oznamovacích služeb naleznete v Home Assistant v sekci \"Developer Tools > Services\", kde vyhledejte \"notification\" pro zjištění názvu zařízení.",
"Automations can optionally be triggered in Home Assistant:": "Automatizaci můžete volitelně aktivovat prostřednictvím Home Assistant:",
"Trigger type:": "Typ podmínky spuštění:",
"Event type:": "Typ události:",
"Event data:": "Data události:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Následně vyberte akci, například přepnutí scény z RGB světla na červenou.",
"Frontend Version": "Verze frontendu",
"Frontend Version do not match backend version!": "Verze frontendu neodpovídá verzi backendu!",
"Base URL": "Primární URL adresa",
goAlertInfo: "GoAlert je aplikace s otevřeným zdrojovým kódem pro plánování hovorů, automatické eskalace a upozornění (jako jsou SMS nebo hlasové hovory). Automaticky zapojte správnou osobu, správným způsobem a ve správný čas! {0}",
goAlertIntegrationKeyInfo: "Obecný API integrační klíč pro danou službu ve formátu \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" se obvykle nachází ve zkopírované URL jako hodnota parametru token.",
goAlert: "GoAlert",
backupOutdatedWarning: "Zastaralé: V poslední době byla funkčnost aplikace značně rozšířena, nicméně součást pro zálohování nepokrývá všechny možnosti. Z tohoto důvodu není možné vygenerovat úplnou zálohu a zajistit obnovení všech dat.",
backupRecommend: "Prosím, zálohujte si ručně celý svazek nebo datovou složku (./data/).",
};

View File

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

View File

@@ -2,6 +2,8 @@ export default {
languageName: "English",
checkEverySecond: "Check every {0} seconds",
retryCheckEverySecond: "Retry every {0} seconds",
resendEveryXTimes: "Resend every {0} times",
resendDisabled: "Resend disabled",
retriesDescription: "Maximum retries before the service is marked as down and a notification is sent",
ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites",
upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.",
@@ -72,6 +74,7 @@ export default {
"Heartbeat Interval": "Heartbeat Interval",
Retries: "Retries",
"Heartbeat Retry Interval": "Heartbeat Retry Interval",
"Resend Notification if Down X times consequently": "Resend Notification if Down X times consequently",
Advanced: "Advanced",
"Upside Down Mode": "Upside Down Mode",
"Max. Redirects": "Max. Redirects",
@@ -408,6 +411,8 @@ export default {
SignName: "SignName",
"Sms template must contain parameters: ": "Sms template must contain parameters: ",
"Bark Endpoint": "Bark Endpoint",
"Bark Group": "Bark Group",
"Bark Sound": "Bark Sound",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "For safety, must use secret key",
@@ -453,6 +458,8 @@ export default {
"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:",
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.",
"HTTP Headers": "HTTP Headers",
"Trust Proxy": "Trust Proxy",
"Other Software": "Other Software",
"For example: nginx, Apache and Traefik.": "For example: nginx, Apache and Traefik.",
"Please read": "Please read",
@@ -465,6 +472,7 @@ export default {
"Domain Name Expiry Notification": "Domain Name Expiry Notification",
Proxy: "Proxy",
"Date Created": "Date Created",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP Address",
onebotMessageType: "OneBot Message Type",
onebotGroupMessage: "Group",
@@ -477,6 +485,12 @@ export default {
"Domain Names": "Domain Names",
signedInDisp: "Signed in as {0}",
signedInDispDisabled: "Auth Disabled.",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "Shared Secret between client and server",
RadiusCalledStationId: "Called Station Id",
RadiusCalledStationIdDescription: "Identifier of the called device",
RadiusCallingStationId: "Calling Station Id",
RadiusCallingStationIdDescription: "Identifier of the calling device",
"Certificate Expiry Notification": "Certificate Expiry Notification",
"API Username": "API Username",
"API Key": "API Key",
@@ -485,7 +499,7 @@ export default {
"Leave blank to use a shared sender number.": "Leave blank to use a shared sender number.",
"Octopush API Version": "Octopush API Version",
"Legacy Octopush-DM": "Legacy Octopush-DM",
"endpoint": "endpoint",
endpoint: "endpoint",
octopushAPIKey: "\"API key\" from HTTP API credentials in control panel",
octopushLogin: "\"Login\" from HTTP API credentials in control panel",
promosmsLogin: "API Login Name",
@@ -529,11 +543,45 @@ export default {
"Coming Soon": "Coming Soon",
wayToGetClickSendSMSToken: "You can get API Username and API Key from {0} .",
"Connection String": "Connection String",
"Query": "Query",
Query: "Query",
settingsCertificateExpiry: "TLS Certificate Expiry",
certificationExpiryDescription: "HTTPS Monitors trigger notification when TLS certificate expires in:",
"Setup Docker Host": "Setup Docker Host",
"Connection Type": "Connection Type",
"Docker Daemon": "Docker Daemon",
deleteDockerHostMsg: "Are you sure want to delete this docker host for all monitors?",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker Container",
"Container Name / ID": "Container Name / ID",
"Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Topic",
"Domain": "Domain",
"Workstation": "Workstation",
disableCloudflaredNoAuthMsg: "You are in No Auth mode, password is not require.",
Domain: "Domain",
Workstation: "Workstation",
disableCloudflaredNoAuthMsg: "You are in No Auth mode, a password is not required.",
trustProxyDescription: "Trust 'X-Forwarded-*' headers. If you want to get the correct client IP and your Uptime Kuma is behind such as Nginx or Apache, you should enable this.",
wayToGetLineNotifyToken: "You can get an access token from {0}",
Examples: "Examples",
"Home Assistant URL": "Home Assistant URL",
"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. ",
"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.": "A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.",
"Automations can optionally be triggered in Home Assistant:": "Automations can optionally be triggered in Home Assistant:",
"Trigger type:": "Trigger type:",
"Event type:": "Event type:",
"Event data:": "Event data:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Then choose an action, for example switch the scene to where an RGB light is red.",
"Frontend Version": "Frontend Version",
"Frontend Version do not match backend version!": "Frontend Version do not match backend version!",
"Base URL": "Base URL",
goAlertInfo: "GoAlert is a An open source application for on-call scheduling, automated escalations and notifications (like SMS or voice calls). Automatically engage the right person, the right way, and at the right time! {0}",
goAlertIntegrationKeyInfo: "Get generic API integration key for the service in this format \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\" usually the value of token parameter of copied URL.",
goAlert: "GoAlert",
backupOutdatedWarning: "Deprecated: Since a lot of features added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.",
backupRecommend: "Please backup the volume or the data folder (./data/) directly instead.",
"Optional": "Optional",
squadcast: "Squadcast",
};

View File

@@ -7,8 +7,8 @@ export default {
maxRedirectDescription: "Número máximo de direcciones a seguir. Establecer a 0 para deshabilitar.",
acceptedStatusCodesDescription: "Seleccionar los códigos de estado que se consideran como respuesta exitosa.",
passwordNotMatchMsg: "La contraseña repetida no coincide.",
notificationDescription: "Por favor asigne una notificación a el/los monitor(es) para hacerlos funcional(es).",
keywordDescription: "Palabra clave en HTML plano o respuesta JSON y es sensible a mayúsculas",
notificationDescription: "Por favor asigna una notificación a el/los monitor(es) para hacerlos funcional(es).",
keywordDescription: "Palabra clave en HTML plano o respuesta JSON, es sensible a mayúsculas",
pauseDashboardHome: "Pausado",
deleteMonitorMsg: "¿Seguro que quieres eliminar este monitor?",
deleteNotificationMsg: "¿Seguro que quieres eliminar esta notificación para todos los monitores?",
@@ -35,7 +35,7 @@ export default {
Pause: "Pausar",
Name: "Nombre",
Status: "Estado",
DateTime: "Fecha y Hora",
DateTime: "Fecha y hora",
Message: "Mensaje",
"No important events": "No hay eventos importantes",
Resume: "Reanudar",
@@ -50,7 +50,7 @@ export default {
"-hour": "-hora",
Response: "Respuesta",
Ping: "Ping",
"Monitor Type": "Tipo de Monitor",
"Monitor Type": "Tipo de monitor",
Keyword: "Palabra clave",
"Friendly Name": "Nombre sencillo",
URL: "URL",
@@ -60,11 +60,11 @@ export default {
Retries: "Reintentos",
Advanced: "Avanzado",
"Upside Down Mode": "Modo invertido",
"Max. Redirects": "Redirecciones Máximas",
"Max. Redirects": "Redirecciones máximas",
"Accepted Status Codes": "Códigos de estado aceptados",
Save: "Guardar",
Notifications: "Notificaciones",
"Not available, please setup.": "No disponible, por favor configúrelo.",
"Not available, please setup.": "No disponible, por favor configúralo.",
"Setup Notification": "Configurar notificación",
Light: "Claro",
Dark: "Oscuro",
@@ -82,8 +82,8 @@ export default {
"New Password": "Nueva contraseña",
"Repeat New Password": "Repetir nueva contraseña",
"Update Password": "Actualizar contraseña",
"Disable Auth": "Deshabilitar Autenticación",
"Enable Auth": "Habilitar Autenticación",
"Disable Auth": "Deshabilitar autenticación",
"Enable Auth": "Habilitar autenticación",
"disableauth.message1": "Seguro que deseas <strong>deshabilitar la autenticación</strong>?",
"disableauth.message2": "Es para <strong>quien implementa autenticación de terceros</strong> ante Uptime Kuma como por ejemplo Cloudflare Access.",
"Please use this option carefully!": "Por favor usar con cuidado.",
@@ -104,32 +104,32 @@ export default {
Test: "Test",
"Certificate Info": "Información del certificado",
"Resolver Server": "Servidor de resolución",
"Resource Record Type": "Tipo de Registro",
"Resource Record Type": "Tipo de registro",
"Last Result": "Último resultado",
"Create your admin account": "Crea tu cuenta de administrador",
"Repeat Password": "Repetir contraseña",
respTime: "Tiempo de resp. (ms)",
notAvailableShort: "N/A",
Create: "Crear",
clearEventsMsg: "¿Está seguro de que desea eliminar todos los eventos de este monitor?",
clearHeartbeatsMsg: "¿Está seguro de que desea eliminar todos los latidos de este monitor?",
confirmClearStatisticsMsg: "¿Está seguro de que desea eliminar TODAS las estadísticas?",
"Clear Data": "Borrar Datos",
clearEventsMsg: "¿Estás seguro de que deseas eliminar todos los eventos de este monitor?",
clearHeartbeatsMsg: "¿Estás seguro de que deseas eliminar todos los latidos de este monitor?",
confirmClearStatisticsMsg: "¿Estás seguro de que deseas eliminar TODAS las estadísticas?",
"Clear Data": "Borrar datos",
Events: "Eventos",
Heartbeats: "Latidos",
"Auto Get": "Obtener automáticamente",
enableDefaultNotificationDescription: "Para cada nuevo monitor, esta notificación estará habilitada de forma predeterminada. Aún puede deshabilitar la notificación por separado para cada monitor.",
enableDefaultNotificationDescription: "Para cada nuevo monitor, esta notificación estará habilitada de forma predeterminada. Aún puedes deshabilitar la notificación por separado para cada monitor.",
"Default enabled": "Habilitado por defecto",
"Also apply to existing monitors": "También se aplica a monitores existentes",
Export: "Exportar",
Import: "Importar",
backupDescription: "Puede hacer una copia de seguridad de todos los monitores y todas las notificaciones en un archivo JSON.",
backupDescription: "Puedes hacer una copia de seguridad de todos los monitores y todas las notificaciones en un archivo JSON.",
backupDescription2: "PD: el historial y los datos de eventos no están incluidos.",
backupDescription3: "Los datos confidenciales, como los tokens de notificación, se incluyen en el archivo de exportación. Guárdelo con cuidado.",
alertNoFile: "Seleccione un archivo para importar.",
alertWrongFileType: "Seleccione un archivo JSON.",
twoFAVerifyLabel: "Ingrese su token para verificar que 2FA está funcionando",
tokenValidSettingsMsg: "¡El token es válido! Ahora puede guardar la configuración de 2FA.",
backupDescription3: "Los datos confidenciales, como los tokens de notificación, se incluyen en el archivo de exportación. Guárdalo con cuidado.",
alertNoFile: "Selecciona un archivo para importar.",
alertWrongFileType: "Selecciona un archivo JSON.",
twoFAVerifyLabel: "Ingresa tu token para verificar que 2FA está funcionando",
tokenValidSettingsMsg: "¡El token es válido! Ahora puedes guardar la configuración de 2FA.",
confirmEnableTwoFAMsg: "¿Estás seguro de que quieres habilitar 2FA?",
confirmDisableTwoFAMsg: "¿Estás seguro de que quieres desactivar 2FA?",
"Apply on all existing monitors": "Aplicar en todos los monitores existentes",
@@ -145,19 +145,19 @@ export default {
"Show URI": "Mostrar URI",
"Clear all statistics": "Borrar todas las estadísticas",
retryCheckEverySecond: "Reintentar cada {0} segundo.",
importHandleDescription: "Elija 'Omitir existente' si desea omitir todos los monitores o notificaciones con el mismo nombre. 'Sobrescribir' eliminará todos los monitores y notificaciones existentes.",
confirmImportMsg: "¿Estás seguro de importar la copia de seguridad? Asegúrese de haber seleccionado la opción de importación correcta.",
importHandleDescription: "Elige 'Omitir existente' si deseas omitir todos los monitores o notificaciones con el mismo nombre. 'Sobrescribir' eliminará todos los monitores y notificaciones existentes.",
confirmImportMsg: "¿Estás seguro de importar la copia de seguridad? Asegúrate de haber seleccionado la opción de importación correcta.",
"Heartbeat Retry Interval": "Intervalo de reintento de latido",
"Import Backup": "Importar copia de seguridad",
"Export Backup": "Exportar copia de seguridad",
"Skip existing": "Omitir existente",
Overwrite: "Sobrescribir",
Options: "Opciones",
"Keep both": "Mantén ambos",
"Keep both": "Manténer ambos",
Tags: "Etiquetas",
"Add New below or Select...": "Agregar nuevo a continuación o Seleccionar...",
"Tag with this name already exist.": "La etiqueta con este nombre ya existe.",
"Tag with this value already exist.": "La etiqueta con este valor ya existe.",
"Add New below or Select...": "Agregar nuevo a continuación o seleccionar...",
"Tag with this name already exist.": "Una etiqueta con este nombre ya existe.",
"Tag with this value already exist.": "Una etiqueta con este valor ya existe.",
color: "color",
"value (optional)": "valor (opcional)",
Gray: "Gris",
@@ -172,17 +172,17 @@ export default {
"Avg. Ping": "Ping promedio",
"Avg. Response": "Respuesta promedio",
"Entry Page": "Página de entrada",
statusPageNothing: "No hay nada aquí, agregue un grupo o un monitor.",
statusPageNothing: "No hay nada aquí, agrega un grupo o un monitor.",
"No Services": "Sin servicio",
"All Systems Operational": "Todos los sistemas están operativos",
"Partially Degraded Service": "Servicio parcialmente degradado",
"Degraded Service": "Servicio degradado",
"Add Group": "Agregar Grupo",
"Add Group": "Agregar grupo",
"Add a monitor": "Agregar un monitor",
"Edit Status Page": "Editar página de estado",
"Go to Dashboard": "Ir al panel de control",
"Status Page": "Página de estado",
"Status Pages": "Página de estado",
"Status Pages": "Páginas de estado",
telegram: "Telegram",
webhook: "Webhook",
smtp: "Email (SMTP)",
@@ -205,5 +205,5 @@ export default {
clearDataOlderThan: "Mantener los datos del historial del monitor durante {0} días.",
records: "registros",
"One record": "Un registro",
steamApiKeyDescription: "Para monitorear un servidor de juegos de Steam, necesita una clave Steam Web-API. Puede registrar su clave API aquí: ",
steamApiKeyDescription: "Para monitorear un servidor de juegos de Steam, necesitas una clave Steam Web-API. Puedes registrar tu clave API aquí: ",
};

539
src/languages/eu.js Normal file
View File

@@ -0,0 +1,539 @@
export default {
languageName: "Euskara",
checkEverySecond: "Egiaztatu {0} segunduro",
retryCheckEverySecond: "Errepikatu {0} segunduro",
retriesDescription: "Zerbitzua erorita markatu eta jakinarazpena bidali aurretik egindako saiakera kopuru maximoa",
ignoreTLSError: "Ezikusiarena egin TLS/SSL erroreei HTTPS webguneetan",
upsideDownModeDescription: "Alderantzizkatu erortze egoera. Zerbitzua martxan badago, ERORITA markatuko du.",
maxRedirectDescription: "Jarraitu beharreko berbideratze kopuru maximoa. Jarri 0 berbideratzeak desgaitzeko.",
acceptedStatusCodesDescription: "Hautatu erantzun ona kontsideratzen diren egoera kodeak.",
passwordNotMatchMsg: "Errepikatutako pasahitza ez dator bat.",
notificationDescription: "Jakinarazpenak monitorizazio funtzio bati asignatu behar zaizkio.",
keywordDescription: "Bilatu gako-hitza HTML edo JSON erantzunean. Bilaketan maiuskulak kontuan hartzen dira.",
pauseDashboardHome: "Gelditu",
deleteMonitorMsg: "Ziur zaude monitorizazio hau ezabatu nahi duzula?",
deleteNotificationMsg: "Ziur zaude jakinarazpen hau monitorizazio guztientzat ezabatu nahi duzula?",
dnsPortDescription: "DNS zerbitzari portua. Defektuz 53. Nahi duzunean aldatu dezakezu portua.",
resolverserverDescription: "Cloudflare zerbitzari lehenetsia da. Edozein unetan alda dezakezu ebazteko zerbitzaria.",
rrtypeDescription: "Hautatu kontrolatu nahi duzun RR mota",
enableDefaultNotificationDescription: "Jakinarazpen hau monitore berrientzat gaituko da defektuz. Baina monitorizazio bakoitzarentzat jakinarazpena desgaitu dezakezu.",
pauseMonitorMsg: "Ziur zaude gelditu egin nahi duzula?",
clearEventsMsg: "Ziur zaude monitorizazio honen gertaera guztiak ezabatu nahi dituzula?",
clearHeartbeatsMsg: "Ziur zaude monitorizazio honen pultsu guztiak ezabatu nahi dituzula?",
confirmClearStatisticsMsg: "Ziur zaude estatistika GUZTIAK ezabatu nahi dituzula?",
importHandleDescription: "Aukeratu 'existitzen bada', izen bereko monitore edo jakinarazpen bakoitza saltatu nahi baduzu. Lehendik dauden kontrol eta jakinarazpen guztiak ezabatuko ditu 'Gainidatzi' aukerak.",
confirmImportMsg: "Ziur zaude segurtasun-kopia inportatu nahi duzula? Egiaztatu inportatzeko aukera zuzena hautatu duzula.",
twoFAVerifyLabel: "Sartu zure tokena 2FA egiaztatzeko:",
tokenValidSettingsMsg: "Tokenak balio du! Orain 2FA konfigurazioa gorde dezakezu.",
confirmEnableTwoFAMsg: "Ziur zaude 2FA gaitu nahi duzula?",
confirmDisableTwoFAMsg: "Ziur zaude 2FA desgaitu nahi duzula?",
Settings: "Ezarpenak",
Dashboard: "Arbela",
"New Update": "Eguneraketa berria",
Language: "Hizkuntza",
Appearance: "Itxura",
Theme: "Gaia",
General: "Orokorra",
"Primary Base URL": "Oinarrizkoa URL",
Version: "Bertsioa",
"Check Update On GitHub": "Egiaztatu eguneraketa GitHuben",
List: "Zerrenda",
Add: "Gehitu",
"Add New Monitor": "Gehitu monitorizazio berria",
"Quick Stats": "Estatistika azkarrak",
Up: "Erabilgarri",
Down: "Erorita",
Pending: "Zain",
Unknown: "Ezezaguna",
Pause: "Gelditu",
Name: "Izena",
Status: "Egoera",
DateTime: "Data eta ordua",
Message: "Mezua",
"No important events": "Gertaera garrantzitsurik ez",
Resume: "Jarraitu",
Edit: "Editatu",
Delete: "Ezabatu",
Current: "Unekoa",
Uptime: "Martxan",
"Cert Exp.": "Ziurtagiri iraun.",
day: "egun | egun",
"-day": "-egun",
hour: "ordua",
"-hour": "-ordu",
Response: "Erantzuna",
Ping: "Ping",
"Monitor Type": "Monitorizazio mota",
Keyword: "Gakohitza",
"Friendly Name": "Izen xumea",
URL: "URLa",
Hostname: "Ostalari izena",
Port: "Portua",
"Heartbeat Interval": "Pultsu interbaloak",
Retries: "Errepikapenak",
"Heartbeat Retry Interval": "Pultsu errepikatze interbaloak",
Advanced: "Aurreratua",
"Upside Down Mode": "Alderantzizkako modua",
"Max. Redirects": "Berbideratze max.",
"Accepted Status Codes": "Onartutako egoera kodeak",
"Push URL": "Push URLa",
needPushEvery: "URL hau {0} segunduro deitu beharko zenuke.",
pushOptionalParams: "Hautazko parametroak: {0}",
Save: "Gorde",
Notifications: "Jakinarazpenak",
"Not available, please setup.": "Ez dago eskuragarri, ezarri mesedez.",
"Setup Notification": "Ezarri jakinarazpenak",
Light: "Argia",
Dark: "Iluna",
Auto: "Auto",
"Theme - Heartbeat Bar": "Gaia - Pultsu barra",
Normal: "Normala",
Bottom: "Behean",
None: "Bat ere ez",
Timezone: "Timezone",
"Search Engine Visibility": "Bilatzaile ikurgarritasuna",
"Allow indexing": "Onartu indexatzea",
"Discourage search engines from indexing site": "Discourage search engines from indexing site",
"Change Password": "Aldatu pasahitza",
"Current Password": "Uneko pasahitza",
"New Password": "Pasahitz berria",
"Repeat New Password": "Errepikatu pasahitz berria",
"Update Password": "Eguneratu pasahitza",
"Disable Auth": "Desgaitu Auth",
"Enable Auth": "Gaitu Auth",
"disableauth.message1": "Ziur zaude <strong>autentifikazioa desgaitu</strong> nahi duzula?",
"disableauth.message2": "Egoera jakin batzuetarako diseinatuta dago, Uptime Kumaren <strong>aurrean hirugarrengo autentifikazio batzuek jartzeko</strong> (Cloudflare Access, Authelia edo beste autentifikazio-mekanismo batzuk).",
"Please use this option carefully!": "Mesedez, kontuz erabili aukera hau!",
Logout: "Saioa amaitu",
Leave: "Utzi",
"I understand, please disable": "Ulertzen dut, mesedez desgaitu",
Confirm: "Baieztatu",
Yes: "Bai",
No: "Ez",
Username: "Erabiltzailea",
Password: "Pasahitza",
"Remember me": "Gogora nazazu",
Login: "Saioa hasi",
"No Monitors, please": "Monitorizaziorik ez, mesedez",
"add one": "gehitu bat",
"Notification Type": "Jakinarazpen mota",
Email: "Emaila",
Test: "Testa",
"Certificate Info": "Ziurtagiri informazioa",
"Resolver Server": "Ebazpen-zerbitzaria",
"Resource Record Type": "Baliabideen erregistro mota",
"Last Result": "Azken emaitza",
"Create your admin account": "Sortu zure admin kontua",
"Repeat Password": "Errepikatu pasahitza",
"Import Backup": "segurtasun-kopia inportatu",
"Export Backup": "segurtasun-kopia esportatu",
Export: "Esportatu",
Import: "Inportatu",
respTime: "Erantz. denbora (ms)",
notAvailableShort: "N/A",
"Default enabled": "Lehenetsia gaituta",
"Apply on all existing monitors": "Aplikatu existitzen diren monitorizazio guztietan",
Create: "Sortu",
"Clear Data": "Garbitu datuak",
Events: "Gertaerak",
Heartbeats: "Pultsuak",
"Auto Get": "Auto Get",
backupDescription: "Monitore eta jakinarazpen guztien segurtasun-kopiak egin ditzakezu JSON fitxategi batean.",
backupDescription2: "Oharra: ez dira historia eta gertaeren datuak sartzen.",
backupDescription3: "Datu sentikorrak, hala nola jakinarazpen tokenak, esportazio-fitxategian sartzen dira; mesedez, gorde esportazioa modu seguruan.",
alertNoFile: "Mesedez hautatu inportatzeko fitxategia.",
alertWrongFileType: "Mesedez hautatu JSON fitxategia.",
"Clear all statistics": "Garbitu estatistika guztiak",
"Skip existing": "Saltatu existitzen bada",
Overwrite: "Gainidatzi",
Options: "Aukerak",
"Keep both": "Biak mantendu",
"Verify Token": "Egiaztatu Tokena",
"Setup 2FA": "Ezarri 2FA",
"Enable 2FA": "Gaitu 2FA",
"Disable 2FA": "Desgaitu 2FA",
"2FA Settings": "2FA ezarpenak",
"Two Factor Authentication": "Bi aldetako autentifikazioa (2FA)",
Active: "Aktibo",
Inactive: "Inaktibo",
Token: "Tokena",
"Show URI": "Erakutsi URIa",
Tags: "Etiketak",
"Add New below or Select...": "Gehitu beste bat behean edo hautatu...",
"Tag with this name already exist.": "Izen hau duen etiketa dagoeneko badago.",
"Tag with this value already exist.": "Balio hau duen etiketa dagoeneko badago.",
color: "kolorea",
"value (optional)": "balioa (hautazkoa)",
Gray: "Grisa",
Red: "Gorria",
Orange: "Naranja",
Green: "Berdea",
Blue: "Urdina",
Indigo: "Indigo",
Purple: "Morea",
Pink: "Arrosa",
"Search...": "Bilatu...",
"Avg. Ping": "Batazbesteko Pinga",
"Avg. Response": "Batazbesteko erantzuna",
"Entry Page": "Sarrera orria",
statusPageNothing: "Ezer ere ez hemen, mesedez gehitu taldea edo monitorizazioa.",
"No Services": "Zerbitzurik ez",
"All Systems Operational": "Sistema guztiak martxan",
"Partially Degraded Service": "Zerbitzu partzialki degradatua",
"Degraded Service": "Zerbitzu degradatua",
"Add Group": "Gehitu taldea",
"Add a monitor": "Gehitu monitorizazioa",
"Edit Status Page": "Editatu egoera orria",
"Go to Dashboard": "Joan arbelera",
"Status Page": "Egoera orria",
"Status Pages": "Egoera orriak",
defaultNotificationName: "Nire {notification} Alerta ({number})",
here: "Hemen",
Required: "Beharrezkoa",
telegram: "Telegram",
"Bot Token": "Bot Tokena",
wayToGetTelegramToken: "You can get a token from {0}.",
"Chat ID": "Txat IDa",
supportTelegramChatID: "Support Direct Chat / Group / Channel's Chat ID",
wayToGetTelegramChatID: "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
chatIDNotFound: "Chat ID is not found; please send a message to this bot first",
webhook: "Webhook",
"Post URL": "Bidalketa URLa",
"Content Type": "Eduki mota",
webhookJsonDesc: "{0} is good for any modern HTTP servers such as Express.js",
webhookFormDataDesc: "{multipart} is good for PHP. The JSON will need to be parsed with {decodeFunction}",
smtp: "Emaila (SMTP)",
secureOptionNone: "Bat ere ez / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignore TLS Error",
"From Email": "Email honetatik",
emailCustomSubject: "Pertsonalizatutako gaia",
"To Email": "Email honetara",
smtpCC: "CC",
smtpBCC: "BCC",
discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "You can get this by going to Server Settings -> Integrations -> Create Webhook",
"Bot Display Name": "Bot Display Name",
"Prefix Custom Message": "Prefix Custom Message",
"Hello @everyone is...": "Hello {'@'}everyone is...",
teams: "Microsoft Teams",
"Webhook URL": "Webhook URL",
wayToGetTeamsURL: "You can learn how to create a webhook URL {0}.",
signal: "Signal",
Number: "Zenbakia",
Recipients: "Recipients",
needSignalAPI: "You need to have a signal client with REST API.",
wayToCheckSignalURL: "You can check this URL to view how to set one up:",
signalImportant: "IMPORTANT: You cannot mix groups and numbers in recipients!",
gotify: "Gotify",
"Application Token": "Aplikazio tokena",
"Server URL": "Zerbitzari URLa",
Priority: "Lehentasuna",
slack: "Slack",
"Icon Emoji": "Emoji ikonoa",
"Channel Name": "Kanalaren izena",
"Uptime Kuma URL": "Uptime Kuma URL",
aboutWebhooks: "More info about Webhooks on: {0}",
aboutChannelName: "Enter the channel name on {0} Channel Name field if you want to bypass the Webhook channel. Ex: #other-channel",
aboutKumaURL: "If you leave the Uptime Kuma URL field blank, it will default to the Project GitHub page.",
emojiCheatSheet: "Emoji cheat sheet: {0}",
"rocket.chat": "Rocket.Chat",
pushover: "Pushover",
pushy: "Pushy",
PushByTechulus: "Push by Techulus",
octopush: "Octopush",
promosms: "PromoSMS",
clicksendsms: "ClickSend SMS",
lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)",
GoogleChat: "Google Chat (Google Workspace only)",
pushbullet: "Pushbullet",
line: "Line Messenger",
mattermost: "Mattermost",
"User Key": "Erabiltzaile gakoa",
Device: "Gailua",
"Message Title": "Mezuaren izenburua",
"Notification Sound": "Jakinarazpen soinua",
"More info on:": "More info on: {0}",
pushoverDesc1: "Emergency priority (2) has default 30 second timeout between retries and will expire after 1 hour.",
pushoverDesc2: "If you want to send notifications to different devices, fill out Device field.",
"SMS Type": "SMS mota",
octopushTypePremium: "Premium (Fast - recommended for alerting)",
octopushTypeLowCost: "Low Cost (Slow - sometimes blocked by operator)",
checkPrice: "Check {0} prices:",
apiCredentials: "API credentials",
octopushLegacyHint: "Do you use the legacy version of Octopush (2011-2020) or the new version?",
"Check octopush prices": "Check octopush prices {0}.",
octopushPhoneNumber: "Phone number (intl format, eg : +33612345678) ",
octopushSMSSender: "SMS Sender Name : 3-11 alphanumeric characters and space (a-zA-Z0-9)",
"LunaSea Device ID": "LunaSea Device ID",
"Apprise URL": "Apprise URL",
"Example:": "Adibidez: {0}",
"Read more:": "Irakurri gehiago: {0}",
"Status:": "Egoera: {0}",
"Read more": "Irakurri gehiago",
appriseInstalled: "Apprise instalatuta.",
appriseNotInstalled: "Apprise ez dago instalatuta. {0}",
"Access Token": "Access Token",
"Channel access token": "Channel access token",
"Line Developers Console": "Line Developers Console",
lineDevConsoleTo: "Line Developers Console - {0}",
"Basic Settings": "Oinarrizko ezarpenak",
"User ID": "Erabiltzaile ID",
"Messaging API": "Messaging API",
wayToGetLineChannelToken: "First access the {0}, create a provider and channel (Messaging API), then you can get the channel access token and user ID from the above mentioned menu items.",
"Icon URL": "Ikono URL",
aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.",
aboutMattermostChannelName: "You can override the default channel that the Webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in the Mattermost Webhook settings. Ex: #other-channel",
matrix: "Matrix",
promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.",
promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.",
promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use your Sender Name (You need to register name first). Reliable for alerts.",
promosmsTypeSpeed: "SMS SPEED - Highest priority in system. Very quick and reliable but costly (about twice of SMS FULL price).",
promosmsPhoneNumber: "Phone number (for Polish recipient You can skip area codes)",
promosmsSMSSender: "SMS Sender Name : Pre-registred name or one of defaults: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "Feishu WebHookURL",
matrixHomeserverURL: "Hasiera zerbitzari URL (with http(s):// and optionally port)",
"Internal Room Id": "Internal Room ID",
matrixDesc1: "You can find the internal room ID by looking in the advanced section of the room settings in your Matrix client. It should look like !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "It is highly recommended you create a new user and do not use your own Matrix user's access token as it will allow full access to your account and all the rooms you joined. Instead, create a new user and only invite it to the room that you want to receive the notification in. You can get the access token by running {0}",
Method: "Metodoa",
Body: "Gorputza",
Headers: "Goiburuak",
PushUrl: "Push URL",
HeadersInvalidFormat: "The request headers are not valid JSON: ",
BodyInvalidFormat: "The request body is not valid JSON: ",
"Monitor History": "Monitorizazio Historia",
clearDataOlderThan: "Keep monitor history data for {0} days.",
PasswordsDoNotMatch: "Pasahitzak ez datoz bat.",
records: "records",
"One record": "One record",
steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ",
"Current User": "Uneko erabiltzailea",
topic: "Topic",
topicExplanation: "MQTT topic to monitor",
successMessage: "Arrakasta mezua",
successMessageExplanation: "MQTT message that will be considered as success",
recent: "Duela gutxikoa",
Done: "Egina",
Info: "Info",
Security: "Segurtasuna",
"Steam API Key": "Steam API Giltza",
"Shrink Database": "Shrink Datubasea",
"Pick a RR-Type...": "Pick a RR-Type...",
"Pick Accepted Status Codes...": "Hautatu onartutako egoera kodeak...",
Default: "Lehenetsia",
"HTTP Options": "HTTP Aukerak",
"Create Incident": "Sortu inzidentzia",
Title: "Titulua",
Content: "Edukia",
Style: "Estiloa",
info: "info",
warning: "kontuz",
danger: "arriskua",
error: "errorea",
critical: "kritikoa",
primary: "oinarrizkoa",
light: "argia",
dark: "iluna",
Post: "Post",
"Please input title and content": "Mesedez sartu titulua eta edukia",
Created: "Sortuta",
"Last Updated": "Azken eguneratzea",
Unpin: "Unpin",
"Switch to Light Theme": "Aldatu gai argira",
"Switch to Dark Theme": "Aldatu gai ilunera",
"Show Tags": "Erakutsi etiketak",
"Hide Tags": "Ezkutatu etiketak",
Description: "Deskribapena",
"No monitors available.": "Monitorizaziorik eskuragarri ez.",
"Add one": "Gehitu bat",
"No Monitors": "Monitorizaziorik ez",
"Untitled Group": "Titulurik gabeko taldea",
Services: "Zerbitzuak",
Discard: "Baztertu",
Cancel: "Ezeztatu",
"Powered by": "Honekin egina:",
shrinkDatabaseDescription: "Trigger database VACUUM for SQLite. If your database is created after 1.10.0, AUTO_VACUUM is already enabled and this action is not needed.",
serwersms: "SerwerSMS.pl",
serwersmsAPIUser: "API erabiltzailea (webapi_ aurre-hizkia barne)",
serwersmsAPIPassword: "API pasahitza",
serwersmsPhoneNumber: "Telefono zenbakia",
serwersmsSenderName: "SMS bidaltzaile izena (registered via customer portal)",
stackfield: "Stackfield",
Customize: "Pertsonalizatu",
"Custom Footer": "Oin pertsonalizatua",
"Custom CSS": "CSS pertsonalizatua",
smtpDkimSettings: "DKIM ezarpenak",
smtpDkimDesc: "Please refer to the Nodemailer DKIM {0} for usage.",
documentation: "dokumentazioa",
smtpDkimDomain: "Domeinu izena",
smtpDkimKeySelector: "Gako hautatzailea",
smtpDkimPrivateKey: "Gako pribatua",
smtpDkimHashAlgo: "Hash algoritmoa (hautazkoa)",
smtpDkimheaderFieldNames: "Header Keys to sign (Optional)",
smtpDkimskipFields: "Header Keys not to sign (Optional)",
wayToGetPagerDutyKey: "You can get this by going to Service -> Service Directory -> (Select a service) -> Integrations -> Add integration. Here you can search for \"Events API V2\". More info {0}",
"Integration Key": "Integration Key",
"Integration URL": "Integrazio URLa",
"Auto resolve or acknowledged": "Auto resolve or acknowledged",
"do nothing": "ez egin ezer",
"auto acknowledged": "auto acknowledged",
"auto resolve": "auto resolve",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "API Endpoint",
alertaEnvironment: "Ingurunea",
alertaApiKey: "API Key",
alertaAlertState: "Alerta egoera",
alertaRecoverState: "Berreskuratze egoera",
deleteStatusPageMsg: "Ziur zaude egoera orri hau ezabatu nahi duzula?",
Proxies: "Proxiak",
default: "Lehenetsia",
enabled: "Gaituta",
setAsDefault: "Ezarri lehenetsitzat",
deleteProxyMsg: "Are you sure want to delete this proxy for all monitors?",
proxyDescription: "Proxies must be assigned to a monitor to function.",
enableProxyDescription: "This proxy will not effect on monitor requests until it is activated. You can control temporarily disable the proxy from all monitors by activation status.",
setAsDefaultProxyDescription: "This proxy will be enabled by default for new monitors. You can still disable the proxy separately for each monitor.",
"Certificate Chain": "Certificate Chain",
Valid: "Baliozkoa",
Invalid: "Baliogabea",
AccessKeyId: "AccessKey ID",
SecretAccessKey: "AccessKey Secret",
PhoneNumbers: "TelefonoZenbakiak",
TemplateCode: "TemplateCode",
SignName: "SignName",
"Sms template must contain parameters: ": "Sms txantiloiak parametroak eduki behar ditu: ",
"Bark Endpoint": "Bark Endpoint",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "For safety, must use secret key",
"Device Token": "Gailu tokena",
Platform: "Plataforma",
iOS: "iOS",
Android: "Android",
Huawei: "Huawei",
High: "Altua",
Retry: "Errepikatu",
Topic: "Gaia",
"WeCom Bot Key": "WeCom Bot Key",
"Setup Proxy": "Ezarri Proxya",
"Proxy Protocol": "Proxy protokoloa",
"Proxy Server": "Proxy zerbitzaria",
"Proxy server has authentication": "Proxy zerbitzariak autentifikazioa dauka",
User: "Erabiltzailea",
Installed: "Instalatuta",
"Not installed": "Instalatu gabe",
Running: "Martxan",
"Not running": "Ez martxan",
"Remove Token": "Ezabatu Tokena",
Start: "Hasi",
Stop: "Gelditu",
"Uptime Kuma": "Uptime Kuma",
"Add New Status Page": "Gehitu egoera orri berria",
Slug: "Sluga",
"Accept characters:": "Onartu karaktereak:",
startOrEndWithOnly: "Start or end with {0} only",
"No consecutive dashes": "No consecutive dashes",
Next: "Hurrengoa",
"The slug is already taken. Please choose another slug.": "Sluga dagoeneko hartuta dago. Mesedez beste bat hautatu.",
"No Proxy": "Proxyrik ez",
Authentication: "Authentication",
"HTTP Basic Auth": "HTTP oinarrizko Auth",
"New Status Page": "Egoera orri berria",
"Page Not Found": "Orria ez da aurkitu",
"Reverse Proxy": "Alderantzizkako Proxya",
Backup: "Backup",
About: "Honi buruz",
wayToGetCloudflaredURL: "(Download cloudflared from {0})",
cloudflareWebsite: "Cloudflare webgunea",
"Message:": "Mezua:",
"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.",
"Other Software": "Beste softwarea",
"For example: nginx, Apache and Traefik.": "Adibidez: nginx, Apache and Traefik.",
"Please read": "Mesedez irakurri",
"Subject:": "Gaia:",
"Valid To:": "Balio-epea:",
"Days Remaining:": "Egun faltan:",
"Issuer:": "Issuer:",
"Fingerprint:": "Hatzmarka:",
"No status pages": "Egoera orririk ez",
"Domain Name Expiry Notification": "Domeinu izen iraungitze jakinarazpena",
Proxy: "Proxya",
"Date Created": "Data sortuta",
onebotHttpAddress: "OneBot HTTP helbidea",
onebotMessageType: "OneBot mezu mota",
onebotGroupMessage: "Taldea",
onebotPrivateMessage: "Pribatua",
onebotUserOrGroupId: "Talde/Erabiltzaile IDa",
onebotSafetyTips: "For safety, must set access token",
"PushDeer Key": "PushDeer Key",
"Footer Text": "Oineko testua",
"Show Powered By": "Erakutsi Honekin egina:",
"Domain Names": "Domeinu izenak",
signedInDisp: "Signed in as {0}",
signedInDispDisabled: "Auth desgaituta.",
"Certificate Expiry Notification": "Zertifikatu iraungitze jakinarazpena",
"API Username": "API Erabiltzailea",
"API Key": "API Gakoa",
"Recipient Number": "Recipient Number",
"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": "Octopush API Version",
"Legacy Octopush-DM": "Legacy Octopush-DM",
endpoint: "endpoint",
octopushAPIKey: "\"API key\" from HTTP API credentials in control panel",
octopushLogin: "\"Login\" from HTTP API credentials in control panel",
promosmsLogin: "API Saio haste izena",
promosmsPassword: "API Pasahitza",
"pushoversounds pushover": "Pushover (defektuz)",
"pushoversounds bike": "Bizikleta",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds classical": "Klasikoa",
"pushoversounds cosmic": "Kosmikoa",
"pushoversounds falling": "Erortzen",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magia",
"pushoversounds mechanical": "Mekanikoa",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Sirena",
"pushoversounds spacealarm": "Espazio Alarma",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (long)",
"pushoversounds climb": "Climb (long)",
"pushoversounds persistent": "Persistent (long)",
"pushoversounds echo": "Pushover Echo (long)",
"pushoversounds updown": "Up Down (long)",
"pushoversounds vibrate": "Bibrazioa soilik",
"pushoversounds none": "Bat ere ez (isilik)",
pushyAPIKey: "Secret API giltza",
pushyToken: "Gailu tokena",
"Show update if available": "Erakutsi eguneratzea eskuragarri badago",
"Also check beta release": "Beta bertsioak ere egiaztatu",
"Using a Reverse Proxy?": "Proxy alderantzizkako zerbitzaria erabiltzen?",
"Check how to config it for WebSocket": "Check how to config it for WebSocket",
"Steam Game Server": "Steam joko zerbitzaria",
"Most likely causes:": "Arrazoi probableenak:",
"The resource is no longer available.": "Baliabidea ez dago erabilgarri.",
"There might be a typing error in the address.": "Idazketa-akats bat egon daiteke helbidean.",
"What you can try:": "Probatu dezakezuna:",
"Retype the address.": "Berridatzi helbidea.",
"Go back to the previous page.": "Itzuli aurreko orrialdera",
"Coming Soon": "Laster",
wayToGetClickSendSMSToken: "API erabiltzailea and API giltza hemendik lortu ditzakezu: {0} .",
"Connection String": "Konexio katea",
Query: "Kontsulta",
settingsCertificateExpiry: "TLS irungitze zertifikatua",
certificationExpiryDescription: "HTTPS Monitorizazio jakinarazpena martxan jarri TLS zertifikatua iraungitzeko hau falta denean:",
"ntfy Topic": "ntfy Topic",
Domain: "Domeinua",
Workstation: "Lan gunea",
disableCloudflaredNoAuthMsg: "Ez Auth moduan zaude, pasahitza ez da beharrezkoa.",
};

View File

@@ -177,8 +177,16 @@ export default {
"Add a monitor": "Ajouter une sonde",
"Edit Status Page": "Modifier la page de statut",
"Go to Dashboard": "Accéder au tableau de bord",
"Status Page": "Status Page",
"Status Pages": "Status Pages",
"Status Page": "Page de statut",
"Status Pages": "Pages de statut",
"New Status Page": "Ajouter page de statut",
"Add New Status Page": "Ajouter une page de statut",
"No status pages": "Aucune page de statut.",
"Accept characters:": "Caractères acceptés:",
startOrEndWithOnly: "Commence uniquement par {0}",
"No consecutive dashes": "Pas de double tirets",
Next: "Continuer",
"Setup Proxy": "Configuer Proxy",
defaultNotificationName: "Ma notification {notification} numéro ({number})",
here: "ici",
Required: "Requis",
@@ -236,7 +244,7 @@ export default {
octopush: "Octopush",
promosms: "PromoSMS",
lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)",
apprise: "Apprise (Prend en charge plus de 50 services de notification)",
pushbullet: "Pushbullet",
line: "Line Messenger",
mattermost: "Mattermost",
@@ -261,7 +269,7 @@ export default {
"Read more": "En savoir plus",
appriseInstalled: "Apprise est installé.",
appriseNotInstalled: "Apprise n'est pas installé. {0}",
"Access Token": "Access Token",
"Access Token": "Token d'accès",
"Channel access token": "Token d'accès au canal",
"Line Developers Console": "Ligne console de développeurs",
lineDevConsoleTo: "Ligne console de développeurs - {0}",
@@ -309,4 +317,118 @@ export default {
alertaApiKey: "Clé de l'API",
alertaAlertState: "État de l'Alerte",
alertaRecoverState: "État de récupération",
resendEveryXTimes: "Renvoyez toutes les {0} fois",
resendDisabled: "Renvoi désactivé",
dnsPortDescription: "Port du serveur DNS. La valeur par défaut est 53. Vous pouvez modifier le port à tout moment.",
"Resend Notification if Down X times consequently": "Renvoyer la notification a partir d'un certain temps",
"Push URL": "Push URL",
needPushEvery: "Vous devez appeler cette URL toutes les {0} secondes.",
pushOptionalParams: "parametres optionnels: {0}",
"disableauth.message1": "Voulez-vous vraiment <strong>désactiver l'authentification</strong>?",
"disableauth.message2": "Il est conçu pour les scénarios <strong>où vous avez l'intention d'implémenter une authentification tierce</strong> devant Uptime Kuma, comme Cloudflare Access, Authelia ou d'autres mécanismes d'authentification.",
"Please use this option carefully!": "Veuillez utiliser cette option avec précaution !",
PushByTechulus: "Pousser par Techulus",
GoogleChat: "Google Chat (Google Workspace uniquement)",
Done: "Fait",
Info: "Info",
Security: "Sécurité",
"Steam API Key": "Clé API Steam",
"Shrink Database": "Réduire la base de données",
"Pick a RR-Type...": "Pick a RR-Type...",
"Pick Accepted Status Codes...": "Pick Accepted Status Codes...",
Default: "Défaut",
"HTTP Options": "HTTP Options",
"Create Incident": "Créer un incident",
Title: "Titre",
Content: "Contenu",
Style: "Style",
info: "info",
warning: "Attention",
danger: "danger",
error: "Erreur",
critical: "critique",
primary: "primaire",
light: "blanc",
dark: "Noir",
Post: "Post",
"Please input title and content": "Veuillez entrer le titre et le contenu",
Created: "Created",
"Last Updated": "Dernière mise à jour",
Unpin: "Détacher",
"Switch to Light Theme": "Passer au thème clair",
"Switch to Dark Theme": "Passer au thème sombre",
"Show Tags": "Voir les étiquettes",
"Hide Tags": "Masquer les étiquettes",
Description: "Description",
"No monitors available.": "Aucun moniteur disponible.",
"Add one": "En rajouter un",
"No Monitors": "Aucun moniteur",
"Untitled Group": "Groupe sans titre",
Services: "Services",
Discard: "Annuler",
Cancel: "Annuler",
shrinkDatabaseDescription: "Déclencher la base de données VACUUM pour SQLite. Si votre base de données est créée après 1.10.0, AUTO_VACUUM est déjà activé et cette action n'est pas nécessaire.",
serwersmsAPIUser: "Nom d'utilisateur de l'API (incl. webapi_ prefix)",
serwersmsAPIPassword: "Mot de passe API",
serwersmsPhoneNumber: "Numéro de téléphone",
serwersmsSenderName: "Nom de l'expéditeur du SMS (enregistré via le portail client)",
Customize: "Personnaliser",
"Custom Footer": "Pied de page personnalisé",
"Custom CSS": "CSS personnalisé",
deleteStatusPageMsg: "Voulez-vous vraiment supprimer cette page d'état ?",
Proxies: "Proxies",
default: "Défaut",
enabled: "Activé",
setAsDefault: "Définir par défaut",
deleteProxyMsg: "Voulez-vous vraiment supprimer ce proxy pour tous les moniteurs ?",
proxyDescription: "Les proxys doivent être affectés à un moniteur pour fonctionner.",
enableProxyDescription: "Ce proxy n'aura pas d'effet sur les demandes de moniteur tant qu'il n'est pas activé. Vous pouvez contrôler la désactivation temporaire du proxy de tous les moniteurs en fonction de l'état d'activation.",
setAsDefaultProxyDescription: "Ce proxy sera activé par défaut pour les nouveaux moniteurs. Vous pouvez toujours désactiver le proxy séparément pour chaque moniteur.",
Valid: "Valide",
Invalid: "Non valide",
User: "Utilisateur",
Installed: "Installé",
"Not installed": "Pas installé",
"Remove Token": "Supprimer le jeton",
Slug: "chemin",
"The slug is already taken. Please choose another slug.": "Le chemin est déjà pris. Veuillez choisir un autre chemin.",
Authentication: "Authentication",
"Page Not Found": "Page non trouvée",
Backup: "Sauvegarde",
About: "À propos de",
"Footer Text": "Texte de pied de page",
"Domain Names": "Noms de domaine",
signedInDisp: "Connecté en tant que {0}",
signedInDispDisabled: "Authentification désactivée.",
"Show update if available": "Afficher la mise à jour si disponible",
"Also check beta release": "Vérifiez également la version bêta",
"Steam Game Server": "Serveur de jeu Steam",
"Most likely causes:": "Causes les plus probables:",
"The resource is no longer available.": "La ressource n'est plus disponible.",
"There might be a typing error in the address.": "Il se peut qu'il y ait une erreur de frappe dans l'adresse.",
"What you can try:": "Ce que vous pouvez essayer:",
"Retype the address.": "Retapez l'adresse.",
"Go back to the previous page.": "Retournez à la page précédente.",
"Coming Soon": "À venir",
settingsCertificateExpiry: "Expiration du certificat TLS",
certificationExpiryDescription: "Les moniteurs HTTPS déclenchent une notification lorsque le certificat TLS expire dans:",
"Setup Docker Host": "Configurer l'hôte Docker",
"Connection Type": "Type de connexion",
deleteDockerHostMsg: "Voulez-vous vraiment supprimer cet hôte Docker pour tous les moniteurs ?",
"Container Name / ID": "Nom / ID du conteneur",
"Docker Host": "Hôte Docker",
"Docker Hosts": "Hôtes Docker",
Domain: "Domaine",
trustProxyDescription: "Faire confiance aux en-têtes 'X-Forwarded-*'. Si vous souhaitez obtenir la bonne adresse IP client et que votre Uptime Kuma est en retard, comme Nginx ou Apache, vous devez l'activer.",
wayToGetLineNotifyToken: "Vous pouvez obtenir un jeton d'accès auprès de {0}",
Examples: "Exemples",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Un jeton d'accès de longue durée peut être créé en cliquant sur le nom de votre profil (en bas à gauche) et en faisant défiler vers le bas, puis cliquez sur Créer un jeton. ",
"Notification Service": "Service de notifications",
"default: notify all devices": "par défaut: notifier tous les appareils",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Une liste des services de notification peut être trouvée dans Home Assistant sous \"Outils de développement > Services\" recherchez \"notification\" pour trouver le nom de votre appareil/téléphone.",
"Automations can optionally be triggered in Home Assistant:": "Les automatisations peuvent éventuellement être déclenchées dans Home Assistant:",
"Trigger type:": "Type de déclencheur:",
"Event type:": "Type d'événement:",
"Event data:": "Données d'événement:",
};

View File

@@ -80,7 +80,7 @@ export default {
pushOptionalParams: "Neobavezni parametri: {0}",
Save: "Spremi",
Notifications: "Obavijesti",
"Not available, please setup.": "Obavijesti nisu dostupne, potrebno dodati novu obavijest.",
"Not available, please setup.": "Nije dostupno, potrebno je dodati novu stavku.",
"Setup Notification": "Dodaj obavijest",
Light: "Svijetli način",
Dark: "Tamni način",
@@ -129,7 +129,7 @@ export default {
Export: "Izvoz",
Import: "Uvoz",
respTime: "Vrijeme odgovora (ms)",
notAvailableShort: "N/A",
notAvailableShort: "ne postoji",
"Default enabled": "Omogući za nove monitore",
"Apply on all existing monitors": "Primijeni na postojeće monitore",
Create: "Kreiraj",
@@ -375,4 +375,207 @@ export default {
alertaAlertState: "Stanje upozorenja",
alertaRecoverState: "Stanje oporavka",
deleteStatusPageMsg: "Sigurno želite obrisati ovu statusnu stranicu?",
resendEveryXTimes: "Ponovno pošalji svakih {0} puta",
resendDisabled: "Ponovno slanje je onemogućeno",
dnsPortDescription: "Port DNS poslužitelja. Zadana vrijednost je 53. Moguće je promijeniti ga u svakom trenutku.",
"Resend Notification if Down X times consequently": "Ponovno pošalji obavijest ako je usluga nedostupna više puta zaredom",
topic: "Tema",
topicExplanation: "MQTT tema koja će se monitorirati",
successMessage: "Poruka o uspjehu",
successMessageExplanation: "MQTT poruka koja se smatra uspješnom",
error: "greška",
critical: "kritično",
Customize: "Customize",
"Custom Footer": "Prilagođeno podnožje",
"Custom CSS": "Prilagođeni CSS",
wayToGetPagerDutyKey: "Ključ možete dobiti odlaskom na \"Service -> Service Directory -> (Odabrani servis) -> Integrations -> Add integration\". Ovdje pretražite za \"Events API V2\". Više informacija {0}",
"Integration Key": "Ključ integracije",
"Integration URL": "URL integracije",
"Auto resolve or acknowledged": "Automatsko razrješavanje i priznavanje",
"do nothing": "Ne radi ništa",
"auto acknowledged": "Automatsko priznavanje",
"auto resolve": "Automatsko razrješavanje",
Proxies: "Proxy poslužitelji",
default: "Zadano",
enabled: "Omogućeno",
setAsDefault: "Postavi kao zadano",
deleteProxyMsg: "Sigurno želite obrisati ovaj proxy za sve monitore?",
proxyDescription: "Proxy poslužitelji moraju biti dodijeljni monitoru kako bi funkcionirali.",
enableProxyDescription: "Onemogućeni proxy poslužitelj neće imati učinak na zahtjeve monitora. Možete privremeno onemogućiti proxy poslužitelja za sve monitore.",
setAsDefaultProxyDescription: "Ovaj proxy poslužitelj bit će odmah omogućen za nove monitore. I dalje ga možete onemogućiti za svaki monitor zasebno.",
"Certificate Chain": "Lanac certifikata",
Valid: "Važeći",
Invalid: "Nevažeći",
AccessKeyId: "AccessKey ID",
SecretAccessKey: "AccessKey tajni ključ",
PhoneNumbers: "Telefonski brojevi",
TemplateCode: "Predložak koda",
SignName: "Potpis",
"Sms template must contain parameters: ": "SMS predložak mora sadržavati parametre: ",
"Bark Endpoint": "Bark krajnja točka (endpoint)",
"Bark Group": "Bark grupa",
"Bark Sound": "Bark zvuk",
WebHookUrl: "WebHookUrl",
SecretKey: "Tajni ključ",
"For safety, must use secret key": "Korištenje tajnog ključa je obavezno",
"Device Token": "Token uređaja",
Platform: "Platforma",
iOS: "iOS",
Android: "Android",
Huawei: "Huawei",
High: "Visoko",
Retry: "Ponovnih pokušaja",
Topic: "Tema",
"WeCom Bot Key": "WeCom ključ Bota",
"Setup Proxy": "Dodaj proxy poslužitelj",
"Proxy Protocol": "Protokol",
"Proxy Server": "Proxy poslužitelj",
"Proxy server has authentication": "Proxy poslužitelj ima autentikaciju",
User: "Korisnik",
Installed: "Instalirano",
"Not installed": "Nije instalirano",
Running: "Pokrenuto",
"Not running": "Nije pokrenuto",
"Remove Token": "Ukloni Token",
Start: "Pokreni",
Stop: "Zaustavi",
"Uptime Kuma": "Uptime Kuma",
"Add New Status Page": "Dodaj novu statusnu stranicu",
Slug: "Slug",
"Accept characters:": "Dozvoljeni znakovi:",
startOrEndWithOnly: "Započinje ili završava znakovima {0}",
"No consecutive dashes": "Bez uzastopnih povlaka",
Next: "Sljedeće",
"The slug is already taken. Please choose another slug.": "Slug je zauzet. Odaberite novi slug.",
"No Proxy": "Bez proxy poslužitelja",
Authentication: "Autentikacija",
"HTTP Basic Auth": "HTTP Basic Auth",
"New Status Page": "Dodaj statusnu stranicu",
"Page Not Found": "Stranica nije pronađena",
"Reverse Proxy": "Reverzni proxy",
Backup: "Sigurnosno kopiranje",
About: "O Uptime Kumi",
wayToGetCloudflaredURL: "(Preuzmite cloudflared s {0})",
cloudflareWebsite: "Cloudflare web stranice",
"Message:": "Poruka:",
"Don't know how to get the token? Please read the guide:": "Ne znate kako doći do tokena? Pročitajte vodič:",
"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.": "Trenutna veza možda bude prekinuta jer se koristi Cloudflare tuneliranje. Sigurno želite zaustaviti? Unesite lozinku za potvrdu.",
"HTTP Headers": "HTTP zaglavlja",
"Trust Proxy": "Vjeruj proxy poslužitelju",
"Other Software": "Ostali programi",
"For example: nginx, Apache and Traefik.": "Primjerice: nginx, Apache ili Traefik.",
"Please read": "Molimo pročitajte",
"Subject:": "Predmet:",
"Valid To:": "Valjano do:",
"Days Remaining:": "Preostalo dana:",
"Issuer:": "Izdavatelj:",
"Fingerprint:": "Fingerprint:",
"No status pages": "Nema statusnih stranica",
"Domain Name Expiry Notification": "Obavijest za istek domena",
Proxy: "Proxy",
"Date Created": "Datum stvaranja",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP adresa",
onebotMessageType: "OneBot tip poruke",
onebotGroupMessage: "Grupna",
onebotPrivateMessage: "Privatna",
onebotUserOrGroupId: "ID korisnika/grupe",
onebotSafetyTips: "Pristupni token mora biti postavljen",
"PushDeer Key": "PushDeer ključ",
"Footer Text": "Tekst podnožja",
"Show Powered By": "Pokaži natpis 'Pokreće...'",
"Domain Names": "Domene",
signedInDisp: "Prijavljeni ste kao {0}",
signedInDispDisabled: "Autentikacija onemogućena.",
RadiusSecret: "Radius Tajna",
RadiusSecretDescription: "Dijeljena Tajna između klijenta i poslužitelja",
RadiusCalledStationId: "Called Station ID",
RadiusCalledStationIdDescription: "Identifikator pozivne stanice",
RadiusCallingStationId: "Calling Station ID",
RadiusCallingStationIdDescription: "Identifikator pozivajuće stanice",
"Certificate Expiry Notification": "Obavijest za istek certifikata",
"API Username": "API korisničko ime",
"API Key": "API ključ",
"Recipient Number": "Broj primatelja",
"From Name/Number": "Naziv/broj pošiljatelja",
"Leave blank to use a shared sender number.": "Ostaviti prazno za korištenje dijeljenog broja pošiljatelja.",
"Octopush API Version": "Octopush verzija API-ja",
"Legacy Octopush-DM": "Legacy Octopush-DM",
endpoint: "krajnja točka (endpoint)",
octopushAPIKey: "\"API ključ\" iz HTTP API postavki",
octopushLogin: "\"Korisničko ime\" iz HTTP API postavki",
promosmsLogin: "API korisničko ime",
promosmsPassword: "API lozinka",
"pushoversounds pushover": "Pushover (default)",
"pushoversounds bike": "Bike",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic",
"pushoversounds falling": "Falling",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magic",
"pushoversounds mechanical": "Mechanical",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Siren",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (long)",
"pushoversounds climb": "Climb (long)",
"pushoversounds persistent": "Persistent (long)",
"pushoversounds echo": "Pushover Echo (long)",
"pushoversounds updown": "Up Down (long)",
"pushoversounds vibrate": "Vibrate Only",
"pushoversounds none": "None (silent)",
pushyAPIKey: "Tajni API ključ",
pushyToken: "Token uređaja",
"Show update if available": "Pokaži moguću nadogradnju",
"Also check beta release": "Provjeravaj i za beta izdanja",
"Using a Reverse Proxy?": "Koristi li se reverzni proxy?",
"Check how to config it for WebSocket": "Provjerite kako se konfigurira za WebSocket protokol",
"Steam Game Server": "Steam poslužitelj igre",
"Most likely causes:": "Najvjerojatniji uzroci:",
"The resource is no longer available.": "Resurs više nije dostupan.",
"There might be a typing error in the address.": "Možda je nastala greška pri upisu adrese.",
"What you can try:": "Što možete pokušati:",
"Retype the address.": "Ponovno napišite adresu.",
"Go back to the previous page.": "Vratite se na prethodnu stranicu.",
"Coming Soon": "Dolazi uskoro",
wayToGetClickSendSMSToken: "Možete dobiti API korisničko ime i API ključ sa {0}.",
"Connection String": "Tekst veze",
Query: "Upit",
settingsCertificateExpiry: "TLS istek certifikata",
certificationExpiryDescription: "HTTPS monitori će obavijesiti kada je istek TLS certifikata za:",
"Setup Docker Host": "Dodaj Docker domaćina",
"Connection Type": "Tip veze",
"Docker Daemon": "Docker daemon",
deleteDockerHostMsg: "Sigurno želite izbrisati ovog Docker domaćina za sve monitore?",
socket: "Docker socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker kontejner",
"Container Name / ID": "Naziv / ID kontejnera",
"Docker Host": "Docker domaćin",
"Docker Hosts": "Docker domaćini",
"ntfy Topic": "ntfy tema",
Domain: "Domena",
Workstation: "Radna stanica",
disableCloudflaredNoAuthMsg: "Lozinka nije nužna dok je isključena autentikacija.",
trustProxyDescription: "Vjeruj 'X-Forwarded-*' zaglavljima. Ako želite dobiti ispravnu IP adresu klijenta i Uptime Kuma je iza reverznog proxy poslužitelja, trebate omogućiti ovo.",
wayToGetLineNotifyToken: "Možete dobiti pristupni token sa {0}",
Examples: "Primjeri",
"Home Assistant URL": "URL Home Assistanta",
"Long-Lived Access Token": "Dugotrajni pristupni 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. ": "Dugotrajni pristupni token može se kreirati klikom na korisničko ime (dolje lijevo) u Home Assistantu, pomicanjem do dna, te klikom na 'Create Token'. ",
"Notification Service": "Notification Service",
"default: notify all devices": "zadano ponašanje: obavijesti sve uređaje",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Popis servisa za obavijesti u Home Assistantu nalaze se pod \"Developer Tools > Services\" te pretražiti \"notification\".",
"Automations can optionally be triggered in Home Assistant:": "Automacije se mogu okinuti u Home Assistantu:",
"Trigger type:": "Tip triggera:",
"Event type:": "Tip eventa:",
"Event data:": "Podaci eventa:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "Potrebno je i odabrati akciju za izvođenje na Home Assistantu.",
"Frontend Version": "Inačica sučelja",
"Frontend Version do not match backend version!": "Inačica sučelja ne odgovara poslužitelju!",
};

View File

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

View File

@@ -7,25 +7,25 @@ export default {
upsideDownModeDescription: "Se il servizio risulta raggiungibile viene marcato come \"DOWN\".",
maxRedirectDescription: "Numero massimo di redirezionamenti consentito. Per disabilitare, impostare \"0\".",
acceptedStatusCodesDescription: "Elenco di codici di stato HTTP che sono considerati validi.",
passwordNotMatchMsg: "La password non coincide.",
passwordNotMatchMsg: "La password non corrisponde.",
notificationDescription: "Assegnare la notifica a uno o più oggetti monitorati per metterla in funzione.",
keywordDescription: "Cerca la parola chiave nella risposta in html o JSON e fai distinzione tra maiuscole e minuscole",
pauseDashboardHome: "In Pausa",
deleteMonitorMsg: "Si è certi di voler eliminare questo oggetto monitorato?",
deleteNotificationMsg: "Si è certi di voler eliminare questa notifica per tutti gli oggetti monitorati?",
resolverserverDescription: "Cloudflare è il server predefinito, è possibile cambiare il server DNS.",
deleteMonitorMsg: "Sei sicuro di voler eliminare questo oggetto monitorato?",
deleteNotificationMsg: "Sei sicuro di voler eliminare questa notifica per tutti gli oggetti monitorati?",
resolverserverDescription: "Cloudflare è il server predefinito ma è possibile cambiare il server DNS.",
rrtypeDescription: "Scegliere il tipo di RR che si vuole monitorare",
pauseMonitorMsg: "Si è certi di voler mettere in pausa?",
pauseMonitorMsg: "Sei sicuro di voler mettere in pausa?",
enableDefaultNotificationDescription: "Per ogni nuovo monitor questa notifica sarà abilitata di default. È comunque possibile disabilitare la notifica singolarmente.",
clearEventsMsg: "Si è certi di voler eliminare tutti gli eventi per questo servizio?",
clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?",
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?",
clearEventsMsg: "Sei sicuro di voler eliminare tutti gli eventi per questo servizio?",
clearHeartbeatsMsg: "Sei sicuro di voler eliminare tutti gli intervalli di controllo per questo servizio?",
confirmClearStatisticsMsg: "Sei sicuro di voler eliminare TUTTE le statistiche?",
importHandleDescription: "Selezionare \"Ignora esistenti\" se si vuole ignorare l'importazione dei monitor o delle notifiche con lo stesso nome. \"Sovrascrivi\" rimpiazzerà tutti i monitor e le notifiche presenti con quelli nel backup.",
confirmImportMsg: "Si è certi di voler importare il backup? Essere certi di aver selezionato l'opzione corretta di importazione.",
confirmImportMsg: "Sei sicuro di voler importare il backup? Controlla di aver selezionato l'opzione corretta di importazione.",
twoFAVerifyLabel: "Digita il token per verificare che l'autenticazione a due fattori funzioni correttamente:",
tokenValidSettingsMsg: "Il token è valido! È ora possibile salvare le impostazioni.",
confirmEnableTwoFAMsg: "Si è certi di voler abilitare l'autenticazione a due fattori?",
confirmDisableTwoFAMsg: "Si è certi di voler disabilitare l'autenticazione a due fattori?",
confirmEnableTwoFAMsg: "Sei sicuro di voler abilitare l'autenticazione a due fattori?",
confirmDisableTwoFAMsg: "Sei sicuro di voler disabilitare l'autenticazione a due fattori?",
Settings: "Impostazioni",
Dashboard: "Dashboard",
"New Update": "Nuovo aggiornamento disponibile!",

View File

@@ -3,7 +3,7 @@ export default {
checkEverySecond: "{0}초마다 확인해요.",
retryCheckEverySecond: "{0}초마다 다시 확인해요.",
retriesDescription: "서비스가 중단된 후 알림을 보내기 전 최대 재시도 횟수",
ignoreTLSError: "HTTPS 웹사이트에서 TLS/SSL 에러 무시하기",
ignoreTLSError: "HTTPS 웹사이트에서 TLS/SSL 오류 무시하기",
upsideDownModeDescription: "서버 상태를 반대로 표시해요. 서버가 작동하면 오프라인으로 표시할 거예요.",
maxRedirectDescription: "최대 리다이렉트 횟수예요. 0을 입력하면 리다이렉트를 꺼요.",
acceptedStatusCodesDescription: "응답 성공으로 간주할 상태 코드를 정해요.",
@@ -30,7 +30,7 @@ export default {
Dashboard: "대시보드",
"New Update": "새로운 업데이트",
Language: "언어",
Appearance: "외형",
Appearance: "디스플레이",
Theme: "테마",
General: "일반",
Version: "버전",
@@ -69,7 +69,7 @@ export default {
Port: "포트",
"Heartbeat Interval": "하트비트 주기",
Retries: "재시도",
"Heartbeat Retry Interval": "하트비 재시도 주기",
"Heartbeat Retry Interval": "하트비 재시도 주기",
Advanced: "고급",
"Upside Down Mode": "상태 반전 모드",
"Max. Redirects": "최대 리다이렉트",
@@ -78,7 +78,7 @@ export default {
Notifications: "알림",
"Not available, please setup.": "존재하지 않아요, 새로운 거 하나 만드는 건 어때요?",
"Setup Notification": "알림 설정",
Light: "이트",
Light: "이트",
Dark: "다크",
Auto: "자동",
"Theme - Heartbeat Bar": "테마 - 하트비트 바",
@@ -91,7 +91,7 @@ export default {
"Discourage search engines from indexing site": "검색 엔진 인덱싱 거부",
"Change Password": "비밀번호 변경",
"Current Password": "기존 비밀번호",
"New Password": "새로운 비밀번호",
"New Password": "새 비밀번호",
"Repeat New Password": "새로운 비밀번호 재입력",
"Update Password": "비밀번호 변경",
"Disable Auth": "인증 비활성화",
@@ -109,14 +109,14 @@ export default {
Password: "비밀번호",
"Remember me": "비밀번호 기억하기",
Login: "로그인",
"No Monitors, please": "모니터링이 없어요,",
"add one": "하나 추가해봐요",
"No Monitors, please": "모니터링이 현재 없어요,",
"add one": "한번 추가해보실래요?",
"Notification Type": "알림 종류",
Email: "이메일",
Test: "테스트",
"Certificate Info": "인증서 정보",
"Resolver Server": "Resolver 서버",
"Resource Record Type": "자원 레코드 유형",
"Resource Record Type": "리소스 레코드 유형",
"Last Result": "최근 결과",
"Create your admin account": "관리자 계정 만들기",
"Repeat Password": "비밀번호 재입력",
@@ -208,19 +208,19 @@ export default {
smtpBCC: "숨은 참조",
discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "서버 설정 -> 연동 -> 웹후크 보기 -> 새 웹후크에서 얻을 수 있어요.",
wayToGetDiscordURL: "서버 설정 -> 연동 -> 웹후크 보기 -> 새 웹후크에서 얻을 수 있어요!",
"Bot Display Name": "표시 이름",
"Prefix Custom Message": "접두사 메시지",
"Hello @everyone is...": "{'@'}everyone 서버 상태 알림이에요...",
teams: "Microsoft Teams",
"Webhook URL": "Webhook URL",
wayToGetTeamsURL: "{0}에서 Webhook을 어떻게 만드는지 알아봐요.",
wayToGetTeamsURL: "{0}에서 Webhook을 어떻게 만드는지 알아보세요!",
signal: "Signal",
Number: "숫자",
Recipients: "받는 사람",
needSignalAPI: "REST API를 사용하는 Signal 클라이언트가 있어야 해요.",
wayToCheckSignalURL: "밑에 URL을 확인해 URL 설정 방법을 볼 수 있어요.",
signalImportant: "중요: 받는 사람의 그룹과 숫자는 섞을 수 없어요!",
signalImportant: "경고: 받는 사람의 그룹과 숫자는 섞을 수 없어요!",
gotify: "Gotify",
"Application Token": "애플리케이션 토큰",
"Server URL": "서버 URL",
@@ -230,8 +230,8 @@ export default {
"Channel Name": "채널 이름",
"Uptime Kuma URL": "Uptime Kuma URL",
aboutWebhooks: "Webhook에 대한 설명: {0}",
aboutChannelName: "Webhook 채널을 우회하려면 {0} 채널 이름칸에 채널 이름을 입력해주세요. 예: #기타-채널",
aboutKumaURL: "Uptime Kuma URL칸을 공백으로 두면 기본적으로 Project Github 페이지로 설정해요.",
aboutChannelName: "Webhook 채널을 무시하려면 {0} 채널 이름칸에 채널 이름을 입력해주세요. 예: #기타-채널",
aboutKumaURL: "Uptime Kuma URL칸을 공백으로 두면 기본적으로 Github Project 페이지로 설정해요.",
emojiCheatSheet: "이모지 목록 시트: {0}",
"rocket.chat": "Rocket.chat",
pushover: "Pushover",
@@ -243,8 +243,8 @@ export default {
pushbullet: "Pushbullet",
line: "Line Messenger",
mattermost: "Mattermost",
"User Key": "사용자 키",
Device: "장치",
"User Key": "유저 키",
Device: "디바이스",
"Message Title": "메시지 제목",
"Notification Sound": "알림음",
"More info on:": "자세한 정보: {0}",
@@ -254,7 +254,7 @@ export default {
octopushTypePremium: "프리미엄 (빠름) - 알림 기능에 적합해요)",
octopushTypeLowCost: "저렴한 요금 (느림) - 가끔 차단될 수 있어요)",
"Check octopush prices": "{0}에서 Octopush 가격을 확인할 수 있어요.",
octopushPhoneNumber: "휴대전화 번호 (intl format, eg : +33612345678) ",
octopushPhoneNumber: "휴대전화 번호 (intl format, 예시: +821023456789) ",
octopushSMSSender: "보내는 사람 이름 : 3-11개의 영숫자 및 여백공간 (a-z, A-Z, 0-9)",
"LunaSea Device ID": "LunaSea 장치 ID",
"Apprise URL": "Apprise URL",
@@ -324,17 +324,17 @@ export default {
Content: "내용",
Style: "스타일",
info: "정보",
warning: "경고",
danger: "위험",
warning: "주의",
danger: "경고",
primary: "기본",
light: "이트",
light: "이트",
dark: "다크",
Post: "올리기",
Post: "게시",
"Please input title and content": "제목과 내용을 작성해주세요.",
Created: "생성 날짜",
"Last Updated": "마지막 업데이트",
Unpin: "제거",
"Switch to Light Theme": "이트 테마로 전환",
"Switch to Light Theme": "이트 테마로 전환",
"Switch to Dark Theme": "다크 테마로 전환",
"Show Tags": "태그 보이기",
"Hide Tags": "태그 숨기기",
@@ -361,8 +361,8 @@ export default {
topicExplanation: "모니터링할 MQTT Topic",
successMessage: "성공 메시지",
successMessageExplanation: "성공으로 간주되는 MQTT 메시지",
error: "error",
critical: "critical",
error: "오류",
critical: "크리티컬",
Customize: "커스터마이즈",
"Custom Footer": "커스텀 Footer",
"Custom CSS": "커스텀 CSS",
@@ -406,7 +406,7 @@ export default {
PhoneNumbers: "휴대전화 번호",
TemplateCode: "템플릿 코드",
SignName: "SignName",
"Sms template must contain parameters: ": "Sms 템플릿은 다음과 같은 파라미터가 포함되어야 해요:",
"Sms template must contain parameters: ": "SMS 템플릿은 다음과 같은 파라미터가 포함되어야 해요:",
"Bark Endpoint": "Bark Endpoint",
WebHookUrl: "웹훅 URL",
SecretKey: "Secret Key",
@@ -518,14 +518,14 @@ export default {
"Show update if available": "사용 가능한 경우에 업데이트 표시",
"Also check beta release": "베타 릴리즈 확인",
"Using a Reverse Proxy?": "리버스 프록시를 사용하시나요?",
"Check how to config it for WebSocket": "웹소켓 대한 설정 방법 확인",
"Check how to config it for WebSocket": "웹소켓 대한 설정 방법",
"Steam Game Server": "스팀 게임 서버",
"Most likely causes:": "원인:",
"The resource is no longer available.": "더이상 사용할 수 없어요.",
"The resource is no longer available.": "더 이상 사용할 수 없어요...",
"There might be a typing error in the address.": "주소에 오탈자가 있을 수 있어요.",
"What you can try:": "해결 방법:",
"Retype the address.": "주소 다시 입력하기",
"Go back to the previous page.": "이전 페이지로 돌아가기",
"Coming Soon": "Coming Soon",
"Coming Soon": "Coming Soon...",
wayToGetClickSendSMSToken: "{0}에서 API 사용자 이름과 키를 얻을 수 있어요.",
};

View File

@@ -90,8 +90,11 @@ export default {
"New Password": "Nieuw wachtwoord",
"Repeat New Password": "Herhaal nieuw wachtwoord",
"Update Password": "Vernieuw wachtwoord",
"Disable Auth": "Autorisatie uitschakelen",
"Enable Auth": "Autorisatie inschakelen",
"Disable Auth": "Authenticatie uitschakelen",
"Enable Auth": "Authenticatie inschakelen",
"disableauth.message1": "Weet je zeker dat je <strong>authenticatie wilt uitschakelen</strong>?",
"disableauth.message2": "Er zijn omstandigheden waarbij je <strong>authenticatie door derden wilt implementeren</strong> voor Uptime Kuma, zoals Cloudflare Access, Authelia of andere authenticatiemechanismen.",
"Please use this option carefully!": "Gebruik deze optie zorgvuldig!",
Logout: "Uitloggen",
Leave: "Vertrekken",
"I understand, please disable": "Ik begrijp het, schakel a.u.b. uit",
@@ -351,7 +354,7 @@ export default {
Discard: "Weggooien",
Cancel: "Annuleren",
"Powered by": "Mogelijk gemaakt door",
shrinkDatabaseDescription: "Trigger database VACUUM voor SQLite. Als de database na 1.10.0 gemaakt is, dan is AUTO_VACUUM al aangezet en deze actie niet nodig.",
shrinkDatabaseDescription: "Activeer database VACUUM voor SQLite. Als de database na 1.10.0 aangemaakt is, dan staat AUTO_VACUUM al aan en is deze actie niet nodig.",
serwersms: "SerwerSMS.pl",
serwersmsAPIUser: "API Gebruikersnaam (incl. webapi_ prefix)",
serwersmsAPIPassword: "API Wachtwoord",
@@ -386,7 +389,7 @@ export default {
proxyDescription: "Proxies moeten worden toegewezen aan een monitor om te functioneren.",
enableProxyDescription: "Deze proxy heeft geen effect op monitor verzoeken totdat het is geactiveerd. Je kunt tijdelijk de proxy uitschakelen voor alle monitors voor activatie status.",
setAsDefaultProxyDescription: "Deze proxy wordt standaard aangezet voor alle nieuwe monitors. Je kunt nog steeds de proxy apart uitschakelen voor elke monitor.",
"Certificate Chain": "Certificaat Chain",
"Certificate Chain": "Certificaatketen",
Valid: "Geldig",
Invalid: "Ongeldig",
AccessKeyId: "AccessKey ID",
@@ -407,7 +410,7 @@ export default {
High: "Hoog",
Retry: "Opnieuw",
Topic: "Onderwerp",
"WeCom Bot Key": "WeCom Bot Sleutel",
"WeCom Bot Key": "WeCom Bot Key",
"Setup Proxy": "Proxy instellen",
"Proxy Protocol": "Proxy Protocol",
"Proxy Server": "Proxy Server",
@@ -449,7 +452,6 @@ export default {
"Issuer:": "Uitgever:",
"Fingerprint:": "Vingerafruk:",
"No status pages": "Geen status pagina's",
"Domain Name Expiry Notification": "Domein Naam Verloop Notificatie",
Proxy: "Proxy",
"Date Created": "Datum Aangemaakt",
onebotHttpAddress: "OneBot HTTP Adres",
@@ -460,6 +462,70 @@ export default {
onebotSafetyTips: "Voor de veiligheid moet een toegangssleutel worden ingesteld",
"PushDeer Key": "PushDeer Key",
"Footer Text": "Footer Tekst",
"Show Powered By": "Laat 'Mogeljik gemaakt door' zien",
"Show Powered By": "Laat \"Mogeljik gemaakt door\" zien",
"Domain Names": "Domein Namen",
"pushoversounds pushover": "Pushover (default)",
"pushoversounds bike": "Bike",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic",
"pushoversounds falling": "Falling",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magic",
"pushoversounds mechanical": "Mechanical",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Siren",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (long)",
"pushoversounds climb": "Climb (long)",
"pushoversounds persistent": "Persistent (long)",
"pushoversounds echo": "Pushover Echo (long)",
"pushoversounds updown": "Up Down (long)",
"pushoversounds vibrate": "Vibrate Only",
"pushoversounds none": "None (silent)",
dnsPortDescription: "DNS-serverpoort. Standaard ingesteld op 53. Je kunt de poort op elk moment wijzigen.",
error: "fout",
critical: "kritisch",
wayToGetPagerDutyKey: "Je kunt dit krijgen door naar Service -> Service Directory -> (Selecteer een service) -> Integraties -> Integratie toevoegen te gaan. Hier kunt u zoeken naar \"Events API V2\". Meer informatie {0}",
"Integration Key": "Integration Key",
"Integration URL": "Integration URL",
"Auto resolve or acknowledged": "Automatisch oplossen of bevestigen",
"do nothing": "niets doen",
"auto acknowledged": "automatisch bevestigen",
"auto resolve": "automatisch oplossen",
Authentication: "authenticatie",
signedInDisp: "Aangemeld als {0}",
signedInDispDisabled: "Authenticatie uitgeschakeld.",
"Certificate Expiry Notification": "Melding over verlopen certificaat",
"Recipient Number": "Nummer ontvanger",
"From Name/Number": "Van naam/nummer",
"Leave blank to use a shared sender number.": "Laat leeg om een gedeeld afzendernummer te gebruiken.",
endpoint: "endpoint",
pushyAPIKey: "Secret API Key",
pushyToken: "Device token",
"Show update if available": "Update weergeven indien beschikbaar",
"Also check beta release": "Controleer ook de bètaversies",
"Using a Reverse Proxy?": "Een reverse proxy gebruiken?",
"Check how to config it for WebSocket": "Controleer hoe je het configureert voor een WebSocket",
"Steam Game Server": "Steam gameserver",
"Most likely causes:": "Meest waarschijnlijke oorzaken:",
"The resource is no longer available.": "De paginabron is niet langer beschikbaar.",
"There might be a typing error in the address.": "Er zit een typefout in het de URL.",
"What you can try:": "Wat je kan proberen:",
"Retype the address.": "De URL controleren en/of opnnieuw typen.",
"Go back to the previous page.": "Terug naar de vorige pagina.",
"Coming Soon": "Binnenkort beschikbaar",
wayToGetClickSendSMSToken: "Je kan een API Username en API Key krijgen vanuit {0} .",
"Connection String": "Connection String",
Query: "Query",
settingsCertificateExpiry: "TLS Certificate Expiry",
certificationExpiryDescription: "HTTPS Monitors trigger notification when TLS certificate expires in:",
"ntfy Topic": "ntfy Topic",
Domain: "Domein",
Workstation: "Werkstation",
disableCloudflaredNoAuthMsg: "De \"Geen authenticatie\" modus staat aan, wachtwoord is niet vereist.",
};

203
src/languages/pt-PT.js Normal file
View File

@@ -0,0 +1,203 @@
export default {
languageName: "Português (Portugal)",
checkEverySecond: "Verificar a cada {0} segundos.",
retryCheckEverySecond: "Tentar novamente a cada {0} segundos.",
retriesDescription: "Máximo de tentativas antes que o serviço seja marcado como inativo e uma notificação seja enviada",
ignoreTLSError: "Ignorar erros TLS/SSL para sites HTTPS",
upsideDownModeDescription: "Inverte o status de cabeça para baixo. Se o serviço estiver acessível, ele está OFFLINE.",
maxRedirectDescription: "Número máximo de redirecionamentos a seguir. Define como 0 para desativar redirecionamentos.",
acceptedStatusCodesDescription: "Seleciona os códigos de status que são considerados uma resposta bem-sucedida.",
passwordNotMatchMsg: "A senha repetida não corresponde.",
notificationDescription: "Atribuir uma notificação ao (s) monitor (es) para que funcione.",
keywordDescription: "Pesquisa a palavra-chave em HTML simples ou resposta JSON e diferencia maiúsculas de minúsculas",
pauseDashboardHome: "Pausa",
deleteMonitorMsg: "Tens a certeza de que queres excluir este monitor?",
deleteNotificationMsg: "Tens a certeza de que queres excluir esta notificação para todos os monitores?",
resolverserverDescription: "A Cloudflare é o servidor padrão, podes alterar o servidor 'resolvedor' a qualquer momento.",
rrtypeDescription: "Seleciona o RR-Type que queres monitorizar",
pauseMonitorMsg: "Tens a certeza que queres fazer uma pausa?",
enableDefaultNotificationDescription: "Para cada monitor novo esta notificação vai estar activa por padrão. Podes também desativar a notificação separadamente para cada monitor.",
clearEventsMsg: "Tens a certeza que queres excluir todos os eventos deste monitor?",
clearHeartbeatsMsg: "Tens a certeza de que queres excluir todos os heartbeats deste monitor?",
confirmClearStatisticsMsg: "Tens a certeza que queres excluir TODAS as estatísticas?",
importHandleDescription: "Escolhe 'Ignorar existente' se quiseres ignorar todos os monitores ou notificações com o mesmo nome. 'Substituir' excluirá todos os monitores e notificações existentes.",
confirmImportMsg: "Tens a certeza que queres importar o backup? Certifica-te que selecionaste a opção de importação correta.",
twoFAVerifyLabel: "Insire o teu token para verificares se o 2FA está a funcionar",
tokenValidSettingsMsg: "O token é válido! Agora podes salvar as configurações do 2FA.",
confirmEnableTwoFAMsg: "Tens a certeza de que queres habilitar 2FA?",
confirmDisableTwoFAMsg: "Tens a certeza de que queres desativar 2FA?",
Settings: "Configurações",
Dashboard: "Dashboard",
"New Update": "Nova Atualização",
Language: "Linguagem",
Appearance: "Aparência",
Theme: "Tema",
General: "Geral",
Version: "Versão",
"Check Update On GitHub": "Verificar atualização no Github",
List: "Lista",
Add: "Adicionar",
"Add New Monitor": "Adicionar novo monitor",
"Quick Stats": "Estatísticas rápidas",
Up: "On",
Down: "Off",
Pending: "Pendente",
Unknown: "Desconhecido",
Pause: "Pausa",
Name: "Nome",
Status: "Status",
DateTime: "Data hora",
Message: "Mensagem",
"No important events": "Nenhum evento importante",
Resume: "Resumo",
Edit: "Editar",
Delete: "Apagar",
Current: "Atual",
Uptime: "Tempo de atividade",
"Cert Exp.": "Cert Exp.",
day: "dia | dias",
"-day": "-dia",
hour: "hora",
"-hour": "-hora",
Response: "Resposta",
Ping: "Ping",
"Monitor Type": "Tipo de Monitor",
Keyword: "Palavra-Chave",
"Friendly Name": "Nome Amigável",
URL: "URL",
Hostname: "Hostname",
Port: "Porta",
"Heartbeat Interval": "Intervalo de Heartbeats",
Retries: "Novas tentativas",
"Heartbeat Retry Interval": "Intervalo de repetição de Heartbeats",
Advanced: "Avançado",
"Upside Down Mode": "Modo de cabeça para baixo",
"Max. Redirects": "Redirecionamento Máx.",
"Accepted Status Codes": "Status Code Aceitáveis",
Save: "Guardar",
Notifications: "Notificações",
"Not available, please setup.": "Não disponível, por favor configura.",
"Setup Notification": "Configurar Notificação",
Light: "Claro",
Dark: "Escuro",
Auto: "Auto",
"Theme - Heartbeat Bar": "Tema - Barra de Heartbeat",
Normal: "Normal",
Bottom: "Inferior",
None: "Nenhum",
Timezone: "Fuso horário",
"Search Engine Visibility": "Visibilidade do mecanismo de pesquisa",
"Allow indexing": "Permitir Indexação",
"Discourage search engines from indexing site": "Desencorajar que motores de busca indexem o site",
"Change Password": "Mudar senha",
"Current Password": "Senha atual",
"New Password": "Nova Senha",
"Repeat New Password": "Repetir Nova Senha",
"Update Password": "Atualizar Senha",
"Disable Auth": "Desativar Autenticação",
"Enable Auth": "Ativar Autenticação",
"disableauth.message1": "Tens a certeza que queres <strong>desativar a autenticação</strong>?",
"disableauth.message2": "Isso é para <strong>alguém que tem autenticação de terceiros</strong> em frente ao 'UpTime Kuma' como o Cloudflare Access.",
"Please use this option carefully!": "Por favor, utiliza esta opção com cuidado.",
Logout: "Logout",
Leave: "Sair",
"I understand, please disable": "Eu entendo, por favor desativa.",
Confirm: "Confirmar",
Yes: "Sim",
No: "Não",
Username: "Utilizador",
Password: "Senha",
"Remember me": "Lembra-me",
Login: "Autenticar",
"No Monitors, please": "Nenhum monitor, por favor",
"add one": "adicionar um",
"Notification Type": "Tipo de Notificação",
Email: "Email",
Test: "Testar",
"Certificate Info": "Info. do Certificado ",
"Resolver Server": "Resolver Servidor",
"Resource Record Type": "Tipo de registro de aplicação",
"Last Result": "Último resultado",
"Create your admin account": "Cria a tua conta de admin",
"Repeat Password": "Repete a senha",
"Import Backup": "Importar Backup",
"Export Backup": "Exportar Backup",
Export: "Exportar",
Import: "Importar",
respTime: "Tempo de Resp. (ms)",
notAvailableShort: "N/A",
"Default enabled": "Padrão habilitado",
"Apply on all existing monitors": "Aplicar em todos os monitores existentes",
Create: "Criar",
"Clear Data": "Limpar Dados",
Events: "Eventos",
Heartbeats: "Heartbeats",
"Auto Get": "Obter Automático",
backupDescription: "Podes fazer backup de todos os monitores e todas as notificações num arquivo JSON.",
backupDescription2: "OBS: Os dados do histórico e do evento não estão incluídos.",
backupDescription3: "Dados confidenciais, como tokens de notificação, estão incluídos no arquivo de exportação, mantem-no com cuidado.",
alertNoFile: "Seleciona um arquivo para importar.",
alertWrongFileType: "Seleciona um arquivo JSON.",
"Clear all statistics": "Limpar todas as estatísticas",
"Skip existing": "Saltar existente",
Overwrite: "Sobrescrever",
Options: "Opções",
"Keep both": "Manter os dois",
"Verify Token": "Verificar Token",
"Setup 2FA": "Configurar 2FA",
"Enable 2FA": "Ativar 2FA",
"Disable 2FA": "Desativar 2FA",
"2FA Settings": "Configurações do 2FA ",
"Two Factor Authentication": "Autenticação de Dois Fatores",
Active: "Ativo",
Inactive: "Inativo",
Token: "Token",
"Show URI": "Mostrar URI",
Tags: "Tag",
"Add New below or Select...": "Adicionar Novo abaixo ou Selecionar ...",
"Tag with this name already exist.": "Já existe uma etiqueta com este nome.",
"Tag with this value already exist.": "Já existe uma etiqueta com este valor.",
color: "cor",
"value (optional)": "valor (opcional)",
Gray: "Cinza",
Red: "Vermelho",
Orange: "Laranja",
Green: "Verde",
Blue: "Azul",
Indigo: "Índigo",
Purple: "Roxo",
Pink: "Rosa",
"Search...": "Pesquisa...",
"Avg. Ping": "Ping Médio.",
"Avg. Response": "Resposta Média. ",
"Status Page": "Página de Status",
"Status Pages": "Página de Status",
"Entry Page": "Página de entrada",
statusPageNothing: "Nada aqui, por favor, adiciona um grupo ou monitor.",
"No Services": "Nenhum Serviço",
"All Systems Operational": "Todos os Serviços Operacionais",
"Partially Degraded Service": "Serviço parcialmente degradados",
"Degraded Service": "Serviço Degradado",
"Add Group": "Adicionar Grupo",
"Add a monitor": "Adicionar um monitor",
"Edit Status Page": "Editar Página de Status",
"Go to Dashboard": "Ir para o dashboard",
telegram: "Telegram",
webhook: "Webhook",
smtp: "Email (SMTP)",
discord: "Discord",
teams: "Microsoft Teams",
signal: "Signal",
gotify: "Gotify",
slack: "Slack",
"rocket.chat": "Rocket.chat",
pushover: "Pushover",
pushy: "Pushy",
octopush: "Octopush",
promosms: "PromoSMS",
lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)",
pushbullet: "Pushbullet",
line: "Line Messenger",
mattermost: "Mattermost",
};

View File

@@ -184,8 +184,8 @@ export default {
"Add a monitor": "Dodaj monitor",
"Edit Status Page": "Uredi statusno stran",
"Go to Dashboard": "Pojdi na nadzorno ploščo",
"Status Page": "Página de Status",
"Status Pages": "Página de Status",
"Status Page": "Statusna stran",
"Status Pages": "Statusne strani",
defaultNotificationName: "Moje {notification} Obvestilo ({number})",
here: "tukaj",
Required: "Obvezno",

View File

@@ -206,10 +206,10 @@ export default {
smtp: "Email (SMTP)",
secureOptionNone: "None / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignore TLS Error",
"From Email": "From Email",
emailCustomSubject: "Custom Subject",
"To Email": "To Email",
"Ignore TLS Error": "เพิกเฉยข้อผิดพลาด TLS",
"From Email": "จากอีเมล",
emailCustomSubject: "หัวข้อที่กำหนดเอง",
"To Email": "ถึงอีเมล",
smtpCC: "CC",
smtpBCC: "BCC",
discord: "Discord",
@@ -518,4 +518,63 @@ export default {
"Go back to the previous page.": "กลับไปที่หน้าก่อนหน้า",
"Coming Soon": "เร็ว ๆ นี้",
wayToGetClickSendSMSToken: "คุณสามารถรับ API Username และ API Key ได้จาก {0}",
wayToGetLineNotifyToken: "คุณสามารถรับ access token ได้จาก {0}",
resendEveryXTimes: "ส่งซ้ำทุก {0} ครั้ง",
resendDisabled: "การส่งซ้ำถูกปิดใช้งาน",
dnsPortDescription: "พอร์ตของเซิร์ฟเวอร์ DNS, ค่าเริ่มต้นคือ 53, คุณสามารถเปลี่ยนพอร์ตตอนไหนก็ได้",
"Resend Notification if Down X times consequently": "ส่งการแจ้งเตือนซ้ำถ้าออฟไลน์ครบ X ครั้ง",
error: "เกิดข้อผิดพลาด",
critical: "วิกฤต",
wayToGetPagerDutyKey: "คุณสามารถรับได้โดยการไปที่ Service -> Service Directory -> (Select a service) -> Integrations -> Add integration, และค้นหา \"Events API V2\", สำหรับข้อมูลเพิ่มเติม {0}",
"Integration Key": "Integration Key",
"Integration URL": "Integration URL",
"Auto resolve or acknowledged": "แก้ไขอัตโนมัติหรือยอมรับ",
"do nothing": "ไม่ทำอะไร",
"auto acknowledged": "ยอมรับอัตโนมัติ",
"auto resolve": "แก้ไขอัตโนมัติ",
"Bark Group": "กลุ่มที่จะประกาศ",
"Bark Sound": "เสียงประกาศ",
Authentication: "การตรวจสอบสิทธิ์",
"HTTP Headers": "HTTP Headers",
"Trust Proxy": "Trust Proxy",
HomeAssistant: "Home Assistant",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "แบ่งปันข้อมูลลับระหว่างผู้ใช้งานและเซิร์ฟเวอร์",
RadiusCalledStationId: "Called Station Id",
RadiusCalledStationIdDescription: "Identifier of the called device",
RadiusCallingStationId: "Calling Station Id",
RadiusCallingStationIdDescription: "Identifier of the calling device",
"Connection String": "Connection String",
Query: "Query",
settingsCertificateExpiry: "วันหมดอายุใบรับรอง TLS",
certificationExpiryDescription: "การตรวจสอบ HTTPS แจ้งเตือนใบอนุญาติ TLS จะหมดอายุใน:",
"Setup Docker Host": "Setup Docker Host",
"Connection Type": "ประเภทการเชื่อมต่อ",
"Docker Daemon": "Docker Daemon",
deleteDockerHostMsg: "คุณแน่ใจหรือไม่ที่จะลบ Docker host นี้สำหรับการมอนิเตอร์ทั้งหมด?",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker Container",
"Container Name / ID": "Container Name / ID",
"Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Topic",
Domain: "โดเมน",
Workstation: "Workstation",
disableCloudflaredNoAuthMsg: "คุณอยู่ในโหมดไม่มีการตรวจสอบสิทธิ์, ไม่จำเป็นต้องมีรหัสผ่าน",
trustProxyDescription: "เชื่อ Header 'X-Forwarded-*' ถ้าคุณต้องการไอพีที่ถูกต้องและ Uptime Kuma อยู่ข้างหลัง Nginx หรือ Apache, คุณควรเปิดใช้งาน",
Examples: "ตัวอย่าง",
"Home Assistant URL": "Home Assistant URL",
"Long-Lived Access Token": "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. ": "Access Token แบบมีอายุนานสามารถสร้างได้โดยคลิกชื่อบนโปรไฟล์ (ล่างซ้าย) และเลื่อนไปข้างล่างจากนั้นคลิก \"Create Token\"",
"Notification Service": "บริการแจ้งเตือน",
"default: notify all devices": "ค่าเริ่มต้น: แจ้งเตือนทุกอุปกรณ์",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "รายการแจ้งเตือนสามารถหาได้ใน Home Assistant ในเมนู \"Developer Tools > Services\" ค้นหา \"notification\" เพื่อหาชื่ออุปกรณ์หรือชื่อโทรศัพท์",
"Automations can optionally be triggered in Home Assistant:": "สามารถเลือกสั่งงานระบบอัตโนมัติได้ใน Home Assistant:",
"Trigger type:": "ชนิดสิ่งกระตุ้น:",
"Event type:": "ชนิดกิจกรรม:",
"Event data:": "ข้อมูลกิจกรรม:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "จากนั้นเลือกการกระทำ, ตัวอย่าง เช่น เปลี่ยนเป็นไฟสีแดง",
"Frontend Version": "เวอร์ชั่น Frontend",
"Frontend Version do not match backend version!": "เวอร์ชั่น Frontend ไม่ตรงกับ Backend !",
};

View File

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

View File

@@ -1,5 +1,5 @@
export default {
languageName: "Український",
languageName: "Українська",
checkEverySecond: "Перевірка кожні {0} секунд",
retriesDescription: "Максимальна кількість спроб перед позначенням сервісу як недоступного та надсиланням повідомлення",
ignoreTLSError: "Ігнорувати помилку TLS/SSL для сайтів HTTPS",
@@ -7,11 +7,11 @@ export default {
maxRedirectDescription: "Максимальна кількість перенаправлень. Поставте 0, щоб вимкнути перенаправлення.",
acceptedStatusCodesDescription: "Виберіть коди статусів для визначення доступності сервісу.",
passwordNotMatchMsg: "Повторення паролю не збігається.",
notificationDescription: "Прив'яжіть повідомлення до моніторів.",
notificationDescription: "Прив'яжіть сповіщення до моніторів.",
keywordDescription: "Пошук слова в чистому HTML або JSON-відповіді (чутливо до регістру)",
pauseDashboardHome: "Пауза",
deleteMonitorMsg: "Ви дійсно хочете видалити цей монітор?",
deleteNotificationMsg: "Ви дійсно хочете видалити це повідомлення для всіх моніторів?",
deleteNotificationMsg: "Ви дійсно хочете видалити це сповіщення для всіх моніторів?",
resolverserverDescription: "Cloudflare є сервером за замовчуванням. Ви завжди можете змінити цей сервер.",
rrtypeDescription: "Виберіть тип ресурсного запису, який ви хочете відстежувати",
pauseMonitorMsg: "Ви дійсно хочете поставити на паузу?",
@@ -54,7 +54,7 @@ export default {
Keyword: "Ключове слово",
"Friendly Name": "Ім'я",
URL: "URL",
Hostname: "Ім'я хоста",
Hostname: "Адреса хоста",
Port: "Порт",
"Heartbeat Interval": "Частота опитування",
Retries: "Спроб",
@@ -63,7 +63,7 @@ export default {
"Max. Redirects": "Макс. кількість перенаправлень",
"Accepted Status Codes": "Припустимі коди статусу",
Save: "Зберегти",
Notifications: "Повідомлення",
Notifications: "Сповіщення",
"Not available, please setup.": "Доступних сповіщень немає, необхідно створити.",
"Setup Notification": "Створити сповіщення",
Light: "Світла",
@@ -100,7 +100,7 @@ export default {
"No Monitors, please": "Моніторів немає, будь ласка",
"No Monitors": "Монітори відсутні",
"add one": "створіть новий",
"Notification Type": "Тип повідомлення",
"Notification Type": "Тип сповіщення",
Email: "Пошта",
Test: "Перевірка",
"Certificate Info": "Інформація про сертифікат",
@@ -119,7 +119,7 @@ export default {
Events: "Події",
Heartbeats: "Опитування",
"Auto Get": "Авто-отримання",
enableDefaultNotificationDescription: "Для кожного нового монітора це повідомлення буде включено за замовчуванням. Ви все ще можете відключити повідомлення в кожному моніторі окремо.",
enableDefaultNotificationDescription: "Для кожного нового монітора це сповіщення буде включено за замовчуванням. Ви все ще можете відключити сповіщення в кожному моніторі окремо.",
"Default enabled": "Використовувати за промовчанням",
"Also apply to existing monitors": "Застосувати до існуючих моніторів",
Export: "Експорт",
@@ -170,7 +170,7 @@ export default {
Purple: "Пурпурний",
Pink: "Рожевий",
"Search...": "Пошук...",
"Avg. Ping": "Середнє значення пінгу",
"Avg. Ping": "Середній пінг",
"Avg. Response": "Середній час відповіді",
"Entry Page": "Головна сторінка",
statusPageNothing: "Тут порожньо. Додайте групу або монітор.",
@@ -210,7 +210,7 @@ export default {
"Push URL": "URL пуша",
needPushEvery: "До цієї URL необхідно звертатися кожні {0} секунд",
pushOptionalParams: "Опціональні параметри: {0}",
defaultNotificationName: "Моє повідомлення {notification} ({number})",
defaultNotificationName: "Моє сповіщення {notification} ({number})",
here: "тут",
Required: "Потрібно",
"Bot Token": "Токен бота",
@@ -257,7 +257,7 @@ export default {
"User Key": "Ключ користувача",
Device: "Пристрій",
"Message Title": "Заголовок повідомлення",
"Notification Sound": "Звук повідомлення",
"Notification Sound": "Звук сповіщення",
"More info on:": "Більше інформації: {0}",
pushoverDesc1: "Екстренний пріоритет (2) має таймуут повтору за замовчуванням 30 секунд і закінчується через 1 годину.",
pushoverDesc2: "Якщо ви бажаєте надсилати повідомлення різним пристроям, необхідно заповнити поле Пристрій.",
@@ -354,7 +354,7 @@ export default {
"No consecutive dashes --": "Заборонено використовувати тире --",
"HTTP Options": "HTTP Опції",
Authentication: "Аутентифікація",
"HTTP Basic Auth": "HTTP Авторизація",
"HTTP Basic Auth": "Базова HTTP",
PushByTechulus: "Push by Techulus",
clicksendsms: "ClickSend SMS",
GoogleChat: "Google Chat (тільки Google Workspace)",
@@ -392,4 +392,139 @@ export default {
alertaAlertState: "Стан алерту",
alertaRecoverState: "Стан відновлення",
deleteStatusPageMsg: "Дійсно хочете видалити цю сторінку статусів?",
Proxies: "Проксі",
default: "За замовчуванням",
enabled: "Активно",
setAsDefault: "Встановити за замовчуванням",
deleteProxyMsg: "Ви впевнені, що хочете видалити цей проксі для всіх моніторів?",
proxyDescription: "Щоб функціонувати, монітору потрібно призначити проксі.",
enableProxyDescription: "Цей проксі не впливатиме на запити моніторингу, доки його не буде активовано. Ви можете контролювати тимчасове відключення проксі з усіх моніторів за статусом активації.",
setAsDefaultProxyDescription: "Цей проксі буде ввімкнено за умовчанням для нових моніторів. Ви все одно можете вимкнути проксі окремо для кожного монітора.",
Invalid: "Недійсний",
AccessKeyId: "AccessKey ID",
SecretAccessKey: "AccessKey Secret",
PhoneNumbers: "PhoneNumbers",
TemplateCode: "TemplateCode",
SignName: "SignName",
"Sms template must contain parameters: ": "Шаблон смс повинен містити параметри: ",
"Bark Endpoint": "Bark Endpoint",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "Для безпеки необхідно використовувати секретний ключ",
"Device Token": "Токен пристрою",
Platform: "Платформа",
iOS: "iOS",
Android: "Android",
Huawei: "Huawei",
High: "Високий",
Retry: "Повтор",
Topic: "Тема",
"WeCom Bot Key": "WeCom Bot ключ",
"Setup Proxy": "Налаштувати проксі",
"Proxy Protocol": "Протокол проксі",
"Proxy Server": "Проксі-сервер",
"Proxy server has authentication": "Проксі-сервер має аутентифікацію",
User: "Користувач",
Installed: "Встановлено",
"Not installed": "Не встановлено",
Running: "Запущено",
"Not running": "Не запущено",
"Remove Token": "Видалити токен",
Start: "Запустити",
Stop: "Зупинити",
"Uptime Kuma": "Uptime Kuma",
Slug: "Slug",
"Accept characters:": "Прийняти символи:",
startOrEndWithOnly: "Починається або закінчується лише {0}",
"No consecutive dashes": "Немає послідовних тире",
"The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.",
"No Proxy": "Без проксі",
"Page Not Found": "Сторінку не знайдено",
"Reverse Proxy": "Реверсивний проксі",
wayToGetCloudflaredURL: "(Завантажити Cloudflare з {0})",
cloudflareWebsite: "Веб-сайт Cloudflare",
"Message:": "Повідомлення:",
"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.": "Поточне з’єднання може бути втрачено, якщо ви зараз під’єднуєтеся через Cloudflare Tunnel. Ви дійсно хочете зробити це? Для підтвердження введіть поточний пароль.",
"Other Software": "Інше програмне забезпечення",
"For example: nginx, Apache and Traefik.": "Наприклад: nginx, Apache and Traefik.",
"Please read": "Будь ласка, прочитайте",
"Subject:": "Тема:",
"Valid To:": "Дійсний до:",
"Days Remaining:": "Залишилось днів:",
"Issuer:": "Емітент:",
"Fingerprint:": "Відбиток:",
"No status pages": "Немає сторінок статусу",
"Domain Name Expiry Notification": "Сповіщення про закінчення терміну дії доменного імені",
Proxy: "Проксі",
"Date Created": "Дата створення",
onebotHttpAddress: "OneBot адреса HTTP",
onebotMessageType: "OneBot тип повідомлення",
onebotGroupMessage: "Група",
onebotPrivateMessage: "Приватне",
onebotUserOrGroupId: "Група/Користувач ID",
onebotSafetyTips: "Для безпеки необхідно встановити маркер доступу",
"PushDeer Key": "PushDeer ключ",
"Footer Text": "Текст нижнього колонтитула",
"Show Powered By": "Показувати платформу",
"Domain Names": "Доменні імена",
signedInDisp: "Ви ввійшли як {0}",
signedInDispDisabled: "Авторизація вимкнена.",
"Certificate Expiry Notification": "Сповіщення про закінчення терміну дії сертифіката",
"API Username": "Користувач API",
"API Key": "Ключ API",
"Recipient Number": "Номер одержувача",
"From Name/Number": "Від Ім'я/Номер",
"Leave blank to use a shared sender number.": "Залиште поле порожнім, щоб використовувати спільний номер відправника.",
"Octopush API Version": "Octopush API версія",
"Legacy Octopush-DM": "Legacy Octopush-DM",
"endpoint": "кінцева точка",
octopushAPIKey: "\"Ключ API\" з облікових даних HTTP API в панелі керування",
octopushLogin: "\"Ім'я користувача\" з облікових даних HTTP API на панелі керування",
promosmsLogin: "API Логін",
promosmsPassword: "API Пароль",
"pushoversounds pushover": "Pushover (по замовчуванню)",
"pushoversounds bike": "Bike",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic",
"pushoversounds falling": "Falling",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magic",
"pushoversounds mechanical": "Mechanical",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Siren",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (long)",
"pushoversounds climb": "Climb (long)",
"pushoversounds persistent": "Persistent (long)",
"pushoversounds echo": "Pushover Echo (long)",
"pushoversounds updown": "Up Down (long)",
"pushoversounds vibrate": "Vibrate Only",
"pushoversounds none": "None (silent)",
pushyAPIKey: "Секретний ключ API",
pushyToken: "Токен пристрою",
"Using a Reverse Proxy?": "Використовувати зворотній проксі?",
"Check how to config it for WebSocket": "Перевірте, як налаштувати його для WebSocket",
"Steam Game Server": "Ігровий сервер Steam",
"Most likely causes:": "Найімовірніші причини:",
"The resource is no longer available.": "Ресурс більше не доступний.",
"There might be a typing error in the address.": "Можливо, в адресі є помилка.",
"What you can try:": "Що ви можете спробувати:",
"Retype the address.": "Повторно введіть адресу.",
"Go back to the previous page.": "Повернутися на попередню сторінку.",
"Coming Soon": "Незабаром",
wayToGetClickSendSMSToken: "Ви можете отримати ім’я користувача API та ключ API з {0} .",
"Connection String": "Рядок підключення",
"Query": "Запит",
settingsCertificateExpiry: "Закінчення терміну дії сертифіката TLS",
certificationExpiryDescription: "Запуск сповіщення для HTTPS моніторів коли до закінчення терміну дії TLS сертифіката:",
"ntfy Topic": "ntfy Тема",
"Domain": "Домен",
"Workstation": "Робоча станція",
disableCloudflaredNoAuthMsg: "Ви перебуваєте в режимі без авторизації, пароль не потрібен.",
};

View File

@@ -404,6 +404,8 @@ export default {
TemplateCode: "TemplateCode",
SignName: "SignName",
"Bark Endpoint": "Bark 接入点",
"Bark Group": "Bark 群组",
"Bark Sound": "Bark 铃声",
"Device Token": "Apple Device Token",
Platform: "平台",
iOS: "iOS",
@@ -538,6 +540,45 @@ export default {
settingsCertificateExpiry: "TLS 证书过期通知",
certificationExpiryDescription: "HTTPS 监控项发现被监控目标的 TLS 证书剩余有效期少于以下天数时将发出通知:",
"ntfy Topic": "ntfy 主题",
"Domain": "域名",
"Workstation": "工作站",
Domain: "域名",
Workstation: "工作站",
resendEveryXTimes: "每 {0} 次失败则重复发送一次",
resendDisabled: "为 0 时禁用重复发送",
"Resend Notification if Down X times consequently": "连续失败时重复发送通知的间隔次数",
"HTTP Headers": "HTTP 头",
"Trust Proxy": "可信的代理类字段",
HomeAssistant: "Home Assistant",
RadiusSecret: "Radius 共享机密",
RadiusSecretDescription: "客户端和服务器之间共享的密钥",
RadiusCalledStationId: "NAS 网络访问服务器号码Called Station Id",
RadiusCalledStationIdDescription: "所访问的服务器的标识",
RadiusCallingStationId: "呼叫方号码Calling Station Id",
RadiusCallingStationIdDescription: "发出请求的设备的标识",
"Setup Docker Host": "配置 Docker 宿主信息",
"Connection Type": "连接方式",
"Docker Daemon": "Docker 守护进程",
deleteDockerHostMsg: "您确定您要删除此 Docker 宿主设置吗?这会影响所有 Docker 监控项",
socket: "Socket",
tcp: "TCP / HTTP",
"Docker Container": "Docker 容器",
"Container Name / ID": "容器名称 / ID",
"Docker Host": "Docker 宿主",
"Docker Hosts": "Docker 宿主",
disableCloudflaredNoAuthMsg: "您现在正处于 No Auth 模式,无需输入密码",
trustProxyDescription: "信任 'X-Forwarded-*' 头。如果您的 Uptime Kuma 是通过 Nginx 或 Apache 等反代服务对外提供访问的话,则您应当启用本功能以获取正确的客户端 IP。",
wayToGetLineNotifyToken: "您可以在 {0} 获取 Access token",
Examples: "例如",
"Home Assistant URL": "Home Assistant 地址",
"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. ": "长期访问令牌可通过点击左下角您的用户名,滚动到页面底部并点击 Create Token 按钮获取。",
"Notification Service": "Notification Service",
"default: notify all devices": "默认:通知所有设备",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "通知服务的列表可在 Home Assistant 中的 Developer Tools > Services 通过搜索您的设备或手机的名称来获得。",
"Automations can optionally be triggered in Home Assistant:": "可以在 Home Assistant 使用下列模板设置自动化操作的触发条件:",
"Trigger type:": "触发类型:",
"Event type:": "事件类型:",
"Event data:": "事件数据:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "然后您可以选择关联操作,例如切换到 RGB 灯发出红光的场景",
"Frontend Version": "前端版本",
"Frontend Version do not match backend version!": "前端版本与后端版本不符!",
};

View File

@@ -2,6 +2,8 @@ export default {
languageName: "繁體中文 (台灣)",
checkEverySecond: "每 {0} 秒檢查一次",
retryCheckEverySecond: "每 {0} 秒重試一次",
resendEveryXTimes: "每 {0} 次便重新傳送",
resendDisabled: "重新傳送已停用",
retriesDescription: "在服務被標記為離線並傳送通知前的最大重試次數",
ignoreTLSError: "忽略 HTTPS 網站的 TLS/SSL 錯誤",
upsideDownModeDescription: "反轉顯示狀態。若服務可以連線,將顯示離線。",
@@ -13,6 +15,7 @@ export default {
pauseDashboardHome: "暫停",
deleteMonitorMsg: "您確定要刪除此監測器嗎?",
deleteNotificationMsg: "您確定要為所有監測器刪除此通知嗎?",
dnsPortDescription: "DNS 伺服器連接埠。預設為 53。您可以隨時變更連接埠。",
resolverserverDescription: "Cloudflare 為預設伺服器。您可以隨時更換解析伺服器。",
rrtypeDescription: "選擇您想要監測的資源記錄類型",
pauseMonitorMsg: "您確定要暫停嗎?",
@@ -71,6 +74,7 @@ export default {
"Heartbeat Interval": "心跳間隔",
Retries: "重試次數",
"Heartbeat Retry Interval": "心跳重試間隔",
"Resend Notification if Down X times consequently": "若 X 次心跳皆離線,重新傳送通知",
Advanced: "進階",
"Upside Down Mode": "顛倒模式",
"Max. Redirects": "最大重新導向次數",
@@ -332,6 +336,8 @@ export default {
info: "資訊",
warning: "警告",
danger: "危險",
error: "錯誤",
critical: "嚴重",
primary: "主要",
light: "淺色",
dark: "暗色",
@@ -372,6 +378,13 @@ export default {
smtpDkimHashAlgo: "雜湊演算法 (選填)",
smtpDkimheaderFieldNames: "要簽署的郵件標頭 (選填)",
smtpDkimskipFields: "不簽署的郵件標頭 (選填)",
wayToGetPagerDutyKey: "您可以前往服務 -> 服務目錄 -> (選取服務) -> 整合 -> 新增整合以取得。您可以搜尋 \"Events API V2\"。詳細資訊 {0}",
"Integration Key": "整合金鑰",
"Integration URL": "整合網址",
"Auto resolve or acknowledged": "自動解決或認可",
"do nothing": "不進行任何操作",
"auto acknowledged": "自動認可",
"auto resolve": "自動解決",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "API 端點",
@@ -398,6 +411,8 @@ export default {
SignName: "SignName",
"Sms template must contain parameters: ": "Sms 範本必須包含參數:",
"Bark Endpoint": "Bark 端點",
"Bark Group": "Bark 群組",
"Bark Sound": "Bark 鈴聲",
WebHookUrl: "WebHookUrl",
SecretKey: "SecretKey",
"For safety, must use secret key": "為了安全起見,必須使用秘密金鑰",
@@ -443,6 +458,8 @@ export default {
"Message:": "訊息:",
"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.": "如果您目前正透過 Cloudflare Tunnel 連線,可能會導致連線中斷。您確定要停止嗎?請輸入密碼以確認。",
"HTTP Headers": "HTTP 標頭",
"Trust Proxy": "信任的 Proxy",
"Other Software": "其他軟體",
"For example: nginx, Apache and Traefik.": "例如 nginx、Apache 和 Traefik。",
"Please read": "請閱覽",
@@ -455,6 +472,7 @@ export default {
"Domain Name Expiry Notification": "網域名稱到期通知",
Proxy: "Proxy",
"Date Created": "建立日期",
HomeAssistant: "Home Assistant",
onebotHttpAddress: "OneBot HTTP 位址",
onebotMessageType: "OneBot 訊息類型",
onebotGroupMessage: "群組",
@@ -465,4 +483,103 @@ export default {
"Footer Text": "頁尾文字",
"Show Powered By": "顯示技術支援文字",
"Domain Names": "網域名稱",
signedInDisp: "以 {0} 身分登入",
signedInDispDisabled: "驗證已停用。",
RadiusSecret: "Radius Secret",
RadiusSecretDescription: "客戶端與伺服器端的共享機密",
RadiusCalledStationId: "被叫站 Id",
RadiusCalledStationIdDescription: "被呼叫裝置的識別碼",
RadiusCallingStationId: "呼叫站 Id",
RadiusCallingStationIdDescription: "呼叫裝置的識別碼",
"Certificate Expiry Notification": "憑證到期通知",
"API Username": "API 使用者名稱",
"API Key": "API 金鑰",
"Recipient Number": "收件者號碼",
"From Name/Number": "來自名字/號碼",
"Leave blank to use a shared sender number.": "留空以使用共享寄件人號碼。",
"Octopush API Version": "Octopush API 版本",
"Legacy Octopush-DM": "舊版 Octopush-DM",
"endpoint": "端",
octopushAPIKey: "在控制台的 HTTP API 憑證取得的 \"API 金鑰\"",
octopushLogin: "在控制台的 HTTP API 憑證取得的 \"Login\"",
promosmsLogin: "API 登入名稱",
promosmsPassword: "API 密碼",
"pushoversounds pushover": "Pushover (預設)",
"pushoversounds bike": "車鈴",
"pushoversounds bugle": "號角",
"pushoversounds cashregister": "收銀機",
"pushoversounds classical": "古典",
"pushoversounds cosmic": "宇宙",
"pushoversounds falling": "下落",
"pushoversounds gamelan": "甘美朗",
"pushoversounds incoming": "來電",
"pushoversounds intermission": "中場休息",
"pushoversounds magic": "魔法",
"pushoversounds mechanical": "機械",
"pushoversounds pianobar": "鋼琴酒吧",
"pushoversounds siren": "警鈴",
"pushoversounds spacealarm": "太空鬧鐘",
"pushoversounds tugboat": "汽笛",
"pushoversounds alien": "外星鬧鐘 (長)",
"pushoversounds climb": "爬升 (長)",
"pushoversounds persistent": "持續 (長)",
"pushoversounds echo": "Pushover 回音 (長)",
"pushoversounds updown": "上下 (長)",
"pushoversounds vibrate": "僅震動",
"pushoversounds none": "無 (靜音)",
pushyAPIKey: "API 密鑰",
pushyToken: "裝置權杖",
"Show update if available": "顯示可用更新",
"Also check beta release": "檢查 Beta 版",
"Using a Reverse Proxy?": "正在使用反向代理?",
"Check how to config it for WebSocket": "查看如何為 WebSocket 設定",
"Steam Game Server": "Steam 遊戲伺服器",
"Most likely causes:": "可能原因:",
"The resource is no longer available.": "資源已不可用。",
"There might be a typing error in the address.": "網址可能有誤。",
"What you can try:": "您可以嘗試:",
"Retype the address.": "重新輸入網址。",
"Go back to the previous page.": "返回上一頁。",
"Coming Soon": "即將推出",
wayToGetClickSendSMSToken: "您可以從 {0} 取得 API 使用者名稱和金鑰。",
"Connection String": "連線字串",
Query: "查詢",
settingsCertificateExpiry: "TLS 憑證到期",
certificationExpiryDescription: "TLS 將於 X 天後到期時觸發 HTTPS 監測器通知:",
"Setup Docker Host": "設定 Docker 主機",
"Connection Type": "連線類型",
"Docker Daemon": "Docker 精靈",
deleteDockerHostMsg: "您確定要為所有監測器刪除此 Docker 主機嗎?",
socket: "通訊端",
tcp: "TCP / HTTP",
"Docker Container": "Docker 容器",
"Container Name / ID": "容器名稱 / ID",
"Docker Host": "Docker 主機",
"Docker Hosts": "Docker 主機",
"ntfy Topic": "ntfy 主題",
Domain: "網域",
Workstation: "工作站",
disableCloudflaredNoAuthMsg: "您處於無驗證模式。無須輸入密碼。",
trustProxyDescription: "信任 'X-Forwarded-*' 標頭。如果您想要取得正確的客戶端 IP且您的 Uptime Kuma 架設於 Nginx 或 Apache 後方,您應啟用此選項。",
wayToGetLineNotifyToken: "您可以從 {0} 取得存取權杖",
Examples: "範例",
"Home Assistant URL": "Home Assistant 網址",
"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. ": "若要建立長期有效存取權杖,請點擊您的個人檔案名稱 (左下角),捲動至最下方,然後點擊建立權杖。",
"Notification Service": "通知服務",
"default: notify all devices": "預設:通知所有服務",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "您可以在 Home Assistant 中查看通知服務的列表,在\"開發者工具 > 服務\"下搜尋\"通知\"來找到您的裝置/手機的名稱。",
"Automations can optionally be triggered in Home Assistant:": "可以選擇在 Home Assistant 中觸發自動化程序:",
"Trigger type:": "觸發器類型:",
"Event type:": "事件類型:",
"Event data:": "事件資料:",
"Then choose an action, for example switch the scene to where an RGB light is red.": "然後選擇動作,例如切換至 RGB 燈為紅色的場景。",
"Frontend Version": "前端版本",
"Frontend Version do not match backend version!": "前端版本與後端版本不符!",
"Base URL": "基底網址",
goAlertInfo: "GoAlert 是用於待命排程、升級自動化,以及通知 (如簡訊或語音通話) 的開源應用程式。自動在正確的時間、用洽當的方法、聯絡合適的人! {0}",
goAlertIntegrationKeyInfo: "取得服務的通用 API 整合金鑰,格式為 \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"。通常是已複製的網址的權杖參數值。",
goAlert: "GoAlert",
backupOutdatedWarning: "過時:由於新功能的增加,且未妥善維護,故此備份功能無法產生或復原完整備份。",
backupRecommend: "請直接備份磁碟區或 ./data/ 資料夾。",
};

View File

@@ -77,7 +77,7 @@
<!-- Mobile Only -->
<div v-if="$root.isMobile" style="width: 100%; height: 60px;" />
<nav v-if="$root.isMobile" class="bottom-nav">
<nav v-if="$root.isMobile && $root.loggedIn" class="bottom-nav">
<router-link to="/dashboard" class="nav-link">
<div><font-awesome-icon icon="tachometer-alt" /></div>
{{ $t("Dashboard") }}

Some files were not shown because too many files have changed in this diff Show More