Compare commits

..

1423 Commits

Author SHA1 Message Date
Louis Lam
6ccf741bc4
Merge pull request #2632 from chakflying/fix/docker-timeout
Fix: Use default timeout & CachebleDnsHttpsAgent for docker monitor
2023-01-19 19:26:40 +08:00
Louis Lam
0a58069742
Merge pull request #2641 from louislam/1.19.X
Merge 1.19.6 to 1.20.X
2023-01-19 14:27:45 +08:00
Louis Lam
2b57b3e863 Update to 1.19.6 2023-01-19 02:17:17 +08:00
Louis Lam
6cd6a2edf0 Fix ping issue on Windows #2636 2023-01-19 02:16:07 +08:00
Nelson Chan
6961b1bdd2 Fix: Use default timeout & CachebleDnsHttpsAgent 2023-01-18 09:53:04 +08:00
Louis Lam
54d4c4d3f7 Merge package-lock.json 2023-01-17 21:18:13 +08:00
Louis Lam
c47b6c5995 Merge remote-tracking branch 'origin/1.19.X'
# Conflicts:
#	package-lock.json
#	package.json
#	src/util-frontend.js
2023-01-17 21:17:04 +08:00
Louis Lam
7ef404ccc1 Update to 1.19.5 2023-01-17 20:32:44 +08:00
Louis Lam
a5ff27da7a Drop the property monitor.maintenance, use lastHeartBeat.status to check status instead 2023-01-17 17:34:47 +08:00
Louis Lam
7bb12a7e00 Fix #2608 2023-01-17 17:25:35 +08:00
Louis Lam
27585d0812 Fix #2618 2023-01-17 01:21:01 +08:00
Louis Lam
e675316635
Merge pull request #2586 from PopcornPanda/fix-2544
Fix: Allow long sms in PromoSMS
2023-01-16 13:21:56 +08:00
Louis Lam
b073ec2287 Add Help button which links to wiki 2023-01-16 12:39:24 +08:00
Louis Lam
31f45dcfc9
Merge pull request #2540 from twiggotronix/add-mqtt-schemes
Add mqtt, mqtts, ws and wss protocols to the mqtt monitor
2023-01-15 20:14:11 +08:00
Louis Lam
49ac71e25c
Merge pull request #2549 from Computroniks/docs/update-jsdoc-2023-01-05
Added missing JSDoc comments
2023-01-15 13:10:17 +08:00
Louis Lam
1a9b013fc2
Merge pull request #2328 from rmarops/mongodb-ping
added MongoDB ping monitor
2023-01-15 01:43:43 +08:00
Louis Lam
1326761a8a Update mongodb and simplify the logic of mongodbPing 2023-01-15 01:36:49 +08:00
Louis Lam
e48a987b9c Merge remote-tracking branch 'origin/master' into mongodb-ping
# Conflicts:
#	server/model/monitor.js
#	server/util-server.js
#	src/pages/EditMonitor.vue
2023-01-15 01:13:11 +08:00
Louis Lam
712a3c29d4 Fix Postgres monitor do not handle some error cases correctly 2023-01-14 21:06:10 +08:00
Louis Lam
e9497ac1ab Fix knex.js issue 2023-01-14 20:49:34 +08:00
Louis Lam
6437ef198f
Merge pull request #2541 from long2ice/master
feat: support redis monitor
2023-01-14 20:16:53 +08:00
Louis Lam
973d5692d0
Merge pull request #2604 from black23/patch-1
Update cs-CZ.js
2023-01-14 13:04:41 +08:00
Louis Lam
468cb004d6
Merge pull request #1690 from chakflying/feat/tags-manager
Feat: Tags Manager
2023-01-13 23:29:01 +08:00
Louis Lam
f7d41a30fa
Update src/components/TagEditDialog.vue
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-13 23:15:41 +08:00
black23
0ef686ac2f
Update cs-CZ.js
new string
2023-01-13 14:52:03 +01:00
long2ice
3b5893ea60 fix: add preserve line in redisPingAsync 2023-01-13 21:30:10 +08:00
long2ice
21cd4d64c3 fix: redisPingAsync 2023-01-13 19:10:07 +08:00
long2ice
db757123ba refactor: reuse databaseConnectionString 2023-01-13 16:32:49 +08:00
Louis Lam
4dcf31621e
Update README.md 2023-01-13 15:34:48 +08:00
Nelson Chan
9c1ba97e7d Chore: Fix typo 2023-01-12 21:25:33 +08:00
Nelson Chan
e9564619f1 Feat: Implement tags manager in settings
Fix: Remove unused color options

Chore: Fix typo
2023-01-12 21:25:33 +08:00
Łukasz Szczepański
8433bceb32 Trim message to maximum allowed length 2023-01-12 08:14:31 +01:00
Louis Lam
98d001b38b
Merge pull request #2575 from Joseph-Irving/victorops_notifications
Add Splunk Notification Provider
2023-01-12 14:15:36 +08:00
Louis Lam
d9f12a6376 Fallback to /bin/ping if ping is not found 2023-01-12 01:05:16 +08:00
Łukasz Szczepański
56ba133a1f Missing semicolon 2023-01-11 14:36:33 +01:00
Łukasz Szczepański
ec30147a7f Add option for allowing long sms in PromoSMS 2023-01-11 14:32:57 +01:00
David Twigger
2bc165379a Add unit test for hostNameRegexPattern 2023-01-11 13:28:30 +01:00
Luke
2172112144
Setting for allowing long sms 2023-01-11 12:13:47 +01:00
Luke
ecd661c801
Allow long sms in PromoSMS 2023-01-11 12:06:09 +01:00
twiggotronix
8fab7112a1
Merge branch 'louislam:master' into add-mqtt-schemes 2023-01-11 10:34:24 +01:00
Louis Lam
cc4ed308b0
Merge pull request #2581 from twiggotronix/add-frontend-unit-tests
Add frontend unit tests
2023-01-11 13:36:20 +08:00
Louis Lam
362280af14
Merge pull request #2578 from DimitriDR/master
Updating French localization
2023-01-10 22:48:20 +08:00
David Twigger
636fc8fcfc Fix workflow 2023-01-10 08:43:39 +01:00
David Twigger
1c05ba09dc Add cypress unit tests to workflow 2023-01-10 08:24:15 +01:00
David Twigger
1565da87cf Implement cypress unit testing 2023-01-10 08:18:48 +01:00
DimitriDR
890e3abf58 Updating French localization
Signed-off-by: DimitriDR <dimitridroeck@gmail.com>
2023-01-09 21:09:57 +01:00
Joseph Irving
33355c51b7 Add Splunk Notifications 2023-01-09 13:33:10 +00:00
Louis Lam
5f5c2d7c46 Update to 1.19.4 2023-01-09 21:02:57 +08:00
Louis Lam
71f4ab0aa6 Improve dockerfile 2023-01-09 21:01:45 +08:00
Louis Lam
24d1dd4c34 [auto-test] Drop Node.js 17, add 19 2023-01-09 20:24:20 +08:00
Louis Lam
c00abac834 Separate golang build layer 2023-01-09 13:43:08 +08:00
Louis Lam
439f963749
Merge pull request #2569 from Computroniks/bug/2565-negative-retention-value
Fixed negative retention time values
2023-01-09 13:08:35 +08:00
Louis Lam
f15c6470af
Merge pull request #2543 from SlothCroissant/master
Removed redundant title in Pushover notification
2023-01-09 12:50:55 +08:00
Matthew Nickson
32f7a0084a
Fixed negative retention time values
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-08 19:09:06 +00:00
SlothCroissant
f8658d6160 Removed redundant title in Pushover notification 2023-01-08 10:32:16 -06:00
Louis Lam
d596f8f7eb
Merge pull request #2560 from DimitriDR/master
Adding translations for Kook & ZohoCliq
2023-01-08 14:03:35 +08:00
Louis Lam
23a525e36a
Update CONTRIBUTING.md 2023-01-08 00:42:15 +08:00
Louis Lam
221d1d40f5
Update CONTRIBUTING.md 2023-01-08 00:32:13 +08:00
Louis Lam
60ec87941e
Merge pull request #2552 from MrEddX/bulgarian
Update bg-BG.js
2023-01-08 00:10:18 +08:00
DimitriDR
e8e4361e09 Adding translations for Kook & ZohoCliq 2023-01-07 13:10:25 +01:00
Matthew Nickson
675806829c
Changed wording for safeDelete function JSDoc 2023-01-06 17:17:37 +00:00
Louis Lam
21c1921867
Update server/uptime-kuma-server.js
Co-authored-by: 琚致远 / Zhiyuan Ju <juzhiyuan@apache.org>
2023-01-06 23:04:02 +08:00
David Twigger
e490ec6d29 move hostname regex pattern function to frontend-utils 2023-01-06 11:00:20 +01:00
MrEddX
7ad4392529
Update bg-BG.js
Translation Updated
2023-01-06 09:00:45 +02:00
Louis Lam
f3d3e064f8
Merge pull request #2538 from deluxghost/master
Updated zh-CN.js
2023-01-06 10:46:37 +08:00
Louis Lam
80c91b8234
Merge pull request #2546 from Computroniks/bug/#2419-padding-around-clear-data-dropdown
Fixed #2419 Styling of clear data dropdown
2023-01-06 10:34:55 +08:00
Matthew Nickson
dc8289df12
Added JSDoc for src/
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-05 22:55:51 +00:00
Matthew Nickson
caff9ca736
Added JSDoc for server/
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-05 22:19:05 +00:00
Matthew Nickson
c7eb72e73b
JSDoc for extra/
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-05 19:57:28 +00:00
Matthew Nickson
fc5ec5f492
Fixed styling of clear data dropdown
Fixed #2419

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-05 19:24:29 +00:00
long2ice
40ebc2df79 feat: support redis monitor 2023-01-05 23:02:56 +08:00
David Twigger
abf5e435fe move to utility function 2023-01-05 14:48:12 +01:00
David Twigger
8a372201f1 clean up 2023-01-05 14:23:05 +01:00
twiggotronix
8ec240fe19
Merge branch 'louislam:master' into add-mqtt-schemes 2023-01-05 14:08:05 +01:00
David Twigger
5362aab0e5 specify scheme for mqtt monitor type only 2023-01-05 14:06:13 +01:00
Louis Lam
bc7271b99c
Merge pull request #2372 from SirMorfield/docker-compose
Fix spelling in README
2023-01-05 21:04:01 +08:00
Louis Lam
4ebf5a5f07
Update README.md 2023-01-05 21:03:28 +08:00
Louis Lam
fbceefec36
Merge pull request #2223 from Computroniks/feature/remove-hardcoded-ping-path
feat: Change ping module to danielzzz/node-ping
2023-01-05 20:40:41 +08:00
Louis Lam
0b959514f8 Fix timeout 2023-01-05 20:38:37 +08:00
Louis Lam
4c5e2ea237
Update CONTRIBUTING.md 2023-01-05 20:03:28 +08:00
Louis Lam
7d92351568 Match previous settings 2023-01-05 19:30:55 +08:00
Louis Lam
494c53971c Convert to UTF8 on Windows only 2023-01-05 19:22:15 +08:00
David Twigger
fc1914bccd Fix lint 2023-01-05 11:42:19 +01:00
Louis Lam
4239cf4255 Pin dependency of ping 2023-01-05 17:11:37 +08:00
David Twigger
c196c34840 Add mqtt, mqtts, ws and wss protocols to the mqtt monitor 2023-01-05 08:57:48 +01:00
DX
554402b484 Updated zh-CN.js 2023-01-05 15:38:51 +08:00
Louis Lam
b049e4e1b4
Merge pull request #2534 from furkanipek/tr-lang-update
Update tr-TR.js
2023-01-05 14:21:30 +08:00
Matthew Nickson
90a2668272
Restructured condition + ensure data is UTF-8
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-04 17:32:27 +00:00
Louis Lam
49b5de7d40 Update Apprise to 1.2.1 2023-01-05 00:48:49 +08:00
Matthew Nickson
69e1880cd3
Added not active condition to prevent false error
Added a check to see if the host is alive. This prevents failiures when
the user specifies a hostname of `unknown`.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2023-01-04 16:46:36 +00:00
Furkan İpek
610b6248aa Update tr-TR.js 2023-01-04 16:41:00 +03:00
Furkan İpek
e591647b60 Update tr-TR.js 2023-01-04 16:35:48 +03:00
Louis Lam
da99833d4c
Merge pull request #2528 from chakflying/fix/tag-validation
Fix: Fix incorrect add tag form validation
2023-01-04 16:11:05 +08:00
Louis Lam
4bf23fdd1a Update jsonwebtoken from ~8 to ~9 2023-01-04 15:55:36 +08:00
Louis Lam
f99a64da67 Run npm update 2023-01-04 15:48:09 +08:00
Louis Lam
2e022789f6
Merge pull request #2527 from chakflying/fix/docker-down
Fix: Fix incorrect handling for container down
2023-01-04 15:33:59 +08:00
Matthew Nickson
73835f3328
Changed from ping-lite to ping module
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>

#Fixes 2126
2023-01-03 20:03:36 +00:00
Matthew Nickson
4819112e25
Merge remote-tracking branch 'origin/master' into feature/remove-hardcoded-ping-path 2023-01-03 19:10:17 +00:00
Joppe Koers
2d3fd738e4 Fix small spelling mistake 2023-01-03 15:37:32 +01:00
Nelson Chan
edd8fe2e22 Fix: Fix incorrect tag form validation 2023-01-03 22:18:45 +08:00
Nelson Chan
204792dd2d Fix: Fix incorrect handling for container down 2023-01-03 22:07:14 +08:00
Louis Lam
b8e8c1b9db Update to 1.19.3 2023-01-03 18:05:19 +08:00
Louis Lam
0cead83705 Fix #2516 2023-01-03 14:50:41 +08:00
Louis Lam
7b0093b8b3
Merge pull request #2514 from lionep/patch-1
Improve french translation
2023-01-03 13:14:25 +08:00
lionep
cd7e362b81
Improve french translation
Set "Not available, please setup" translation more accurate, because it's in use in notifications and proxies page.
2023-01-02 08:46:42 +01:00
Arniwatt Chonkiattipoom
a8af2a418e
Slack notification block not working (#1958)
* [empty commit] pull request for slack notification

* Add attachments block for slack notification

* chore: update action button in new attachment block

* chore: loop in attachments to push blocks

* chore: missing semicolon

Co-authored-by: pruekanw <arniwatt.c@linecorp.com>
2023-01-02 15:01:50 +08:00
Louis Lam
39ac9b887e Fix #2504 2023-01-01 22:27:14 +08:00
Louis Lam
28c3291020
Merge pull request #2513 from louislam/revert-2433-mathias/Auth-case-insensitive-login
Revert "Auth: Case insensitive login check on username"
2023-01-01 22:19:27 +08:00
Louis Lam
50711391d1
Revert "Auth: Case insensitive login check on username" 2023-01-01 22:19:00 +08:00
Louis Lam
e88e10cc8e Fix #2494 2023-01-01 21:43:54 +08:00
Louis Lam
27146ffeef
Merge pull request #2433 from mathiash98/mathias/Auth-case-insensitive-login
Auth: Case insensitive login check on username
2023-01-01 14:16:59 +08:00
Louis Lam
41a9f2ff8a
Merge pull request #2495 from minhhoangvn/fix/update-service-name-grpc
Bug fix: gRPC check throws errors when response data size > 50 chars
2023-01-01 13:57:10 +08:00
Louis Lam
cd7a6e4019
Merge pull request #2478 from YehowahLiu/master
Add Kook notification provider
2023-01-01 02:53:03 +08:00
Louis Lam
8bb064c6fa
Merge pull request #2157 from Mikkel-T/fix-discord-embed
Improve the URL field in Discord embeds
2022-12-31 22:41:40 +08:00
Louis Lam
1006fbd873 A possible fix for #2447 2022-12-30 13:46:53 +08:00
Louis Lam
5554432b31
Merge pull request #2377 (Zoho Cliq Notification Provider)
Zoho Cliq Notification Provider
2022-12-29 19:00:50 +08:00
minhhoang
d111db0321 fix: add accurate error message when user input invalid service name or method name 2022-12-29 08:10:58 +07:00
minhhoang
4147a4c404 fix: #2480 2022-12-28 22:31:33 +07:00
Louis Lam
8c684e9293
Update SECURITY.md 2022-12-28 19:59:33 +08:00
Louis Lam
f025de6eaf
Merge pull request #2490 from 5idereal/patch-1
update zh-TW.js
2022-12-28 18:17:10 +08:00
5idereal
7f394d0630
update zh-TW.js 2022-12-28 17:29:46 +08:00
Louis Lam
9fe9e235ca
Merge pull request #2236 from mishankov/fix/stats-30-days
Simple fix for Uptime component
2022-12-28 15:37:46 +08:00
401Unauthorized
50b84f5f45
fix code style: add missing semicolon 2022-12-27 14:12:22 +08:00
401Unauthorized
c60b741406
Add kook notification provider 2022-12-27 14:12:22 +08:00
thefourCraft
f6ea1fe9a5
he-IL (#2460) 2022-12-27 14:04:53 +08:00
Louis Lam
b7e3ec2372
Merge pull request #2476 from DimitriDR/master
Huge improvement for French localization.
2022-12-27 14:02:25 +08:00
DimitriDR
625fd7c2aa Huge improvement for French localization. 2022-12-27 01:02:43 +01:00
Louis Lam
aec80b53d5 Update to 1.19.2 2022-12-27 00:22:52 +08:00
Louis Lam
06852bbf0d Fix the UI broken after removed a monitor 2022-12-27 00:22:09 +08:00
Louis Lam
056d957c1e Update to 1.19.1 2022-12-26 23:49:20 +08:00
Louis Lam
e12225e595 Fix #2475 #2468 #2455, add Accept-Encoding only if encountered the abort error 2022-12-26 21:00:46 +08:00
Louis Lam
1b6c587cc9 Fix #2472 2022-12-26 14:46:29 +08:00
Louis Lam
4a1db336df
Merge pull request #2465 from augustin64/patch-1
(fr) Fix typo
2022-12-25 19:18:46 +08:00
Augustin
9e9c5cd1d2
(fr) Fix typo 2022-12-24 19:41:55 +01:00
Louis Lam
1e689d99b4
Merge pull request #2393 from zImPatrick/discord-docker-fix
Fix discord notification not sending when docker container goes down
2022-12-24 14:26:53 +08:00
Louis Lam
14fffcf06b Globally fix if heartbeatJSON["msg"] is undefined 2022-12-24 14:23:50 +08:00
Louis Lam
6962e056ce Update to 1.19.0 2022-12-23 22:44:49 +08:00
Louis Lam
b7a898326e
Merge pull request #2437 from MrEddX/bulgarian
Update bg-BG.js
2022-12-19 20:22:47 +08:00
MrEddX
a89be0e6d4
Update bg-BG.js
Translation Update
2022-12-19 13:37:42 +02:00
Mathias Haugsbø
b3ac7c3d43 Username case insensitive, patch db instead of using LIKE 2022-12-19 12:18:33 +01:00
Mathias Haugsbø
c79b2913a2 Auth: Case insensitive login check on username
Allows users to add users with capital letters and then login with just lowercase letters.

We accidentally capitalized the first letter of our username so the other people using it frequently thinks they wrote the wrong password.
2022-12-18 17:16:19 +01:00
Louis Lam
b58b83541b
Merge pull request #2428 from rbunpat/master
Update th-TH.js
2022-12-18 15:40:40 +08:00
Cyril59310
df4f91c20d
Update EN language (#2429)
* Update EN language
2022-12-18 15:39:54 +08:00
Rachatat Bunpat
fc6b040a4e
Update th-TH.js 2022-12-17 17:34:03 +07:00
Louis Lam
9838f36b50
Merge pull request #2418 from Johno95CZ/patch-1
Update cs-CZ.js
2022-12-17 17:44:55 +08:00
Louis Lam
a60072adbc
Merge pull request #2423 from rbunpat/master
Update th-TH.js
2022-12-17 17:43:51 +08:00
Louis Lam
e7aeb6f6bf
Merge pull request #2422 from Justman10000/master
Update
2022-12-17 17:43:25 +08:00
Rachatat Bunpat
06e570c52d
Update th-TH.js 2022-12-16 19:15:14 +07:00
Justman10000
890b8f8333 Updated German 2022-12-16 10:42:41 +00:00
Louis Lam
df21f7da76 Check login for initServerTimezone 2022-12-16 12:56:40 +08:00
Joppe Koers
3ea6711053 Remove docker compose again 2022-12-15 23:03:06 +01:00
JohnoCZ
20c37a70f7
Update cs-CZ.js 2022-12-15 14:35:59 +01:00
Louis Lam
b75db27658 Fix lint 2022-12-15 13:57:28 +08:00
Louis Lam
765d8e1297 Fix #2318 2022-12-15 13:39:48 +08:00
Louis Lam
9dc2cc1f0d Copy timezone.js from dayjs 2022-12-15 13:05:04 +08:00
Louis Lam
2532becf61 Update to 1.19.0-beta.2 2022-12-14 23:37:00 +08:00
Louis Lam
6154776b34
Merge pull request #2409 from Justman10000/master
Update
2022-12-14 22:39:00 +08:00
Louis Lam
7e6b92203d
Merge pull request #2406 from MrEddX/bulgarian
Bulgarian
2022-12-14 22:38:13 +08:00
Louis Lam
1da00d19fd Try to fix incorrect header check 2022-12-14 21:34:13 +08:00
Justman10000
da4bdab4f6 Updated german 2022-12-14 13:16:32 +00:00
MrEddX
86ab97ef56
Update bg-BG.js
Translation Update
2022-12-14 09:56:28 +02:00
MrEddX
345b0c1829
Update bg-BG.js
Fixed Style
2022-12-14 09:49:31 +02:00
MrEddX
2ac87fcea7
Update bg-BG.js
Fixed Typos
2022-12-14 09:26:43 +02:00
Cyril59310
4862bec965
Update Fr language + added variable for missing translation (#2395)
* Update FR language
2022-12-13 22:00:54 +08:00
Louis Lam
aa784fb3b2 Fix #2394 2022-12-13 16:48:23 +08:00
Louis Lam
466b403a96 Handle unexpected error of checkCertificate 2022-12-13 02:21:12 +08:00
zImPatrick
f32441e2f6 fix discord notification not sending when docker container is down 2022-12-12 18:05:10 +01:00
Louis Lam
39987ba9ac Init server timezone 2022-12-12 22:57:57 +08:00
Louis Lam
3b87209e26 Add configurable dns cache 2022-12-12 17:19:22 +08:00
Louis Lam
e6dc0a0293 Slightly improve maintenance page's css on mobile 2022-12-12 16:06:17 +08:00
Louis Lam
5c5a339a36 Add links for status pages and maintenance for mobile (Fix #2257) 2022-12-12 15:54:46 +08:00
Louis Lam
3040bd41d9 Speed up armv7 build time of healthcheck by using go compiler cross-build feature in the host 2022-12-12 15:42:00 +08:00
Louis Lam
3b58fd3b3c Cache uptime 2022-12-11 21:33:26 +08:00
Louis Lam
bc86f8bb5f Reset busy_timeout to default 2022-12-11 20:25:15 +08:00
Louis Lam
ab5f6dc82c Fix css 2022-12-11 18:52:24 +08:00
Louis Lam
5176fd02c1 Fix healthcheck do not check https 2022-12-10 23:30:32 +08:00
Louis Lam
02b5cae577 Fix #2371 by left join maintenance_timeslot 2022-12-09 21:03:12 +08:00
Louis Lam
54aa7d5dca Merge remote-tracking branch 'origin/master' 2022-12-08 23:22:09 +08:00
Louis Lam
4cd5b5563f Fix #1145 2022-12-08 23:21:55 +08:00
Louis Lam
f1c30204b6
Merge pull request #2373 from saw303/master
Fixed some typos in the German translations 🇩🇪🇨🇭
2022-12-08 23:01:48 +08:00
panos
9da28fbbc7 zoho cliq code style 2022-12-08 13:56:02 +02:00
panos
851a04b082 zoho cliq code style 2022-12-08 13:53:02 +02:00
panos
68bc7ac421 zoho cliq code style 2022-12-08 13:41:05 +02:00
panos
73bfdb9ef9 zoho cliq notification provider 2022-12-08 13:32:10 +02:00
Louis Lam
e478084ff9 Fix Uptime Kuma cannot be stopped 2022-12-08 19:13:47 +08:00
Louis Lam
2dff7dd380 Make dockerfile slightly clear and improve the build flow 2022-12-08 18:29:17 +08:00
Louis Lam
9bfa43100b Compile healthcheck.go 2022-12-08 18:29:17 +08:00
Louis Lam
ad5e1957b1 Deprecate healthcheck.js 2022-12-08 18:29:17 +08:00
Louis Lam
cc68ebca39 Convert healthcheck.js into go-lang 2022-12-08 18:29:17 +08:00
Silvio Wangler
aa27d976c2
Fixed some typos in the German translations 🇩🇪🇨🇭 2022-12-07 09:10:05 +01:00
Louis Lam
ecbc0f0477
Merge pull request #2369 from saw303/master
Added new language German (Switzerland)
2022-12-07 15:14:52 +08:00
Joppe Koers
f8c7da7995 Add docker-compose to README 2022-12-06 18:44:16 +01:00
Joppe Koers
f3660a0cec Fix spelling in README 2022-12-06 18:43:28 +01:00
Silvio Wangler
92caec95fe
Added new language German (Switzerland) 2022-12-06 13:43:37 +01:00
Louis Lam
2c3abdc146
[stale-bot] Do not close pr 2022-12-05 20:11:28 +08:00
Louis Lam
b1170211b7 Update to 1.19.0-beta.1 2022-12-05 19:24:04 +08:00
Louis Lam
eadf2c810a Fix check version 2022-12-05 19:17:24 +08:00
Louis Lam
8aa97635ec Improve the clear filter button 2022-12-05 18:21:16 +08:00
Louis Lam
ee1a56caae Update /test-webhook and reevaluate sensitive fields 2022-12-05 18:18:19 +08:00
Louis Lam
e886df4788 Fix typo 2022-12-05 17:55:45 +08:00
Louis Lam
5196abfd36 Merge remote-tracking branch 'origin/master' into feat/add-auth-header-to-webhook-notification-#1919 2022-12-05 17:52:02 +08:00
Louis Lam
3e68cf2a1c Specify Accept-Encoding for axios request (Fix #2253) 2022-12-04 22:55:05 +08:00
Louis Lam
0ab82e6de3 Generate random nightly version 2022-12-04 22:44:50 +08:00
Louis Lam
8cdbe37f6f Update core-js 2022-12-04 21:41:08 +08:00
Louis Lam
28d13e198c
Merge pull request #2350 from MrEddX/bulgarian
Bulgarian
2022-11-26 20:52:33 +08:00
MrEddX
14a062804e
Update bg-BG.js
- Translation fixes
2022-11-25 22:00:52 +02:00
MrEddX
cf3e03ab40
Update bg-BG.js
- Added new  fields
- Translated new fields
- Fixed some typos
2022-11-25 21:56:00 +02:00
Louis Lam
191f3ad53b
Merge pull request #2339 from jbrunner/fix-2296
Add socks5h support
2022-11-25 16:24:21 +08:00
Louis Lam
370d522920 Pin dependency of axios-ntlm to 1.3.0. As 1.3.1 causes error 2022-11-25 14:00:33 +08:00
Louis Lam
e0a1ad8a1c Update dependencies and drop start-server-watch-dev as it is unstable 2022-11-25 01:32:33 +08:00
Louis Lam
9720006934
Merge pull request #2151 from Computroniks/feature/#1817-add-mysql-monitor
Feat  Add MySQL/MariaDB monitor #1817
2022-11-25 01:27:40 +08:00
Joshua Brunner
cd270bd8b5 Add socks5h support
Add socks5h support as an extra option to not break previous socks5 implementation.
Allows to toggle between socks5 and socks5h explicit.

Fixes #2296
2022-11-22 11:18:16 +01:00
Louis Lam
bc3229828e Merge remote-tracking branch 'origin/master' 2022-11-20 00:11:38 +08:00
Louis Lam
a5f23b9839 Update Apprise from 1.0 to 1.2 2022-11-20 00:07:19 +08:00
Matthew Nickson
2052fa175f
Merge branch 'master' into feature/#1817-add-mysql-monitor
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-11-17 19:04:14 +00:00
Matthew Nickson
15b63c82c3
Merge remote-tracking branch 'upstream/master' into feature/#1817-add-mysql-monitor
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-11-17 18:46:58 +00:00
Matthew Nickson
b053bc61ce
Fixed MySQL monitor to close connection
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-11-17 18:34:02 +00:00
rmarops
0e30843a75 fixed lint check missing semicolon 2022-11-16 22:27:18 -05:00
rmarops
2103edb604 moved client close out of finally block and fixed linting errors 2022-11-16 22:21:15 -05:00
rmarops
b059a36e66 added MongoDB ping monitor 2022-11-16 20:50:34 -05:00
Jan Hartje
258ff56962
Merge branch 'louislam:master' into feat/add-auth-header-to-webhook-notification-#1919 2022-11-14 20:17:36 +01:00
Louis Lam
cb4e512dc6
Merge pull request #2316 from Dafnik/patch-fix-link-preview-description
Fix 'undefined' in link preview generation
2022-11-15 02:37:28 +08:00
Dafnik
4042c26390 Fix 'undefined' in link preview generation 2022-11-14 18:05:52 +01:00
Louis Lam
5da2315534
Merge pull request #2310 from Ealrang/patch-1
Update zh-CN.js
2022-11-14 22:02:43 +08:00
Ealrang
204015f1f5
Update zh-CN.js
Correct typos
2022-11-12 22:15:04 +08:00
Louis Lam
cc6d17d2e0
Merge pull request #1964 from minhhoangvn/feat/add-gRPC-protocol
Feat/add gRPC protocol
2022-11-11 12:34:35 +08:00
Louis Lam
68862c0b3f Fix Pushbullet do not handle general message correctly and fix name convention (Close #1890) 2022-11-01 20:27:40 +08:00
Louis Lam
fd15e7c2dc Merge remote-tracking branch 'origin/master' into ntfy-icon
# Conflicts:
#	server/notification-providers/ntfy.js
#	src/components/notifications/Ntfy.vue
#	src/languages/en.js
2022-10-31 17:10:20 +08:00
Louis Lam
5c4cf68937
Merge pull request #2260 from m-kiszka/smseagle
Added support for SMSEagle device API notifications
2022-10-31 17:03:34 +08:00
Louis Lam
214ddc264d Fix mistake 2022-10-29 23:40:09 +08:00
Louis Lam
2ea71839d1 Add npm run start-server-watch-dev for watching server code changes and restart (Node.js 19 only) 2022-10-29 23:37:05 +08:00
Louis Lam
54efde8185 Update socket.io and remove an useless event listener 2022-10-29 23:29:33 +08:00
Louis Lam
705124d4ac
Merge pull request #2274 from 5idereal/patch-1
update zh-tw translation
2022-10-28 16:50:24 +08:00
5idereal
1cb6940590
update zh-tw translation 2022-10-28 15:50:00 +08:00
Louis Lam
0f8ad288f3
Merge pull request #2255 from b-reich/update-german-translation
Add german translations
2022-10-27 16:47:11 +08:00
Adam Stachowicz
434174d350
I18n PL update (#2264)
* [PL] Only formatting by ESLint for now

* Translate new i18n keys to polish + small grammar/typo fixes

* ESLint again after npm install...
2022-10-27 16:46:32 +08:00
minhhn3
3d1237ed53 fix: resolve conflict 2022-10-26 20:50:34 +07:00
minhhn3
b459408b10 fix: resolve conflict 2022-10-26 20:41:21 +07:00
Benjamin Reich
f04fe4d230 add new german translations 2022-10-25 10:50:58 +02:00
Louis Lam
e579610426
Merge pull request #2265 from Saibamen/patch-1
Add info about `npm install` to translators
2022-10-25 14:32:43 +08:00
Louis Lam
b115d3f8b9
Merge pull request #2266 from Saibamen/fix_linters
Fix 'dayjs' is never used warning
2022-10-25 14:23:59 +08:00
Adam Stachowicz
134b3b8ac1 Fix 'dayjs' is never used warning 2022-10-25 01:27:25 +02:00
Adam Stachowicz
e7e7751e7b
Correct order 2022-10-24 23:38:38 +02:00
Adam Stachowicz
5cd58e6fa3
Add info about npm install to translators
Without this, you can have wrong indentation from ESLint
2022-10-24 23:36:21 +02:00
Marcin Kiszka
08763b700a Added support for SMSEagle device API notifications 2022-10-24 12:45:56 +02:00
Marcin Kiszka
781f855921 [empty commit] pull request for Added support for SMSEagle device API notifications 2022-10-24 12:44:29 +02:00
Louis Lam
9e81fe120f
Merge pull request #2235 from dave9123/patch-3
Update id-ID.js
2022-10-20 15:57:39 +08:00
Denis Mishankov
7313aa6563 fix spaces 2022-10-17 20:36:52 +03:00
Denis Mishankov
c7871427c3 compute title value 2022-10-17 20:20:51 +03:00
Dave
c0e67b6de9
Update id-ID.js 2022-10-17 20:09:25 +07:00
Louis Lam
a17084f75d
Merge pull request #2229 from falentio/fix-id-lang
fix typos in id lang
2022-10-16 16:25:35 +08:00
Louis Lam
e4fe7b802a
Update bg-BG.js #2228 2022-10-16 16:24:39 +08:00
falentio
5761bc9b90 fix typos in id lang 2022-10-16 13:49:25 +07:00
MrEddX
92ea019fd4
Update bg-BG.js
- Added new  fields
- Translated new fields
2022-10-16 07:21:23 +03:00
Cyril59310
a774b37369
Update FR language + fixed daytime error (#2226)
* Update FR language

* fix a daytime error + add for translation

* Update language file FR + fixed daytime error
2022-10-16 01:42:28 +08:00
Louis Lam
06755f249d Update to 1.19.0-beta.0 2022-10-15 21:02:56 +08:00
Louis Lam
64f84eb118 Update Details.vue's button styles 2022-10-15 21:01:48 +08:00
Louis Lam
afe12ccf24
A complete maintenance planning system (#1213)
A complete maintenance planning system from karelkryda/master
2022-10-15 20:54:28 +08:00
Louis Lam
6f4424de28 Remove unused language keys 2022-10-15 20:44:02 +08:00
Louis Lam
24cb212a37 Fix recurring 2022-10-15 20:15:50 +08:00
Louis Lam
d8a676abb6 Implement recurring day of month and day of week 2022-10-15 18:49:09 +08:00
Louis Lam
0b8d4cdaac Generate Next Timeslot for recurring interval 2022-10-15 17:17:26 +08:00
Louis Lam
268cbdbf8d Merge remote-tracking branch 'origin/master' into maintenance
# Conflicts:
#	server/server.js
#	src/components/settings/General.vue
2022-10-15 15:57:39 +08:00
Louis Lam
b60dde0b2d Update SQLite 2022-10-15 15:18:54 +08:00
Louis Lam
aecf95864e Add index for maintenance tables 2022-10-14 13:26:41 +08:00
Louis Lam
c662d259b0
Firefox Better Support #2206 2022-10-13 19:28:02 +08:00
Matthew Nickson
6b47ad07ca
[empty commit] pull request for #2126 remove hardcoded ping 2022-10-12 22:03:05 +01:00
Matthew Nickson
f459ea845c
Added #2182 Add support for custom radius ports (#2197)
This commit adds support for the port to be specified when using the
radius monitor type. A check has been implemented to ensure that a null
value is not passed to the radius check function as could occur with
monitors that were created before this change was introduced. The
default port of 1812 is displayed when the user selects the radius
monitor in much the same way as the DNS port is handled. The port was
not included in the hostname in the form hostname:port in order to avoid
issues with IPv6 addresses and monitors that had been created before
this change was implemented.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-13 00:32:05 +08:00
Louis Lam
b24c75eec5
Merge pull request #2162 from UltraWelfare/fix-entry-page-redirect
Fixed entry route not redirecting correctly.
2022-10-13 00:28:34 +08:00
MagicFun1241
cb5f90aa89
Update Russian locale (#2218)
* Update ru-RU.js

* Remove duplicates

* Remove duplicates x2

* Revert to previous version for one translation

* Removed conflicting lines

* Remove conflicting 'Reverse Proxy' key
2022-10-13 00:27:50 +08:00
Louis Lam
edacff123b Add UTC in the serverTimezone dropdown 2022-10-12 22:13:07 +08:00
Louis Lam
2faf866e9e Implement generateTimeslot() for recurring interval type 2022-10-12 17:02:16 +08:00
Louis Lam
8cc3e4b7c1 Revert 2022-10-11 22:28:00 +08:00
Louis Lam
7b9766091e Revert testing 2022-10-11 22:18:09 +08:00
Louis Lam
d95e722658 Init dayjs for backend.spec.js 2022-10-11 22:09:18 +08:00
Louis Lam
39b6725163 Update maintenance tables 2022-10-11 21:48:43 +08:00
Louis Lam
dfb75c8afb Update status page's maintenance message 2022-10-11 20:56:48 +08:00
Louis Lam
e07aa982c3 WIP 2022-10-11 18:23:17 +08:00
Christian Meis
1e8a16504b Make icon optional for ntfy notificaation provider. Add Icon header to ntfy request only, if icon is actually defined. 2022-10-11 11:15:33 +02:00
Alexander Borzov
180d881ac1
Update ru-RU.js (#2217) 2022-10-11 15:35:08 +08:00
Louis Lam
2271ac4a5a Add info.serverTimezoneOffset and improve some styles 2022-10-11 14:52:47 +08:00
Louis Lam
f6bbd1ca67 Merge remote-tracking branch 'origin/master' into maintenance 2022-10-11 14:13:08 +08:00
Louis Lam
2ee8378814 Update to 1.18.5 2022-10-11 02:32:57 +08:00
Louis Lam
d5c02fc627 Update Maintenance list order by status 2022-10-11 01:59:47 +08:00
Louis Lam
c84de4d259 WIP: Add maintenance status 2022-10-11 01:45:30 +08:00
Louis Lam
c1ccaa7a9f WIP 2022-10-10 20:48:11 +08:00
Louis Lam
539683f8e9 Merge remote-tracking branch 'origin/master' into maintenance 2022-10-10 16:50:25 +08:00
Louis Lam
bd42450e55 Update vue-i18n from 9.1.9 to 9.2.2, force to use production version of vue-i18n in order to improve the performance 2022-10-10 16:23:32 +08:00
Louis Lam
71af23cf00 Fix #2207 2022-10-10 02:47:24 +08:00
Louis Lam
a577fba848 Change DateTime Range using serverTimezone 2022-10-10 02:28:03 +08:00
Louis Lam
a36f24d827 Add configurable server timezone 2022-10-09 20:59:58 +08:00
Louis Lam
b007681e67 Merge remote-tracking branch 'origin/master' into karelkryda_master
# Conflicts:
#	server/model/monitor.js
#	server/model/status_page.js
#	src/languages/en.js
2022-10-09 19:26:00 +08:00
Louis Lam
07f9aafd7b Update to 1.18.4 2022-10-09 16:50:47 +08:00
Louis Lam
1c8631af8d
Pin dependencies (#2205) 2022-10-09 16:02:47 +08:00
Louis Lam
0d2e02f569
Merge pull request #2190 from VasilisThePikachu/master
Adding Greek Language
2022-10-09 02:48:32 +08:00
Louis Lam
ad1a7c255f Drop exports.entryPage fully 2022-10-08 23:56:58 +08:00
Kevin Falentio
230e5110b1
Fix typo in id-ID language file (#2202) 2022-10-08 20:59:22 +08:00
Matthew Nickson
f67d7cdf3f
Make update-language-files command more useful (#2198)
* [empty commit] pull request for Fix language update script

* Avoid mass changes with update-language-files

This commit updates the update-language-files script to prevent mass
changes as seen on a number of recent PRs where the contributer has
ran the script and comitted the results.
The script has been updated to now require the --language argument to
specify which language file to update. This ensures that only that file
is updated instead of all files. If the provided language code does not
already exist, a new file with that code is created. This should make
it easier to add new languages as you only need to pass the language
code to the script.
The base lang code is now also passed as an optional argument to negate
the need for a seperate script entry in package.json.
The script has been restructures into a couple of functions to make it
easier to understand.
ESlint now only checks the changed file instead of
them all in order to improve performance.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>

* Updated translation docs for new command

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>

* [update-language-files] Add cross-env-shell

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-10-08 15:01:47 +08:00
wellart
df2f536845
[id-ID.js] Fix some type and word (#2149)
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-08 02:15:03 +08:00
Vasilis The Pikachu
59e7aa74a3 Remove some double dots & fix backuprecommended 2022-10-07 17:51:45 +00:00
AnnAngela
43c1ec640c
feat: 🌐 Update zh-cn and en translation (#2167)
Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-10-08 01:45:00 +08:00
Louis Lam
4f6dec41c6 Fix ntfy username should not be required 2022-10-07 20:46:43 +08:00
Vasilis The Pikachu
e29527e22f
Update Greek 2022-10-07 11:33:29 +02:00
Vasilis The Pikachu
91f9e10c94
Merge branch 'louislam:master' into master 2022-10-07 10:55:42 +02:00
Vasilis The Pikachu
7d3cc002ea Added greek language 2022-10-07 08:55:12 +00:00
Louis Lam
6e07ed2081 Fix #2186 2022-10-07 15:02:19 +08:00
Louis Lam
60460442f8 Update to 1.18.3 2022-10-07 00:25:34 +08:00
Louis Lam
959ecc65ff Merge remote-tracking branch 'origin/master' 2022-10-06 23:28:29 +08:00
Louis Lam
c24b64921d Fix #2183 ntfy issue 2022-10-06 23:28:06 +08:00
janhartje
b879428a03
feat(notification): add additional Header to webhook 2022-10-05 17:48:07 +02:00
Ben Scobie
c28d8ddff9
Correctly handle multiple IPs in X-Forwarded-For (#2177)
Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-10-05 23:45:21 +08:00
janhartje
3c5de1c889 Merge branch 'master' of https://github.com/louislam/uptime-kuma into feat/add-auth-header-to-webhook-notification-#1919 2022-10-05 16:44:13 +02:00
CL0Pinette
528a615fb2
Add free.fr SMS notification provider (#2159) 2022-10-05 17:30:49 +08:00
Louis Lam
b993859926
Drop Jest e2e testing (#2174) 2022-10-05 14:26:30 +08:00
Louis Lam
a5c102e750
Update README.md 2022-10-05 14:19:50 +08:00
Cyril59310
64ba2dce24
Update FR language (#2173) 2022-10-05 13:57:38 +08:00
Louis Lam
e5145a209a Update cypress config 2022-10-05 13:29:03 +08:00
Louis Lam
12696dd53e
Update README.md 2022-10-05 12:54:25 +08:00
Muhammed Hussein karimi
d565320f74
New Demo Server (#2172)
Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2022-10-05 12:53:58 +08:00
Sympatron GmbH
f1a9046193
Prevent terminal window from showing when using ping on Windows (#2152) 2022-10-04 23:30:19 +08:00
Louis Lam
afbc283423
Move Cypress directory and convert it to JavaScript (#2170) 2022-10-04 22:23:57 +08:00
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
George Tsomlektsis
3e699f8ac3 Fix linting errors. 2022-10-03 18:01:52 +03:00
George Tsomlektsis
b0d6b5b13d Fixed entry route not redirecting correctly when the status entry page changes slug. 2022-10-03 17:48:34 +03: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
Mikkel-T
a42f7416b5 Improve the URL field in Discord embeds
Instead of having two different ways of showing the URL field in Discord embeds, always show the raw address.
2022-10-02 19:29:33 +02: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
f9be918246
Add support for MySQL/MariaDB databases #1817
This commit adds support for monitoring MySQL and MariaDB database
servers. The mysql2 package was choosen over mysql as it provides a
promise wrapper and is reportedly faster than the original mysql package
whilst still maintaining the same API.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-02 01:52:53 +01:00
Matthew Nickson
314ae38f91
Changed name of SQL Server to avoid confusion
It appears that SQL Server causes some confusion among users as they
believe that it means any SQL database, not the Microsoft product SQL
Server. To avoid this issue, the display value has been changed to
Microsoft SQL Server. No backend changes have been made and it is still
stored as sqlserver in the database. This is only a frontent change.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-10-01 21:35:33 +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
Christian Meis
c03d911657
Update src/languages/en.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-09-28 11:39:13 +02:00
Christian Meis
e12642cf21 Fix double quotes in fallback for no icon url in ntfy notification provider settings 2022-09-28 10:24:56 +02:00
Christian Meis
618d904001 [empty commit] pull request for icon support in ntfy notification provider (fixes #2135) 2022-09-28 10:17:02 +02:00
Christian Meis
6f86236b63 Add support for icon to ntfy notification provider (requires minimum ntfy server version 1.28.0 and Android app 1.14.0, no iOS support as of today) 2022-09-28 10:13:18 +02:00
Louis Lam
204339fbed Make two functions to convert ISO 8601 <=> YYYY-MM-DD hh:mm:ss 2022-09-28 00:48:15 +08:00
Louis Lam
b1465c0282 - Maintenance standardize datetime format to YYYY-MM-DD hh:mm:ss
- Import dayjs extensions one time only
- Maintenance activeCondition centralize
2022-09-28 00:20:17 +08:00
Louis Lam
4002b9f577 [WIP] Checking maintenance time using maintenance_timeslot table 2022-09-27 20:44:44 +08: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
3f63cb246b [WIP] Handle timezone offset for timeRange 2022-09-25 19:38:28 +08: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
f11dfc8f43 [WIP] Add/Edit Maintenance with new UI and recurring 2022-09-24 19:18:24 +08:00
Louis Lam
9d99c39f30 Update Maintenance UI for recurring 2022-09-24 02:33:29 +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
617ba49e6c Fix race condition of selectedStatusPagesOptions 2022-09-18 22:40:53 +08:00
Louis Lam
7853c2cc38 Update Maintenance UI 2022-09-18 22:34:05 +08:00
Louis Lam
f61c1c47aa Update Maintenance UI 2022-09-18 02:13:29 +08:00
Louis Lam
9fe07742ea Linting 2022-09-18 02:07:32 +08:00
Louis Lam
a29eae3213 Update Maintenance UI 2022-09-18 02:02:18 +08:00
Louis Lam
80698a58b8 Tidy up 2022-09-17 22:09:09 +08:00
Louis Lam
bb883e6fa0 Move maintenance under /maintenance 2022-09-17 22:00:11 +08:00
Louis Lam
120e578398 Move maintenance code to maintenance-socket-handler.js 2022-09-17 16:58:08 +08:00
Louis Lam
7017c2e625 Move maintenance code to maintenance-socket-handler.js 2022-09-17 16:54:21 +08:00
Louis Lam
2f67d26702 Merge manually, as this part had been moved 2022-09-17 16:20:10 +08:00
Louis Lam
90761cf831 Merge remote-tracking branch 'origin/master' into karelkryda_master
# Conflicts:
#	server/database.js
#	server/model/monitor.js
#	server/routers/api-router.js
#	server/server.js
#	src/components/HeartbeatBar.vue
#	src/components/MonitorList.vue
#	src/icon.js
#	src/layouts/Layout.vue
#	src/mixins/datetime.js
#	src/mixins/socket.js
#	src/router.js
#	src/util.js
2022-09-17 16:12:57 +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
68875c3091 Fix merging issue 2022-09-13 22:22:01 +08:00
Louis Lam
f35d7c0a1a Merge remote-tracking branch 'origin/master' into feat/add-gRPC-protocol
# Conflicts:
#	package-lock.json
2022-09-13 22:19:41 +08: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
minhhn3
3a90d246a4 fix: wrong type 2022-08-20 22:45:11 +07:00
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
minhhn3
6bb79597e8 fix: resolve merge conflict 2022-08-13 13:26:05 +07: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
minhhn3
34ab6142db fix: remove new space line 2022-08-08 19:38:43 +07: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
minhhn3
2232236a7a [empty commit] pull request for add gRPC protocol 2022-08-03 13:39:31 +07:00
Minh Hoàng
dcecd10c88
Feat/add gRPC protocol (#1)
* feat: added monitor with gRPC

Co-authored-by: minhhn3 <minhhn3@vng.com.vn>
2022-08-03 12:00:39 +07: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
Jan Hartje
af07c7f050 feat(notification): add Authorization Header option to backend 2022-07-18 16:04:27 +00:00
Jan Hartje
95dba6dcaf feat(notification): add Authorization Header option to frontend 2022-07-18 16:04:18 +00:00
Jan Hartje
90c2bf7c94 [empty commit] pull request for #1919 2022-07-18 15:56:53 +00: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
Louis Lam
d5da5af174 Update to 1.17.0 2022-06-22 20:13:39 +08:00
Louis Lam
c36d9a4b8b Fix port data type #1802 2022-06-21 22:33:09 +08:00
Louis Lam
a7063b8aca Fix logo height in the status page list 2022-06-21 15:46:22 +08:00
Louis Lam
0a8046c98e Merge remote-tracking branch 'origin/master' 2022-06-21 15:12:37 +08:00
Louis Lam
7ba717ee55 Fix Lunasea do not handle general message correctly #1790 2022-06-21 15:12:24 +08:00
Louis Lam
ea400ac35f
Merge pull request #1795 from MrEddX/bulgarian
Update bg-BG.js
2022-06-20 21:50:00 +08:00
Louis Lam
15db2c060d
Merge pull request #1791 from Saibamen/patch-1
Update README for i18n
2022-06-20 21:49:42 +08:00
MrEddX
89717495dc
Update bg-BG.js
Added and translated new fields
2022-06-20 11:52:12 +03:00
Adam Stachowicz
7b710af12c
Update README for i18n
Related: https://github.com/louislam/uptime-kuma/pull/1777
2022-06-19 21:17:03 +02:00
Louis Lam
5b278ca500 Add a description that certification expiry have to be assigned to a monitor 2022-06-19 20:57:52 +08:00
Matthew Nickson
f1d24782f8
Merge branch 'master' into feature/#1221-clickable-hostaname-on-status-page 2022-06-18 23:53:35 +01:00
Louis Lam
b97019eea8 Fix cloudflared cannot be stopped in No Auth mode due to password checking 2022-06-18 19:06:03 +08:00
Louis Lam
d65abe5b8c
Merge pull request #1777 from MarcHagen/change/move_translations_to_i18n
[change] Move i18n from Security to locale files
2022-06-18 17:17:06 +08:00
Robert
c4e2d67d17
fix: hide mobile header when not logged in 2022-06-17 10:11:53 +03:00
Louis Lam
bcd616a4d0
Fix names in CONTRIBUTING.md 2022-06-17 15:07:55 +08:00
Louis Lam
7533041696
Merge pull request #1784 from AnnAngela/master
Update i18n for en & zh-CN
2022-06-17 13:30:47 +08:00
Louis Lam
7b0deb5e20
Merge pull request #1785 from MrEddX/bulgarian
Update bg-BG.js
2022-06-17 13:30:18 +08:00
MrEddX
b4a4171178
Update bg-BG.js
Translation fixes.
2022-06-16 21:08:17 +03:00
AnnAngela-work
012be23509 Update i18n 2022-06-16 21:20:12 +08:00
Louis Lam
dd09351c8e Update to 1.17.0-beta.1 2022-06-16 19:34:47 +08:00
Louis Lam
ffad990ca4
Merge pull request #1773 from christopherpickering/patch-3
[beta] updated translation for "basic" auth
2022-06-16 14:37:05 +08: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
Marc Hagen
f7afe121e3 [change] Move i18n to locale files 2022-06-15 19:41:21 +02: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
Christopher Pickering
42848bcd2e
updated translations 2022-06-15 09:00:47 -05:00
Louis Lam
a3b94aa532
Merge pull request #1550 from Computroniks/jsdoc-for-src
JSDoc for src/*/*
2022-06-15 19:29:51 +08:00
Louis Lam
fdbdf83a0d Fix data type of notification.isDefault and notification.active (#1765) 2022-06-15 19:11:52 +08:00
Louis Lam
81d5360520 Merge remote-tracking branch 'origin/master' 2022-06-15 19:03:22 +08:00
Louis Lam
8f1e193de3 [vite] Change legacy browse target to since 2015 2022-06-15 19:02:55 +08:00
Moritz R
ac449ec1c2
Merge branch 'master' into master 2022-06-15 11:33:00 +02:00
Louis Lam
da91317760
Merge pull request #1772 from chakflying/fix/mobile-monitor-list
Fix: Fix monitor list layout on mobile
2022-06-15 15:50:04 +08:00
Louis Lam
bef0febede
Merge pull request #1768 from christopherpickering/patch-1
[beta] prevent null workstation #'s from passing..
2022-06-15 15:33:03 +08:00
Louis Lam
7d63b700e1
Merge pull request #1767 from christopherpickering/patch-2
[beta] workstation field should be text, not password
2022-06-15 15:31:24 +08:00
Louis Lam
0223f86a2a Merge remote-tracking branch 'origin/master' 2022-06-15 15:18:29 +08:00
Louis Lam
c170b1edd0 Better optgroup text color 2022-06-15 15:18:14 +08:00
Louis Lam
5943514a92
Merge pull request #1771 from christopherpickering/master
[beta] added default value for sql server connection string
2022-06-15 14:08:48 +08:00
Nelson Chan
62acd2edb1 Fix: misc. layout fix on mobile 2022-06-14 22:43:44 +08:00
Christopher Pickering
483cbfb636
added default value for sql server connection string 2022-06-14 09:00:23 -05:00
Christopher Pickering
660005b143
cleaned up code 2022-06-14 08:49:36 -05:00
Christopher Pickering
98f3c126e5
passed lint 2022-06-14 07:58:35 -05:00
sur.la.route
6995a29980
workstation field should be text, not password 2022-06-14 07:45:04 -05:00
sur.la.route
cf2ca71dee
prevent null workstation #'s from passing..
to axios-ntlm
2022-06-14 07:42:53 -05:00
Louis Lam
0bd1c42080
Merge pull request #1763 from chakflying/fix/cert-exp-setting-default
Fix: Fix missing certificate exp. notif. default
2022-06-14 17:27:45 +08:00
Louis Lam
9b21b86e70
Merge pull request #1762 from kaysond/master
Fix upside down push monitors
2022-06-14 17:25:32 +08:00
Nelson Chan
f723930d11 Fix: Unify design with Security page 2022-06-14 15:04:46 +08:00
Nelson Chan
e425e408a2 Fix: Fix missing default settings 2022-06-14 15:04:14 +08:00
Aram Akhavan
c690d1c3a1 fix timeout bypass for upside down push monitor 2022-06-13 22:05:58 -07:00
Louis Lam
8abbc9fd15 Update to 1.17.0-beta.0 2022-06-14 11:00:55 +08:00
Louis Lam
af7c905b44
Merge pull request #1759 from MrEddX/bulgarian
Bulgarian
2022-06-14 10:57:14 +08:00
Louis Lam
0e8f6d2f85
Merge pull request #1639 from christopherpickering/ntml-auth
Add NTML Auth Option for HTTP
2022-06-14 10:56:55 +08:00
Louis Lam
d16be6fb7d Fix and use null as authMethod None instead of empty string 2022-06-14 10:49:30 +08:00
Louis Lam
f25ca96308 Update package-lock.json 2022-06-14 10:37:15 +08:00
Louis Lam
6682839ec8 Merge remote-tracking branch 'origin/master' into ntml-auth
# Conflicts:
#	package-lock.json
#	package.json
#	server/database.js
#	server/model/monitor.js
#	server/server.js
#	server/util-server.js
2022-06-14 10:36:29 +08:00
Louis Lam
817f6db4fd Remove SQL Server code (which in another pr already) 2022-06-14 10:32:38 +08:00
Louis Lam
dc2302244f
Merge pull request #1754 from SIMULATAN/patch-1
Remove template comment in SECURITY.md
2022-06-14 10:22:08 +08:00
MrEddX
7a27d3752a
Merge branch 'louislam:master' into bulgarian 2022-06-13 22:36:00 +03:00
MrEddX
f0e8f34aeb
Update bg-BG.js
Added new fields
2022-06-13 22:32:55 +03:00
Super Manito
54b9698a05 Update 2022-06-13 21:44:10 +08:00
Louis Lam
69273a6c41 Merge remote-tracking branch 'origin/master' 2022-06-13 21:16:03 +08:00
Louis Lam
6424fe77ab Change successful log from info to debug in order to avoid large log and less disk usage 2022-06-13 21:15:47 +08:00
Louis Lam
fa60672cce
Merge pull request #1728 from tamasmagyar/test/simplify-discord-unit-tests
test: simplified discord unit tests
2022-06-13 21:02:12 +08:00
Louis Lam
6e43ef1dd3 Merge remote-tracking branch 'origin/master' into feat/cert-exp-settings
# Conflicts:
#	server/model/monitor.js
#	src/languages/en.js
2022-06-13 20:56:14 +08:00
Louis Lam
f4f2b8ddb8 Try to fix #1658 2022-06-13 19:24:05 +08:00
Louis Lam
436bc13aeb
Merge pull request #1598 from gregdev/feature/axios-cached-dns-resolve
add axios cached dns resolve to monitor
2022-06-13 18:58:16 +08:00
Louis Lam
b72a279361 Update package-lock.json 2022-06-13 18:54:02 +08:00
Louis Lam
a28ef56553 Merge remote-tracking branch 'gregdev/feature/axios-cached-dns-resolve' into feature/axios-cached-dns-resolve
# Conflicts:
#	package-lock.json
#	package.json
2022-06-13 18:53:19 +08:00
Louis Lam
7f432bd916 Remove axios-cached-dns-resolve-test 2022-06-13 18:52:08 +08:00
Louis Lam
f570d41142 Merge remote-tracking branch 'origin/master' into feature/axios-cached-dns-resolve
# Conflicts:
#	package-lock.json
#	package.json
2022-06-13 18:50:43 +08:00
Super Manito
1c4ddaeddf Update 2022-06-13 18:17:47 +08:00
Louis Lam
d4485fe62f Make the monitor type list a bit clear 2022-06-13 18:14:47 +08:00
Louis Lam
e1681ce370
Merge pull request #1636 from christopherpickering/master
Add SQLServer Monitor
2022-06-13 18:03:56 +08:00
Jakob
69d6633e6d
Remove template comment 2022-06-13 11:34:36 +02: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
Louis Lam
04e22f17a9 Merge remote-tracking branch 'origin/master' into christopherpickering_master
# Conflicts:
#	package-lock.json
#	src/languages/en.js
2022-06-11 20:59:58 +08:00
Wooferz
aa398948da
Merge branch 'louislam:master' into patch-1 2022-06-11 09:41:03 +10:00
Louis Lam
11243a6ca1
Merge pull request #1222 from NETivism/issue-1201
Show some pure text body in notification when keyword not found
2022-06-09 19:33:10 +08:00
Wooferz
54548e34ed
Added label to status badge 2022-06-08 20:05:10 +10:00
Louis Lam
87428231ad
Merge pull request #1727 from chakflying/patch-2
Fix: Fix error when status page desc. is null
2022-06-07 16:45:28 +08:00
tamasmagyar
a68d945cdc simplified backend unit tests 2022-06-07 09:10:50 +02:00
Nelson Chan
2c0180f323
Fix: Fix error when status page desc. is null 2022-06-07 14:57:23 +08:00
Louis Lam
4fdaa1abb6 [Push API] Response 404 if error, fix #1721 2022-06-06 22:40:26 +08:00
Louis Lam
6ee7b3696a
Merge pull request #1633 from domingospanta/bugfix/1451_blank_page_on_unkown_resource
Bugfix/1451 blank page on unkown resource
2022-06-06 21:54:49 +08:00
Louis Lam
cc258dce14
Merge pull request #1674 from philippdormann/feature/ntfy-support
feat: ntfy push support
2022-06-06 21:52:41 +08:00
Louis Lam
fb420fa1b1 Compress SVG when building dist 2022-06-05 23:49:48 +08:00
Louis Lam
a707b51053
Page Loading Speed Optimization (#1711)
* Update Vite.js to 2.9.9 and add Rollup Plugin Visualizer
* Prebuild gzip and brotli for assets

Original: ~1.2MB
Optimized: ~370KB
2022-06-05 23:43:25 +08:00
Matthew Nickson
a927f5cd15
Fixed typos + improved clarity and detail of some JSDoc
Apply suggestions from code review

Co-authored-by: Nelson Chan <chakflying@hotmail.com>
2022-06-02 16:40:56 +01:00
Matthew Nickson
0e28707307
Minor formatting for JSDoc comments
Added a number of minor formatting changes to JSDoc comments in /src
2022-06-02 15:15:21 +01:00
Matthew Nickson
c94dcf1533
Added JSDoc for src/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-02 14:32:38 +01:00
Matthew Nickson
b0476cfb5b
Added JSDoc for src/pages/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-02 13:46:44 +01:00
Matthew Nickson
2170229031
Improve JSDoc for some components
Apply suggestions from code review

Co-authored-by: Nelson Chan <chakflying@hotmail.com>
2022-06-02 10:42:37 +01:00
Matthew Nickson
213aca4fc3
Added JSDoc for src/mixins/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-02 10:38:17 +01:00
Matthew Nickson
2b42c3c828
Added JSDoc for src/components/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-02 00:32:05 +01:00
Matthew Nickson
d939d03690
Added JSDoc for src/components/settings/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-06-01 23:44:10 +01:00
Matthew Nickson
07888e43f1
[empty commit] pull request for JSDoc src/* 2022-06-01 22:51:26 +01:00
Louis Lam
c6c1bb5b5c
Merge pull request #1710 from AnnAngela/master
Update zh-CN translation
2022-06-01 16:05:23 +08:00
Louis Lam
3210264e28
Update PULL_REQUEST_TEMPLATE.md 2022-06-01 14:20:49 +08:00
Louis Lam
54e948c2ca
Update CONTRIBUTING.md 2022-06-01 14:08:10 +08:00
Louis Lam
80094ec4e1
Merge pull request #1513 from louislam/status-page-inject-html
[Status Page] Render title, meta tag or favicon etc. in server side
2022-06-01 13:25:41 +08:00
Louis Lam
091158cfe7 [Status Page] Preload data 2022-06-01 13:05:12 +08:00
AnnAngela-work
abb6ce2366 Update zhCN translation 2022-06-01 11:28:10 +08:00
Louis Lam
e4ad8cbfc8 Remove unused variables 2022-05-31 23:06:43 +08:00
Louis Lam
a674caa520 [Status Page] Add og meta tags 2022-05-31 22:53:48 +08:00
Nelson Chan
179e3569b5 Chore: Add code comments 2022-05-31 16:24:39 +08:00
Karel Krýda
fa777c5bc0
Update server/server.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-05-30 15:32:42 +02:00
Karel Krýda
6d0683b055
Update server/routers/api-router.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-05-30 15:32:19 +02:00
Karel Krýda
25262cfb91
Update server/model/monitor.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-05-30 15:31:45 +02:00
Nelson Chan
43527f2f40 Chore: Update remaining languages 2022-05-30 18:05:28 +08:00
Nelson Chan
26ff6f45a0 Feat: Use i18n pluralization 2022-05-30 17:53:32 +08:00
Louis Lam
c095767f4a [Status Page] SSR 2022-05-30 15:45:44 +08:00
Louis Lam
ffb7ba176c Merge remote-tracking branch 'origin/master' into status-page-inject-html 2022-05-30 14:00:39 +08:00
Louis Lam
857e88b27e Update to 1.16.1 2022-05-29 12:47:07 +08:00
Louis Lam
90fe25e8ad
Merge pull request #1428 from kaysond/master
Synchronize push monitor heartbeats to api calls (fixes #1422)
2022-05-29 12:34:16 +08:00
Louis Lam
46a593534b
Merge pull request #1695 from furkanipek/update-tr-lang
Update tr-TR.js
2022-05-29 12:13:52 +08:00
Louis Lam
7a4b54f4ee
Merge pull request #1702 from dhfhfk/master
Update Ko-KR.js
2022-05-29 12:12:07 +08:00
Aram Akhavan
ea10d89f51 show correct down message for first tick 2022-05-28 19:57:45 -07:00
Louis Lam
7f46223d68 Fix another log.debug call 2022-05-28 23:22:44 +08:00
Louis Lam
df4ce811d9 Merge remote-tracking branch 'origin/master' into kaysond_master
# Conflicts:
#	server/model/monitor.js
2022-05-28 23:19:58 +08:00
Louis Lam
30858ab038 Fix rollback issue of 9fc5a33 and one issue of #1694 2022-05-28 23:08:14 +08:00
dhfhfk
e25d406fa5
Eslint 2022-05-28 17:12:40 +09:00
dhfhfk
10e16782b1
Update ko-KR.js 2022-05-28 17:10:40 +09:00
Furkan İpek
107a44885c Update tr-TR.js 2022-05-27 15:05:09 +03:00
Furkan İpek
ef9f66fad9 Update tr-TR.js 2022-05-27 15:02:40 +03:00
Moritz R
e9e78c26e5
Merge branch 'master' into master 2022-05-27 13:59:58 +02:00
Furkan İpek
46dae99695 Update tr-TR.js 2022-05-27 12:51:41 +03:00
Furkan İpek
edd9bf3887 Update tr-TR.js 2022-05-27 12:39:07 +03:00
Aram Akhavan
ab4edf2092
Fix log.debug calls 2022-05-26 21:45:56 -07:00
Louis Lam
334cb57fed Update to 1.16.0 2022-05-26 19:32:52 +08:00
Nelson Chan
cfa5b551a5 Feat: Make the expiry days sorted 2022-05-26 12:17:24 +08:00
Nelson Chan
46ee149b70 Chore: Slightly improve design 2022-05-26 12:12:29 +08:00
Louis Lam
0a8c922abf Fix default value of pagerduty-integration-url 2022-05-25 23:34:47 +08:00
Louis Lam
058e5442af
Merge pull request #1310 from MarcHagen/feature/pagerduty
Add support for PagerDuty notifications
2022-05-25 23:26:33 +08:00
Louis Lam
ea1725737f
Merge pull request #1687 from burakurer/patch-3
Update tr-TR.js
2022-05-25 23:24:10 +08:00
burakurer
5566b038c8
Update tr-TR.js 2022-05-25 17:35:05 +03:00
Marc Hagen
5830f1e0b5 [feat] Adding PagerDuty notification 2022-05-25 14:10:31 +02:00
Louis Lam
35b8e89457
Merge pull request #1473 from Computroniks/#1059-specify-dns-resolver-port
Added #1059: Allow to specify Resolver Port for DNS Monitor
2022-05-25 14:59:14 +08:00
Louis Lam
d892b2c549
Merge pull request #1686 from DasCanard/master
Improved Discord Notifications with Push Monitors
2022-05-25 14:57:25 +08:00
DasCanard
f23baf9c22 Added Push Monitor to Discord Notifications 2022-05-24 23:14:27 +02:00
Philipp Dormann
54184350a4
fix: missing semicolons 2022-05-23 21:13:57 +02:00
Philipp Dormann
14dbe7c334
clean up + default ntfs.sh server url 2022-05-23 21:11:01 +02:00
Philipp Dormann
122e6a842b
clean up ntfy topic input 2022-05-23 21:08:56 +02:00
Philipp Dormann
77ef22bdb4
set proper ntfy priorities 2022-05-23 21:08:11 +02:00
Philipp Dormann
59f983d506
fix: unused import "HiddenInput" 2022-05-23 20:57:10 +02:00
Philipp Dormann
71f031c14e
add ntfy support
ref https://github.com/louislam/uptime-kuma/issues/1622
2022-05-23 10:55:03 +02:00
Louis Lam
6ae2a48584
Merge pull request #1662 from kiznick/master
Translate to Thai
2022-05-21 14:14:42 +08:00
Louis Lam
7373747906
Merge pull request #1659 from MrEddX/bulgarian
Bulgarian
2022-05-21 14:13:48 +08:00
Yoswaris Lawpaiboon
9d87f8d390 Update th-TH.js 2022-05-20 19:16:37 +07:00
Domingos F. Panta Jr
73b965c867
Merge branch 'master' into bugfix/1451_blank_page_on_unkown_resource 2022-05-19 19:35:58 +01:00
MrEddX
751e5ac477
Bulgarian Translation
Updated Translation
2022-05-19 20:32:01 +03:00
Yoswaris Lawpaiboon
93e5023ead Translate to Thai ! 2022-05-19 19:44:59 +07: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
Nelson Chan
b7ba6330db Feat: Add cert exp. settings 2022-05-19 16:49:34 +08:00
MrEddX
4c3aa20eb0
Update bg-BG.js
Added new fields
2022-05-18 22:18:58 +03:00
MrEddX
f779c6286a
Merge branch 'louislam:master' into bulgarian 2022-05-18 22:14:18 +03: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
Louis Lam
9fc5a3329f Revert #1208, due to the break animation 2022-05-18 20:16:50 +08:00
Louis Lam
7a46b44d25 Merge remote-tracking branch 'origin/master' into karelkryda_master
# Conflicts:
#	src/components/HeartbeatBar.vue
2022-05-18 19:49:54 +08:00
Louis Lam
23c4ece2a5
Merge pull request #1655 from alexislefebvre/patch-1
Fix typo “cros”?
2022-05-17 23:12:07 +08:00
Alexis Lefebvre
175556f9fc
s/cros/CORS 2022-05-16 20:30:16 +02:00
Louis Lam
398219f847 Update to 1.16.0-beta.0 2022-05-17 01:03:51 +08:00
Louis Lam
7a50f0e3f3
Merge pull request #1589 from AnnAngela/1.15.1_zh-CN
Improve translation work
2022-05-17 00:03:25 +08:00
AnnAngela
4178b003a2
fix value 2022-05-14 15:27:55 +08:00
Louis Lam
8ede6d888f Merge remote-tracking branch 'origin/master' into fix-1448-discord-service-url 2022-05-14 14:37:12 +08:00
Louis Lam
cec0521834 [Discord] Fix ping type should no port, update better naming 2022-05-14 14:36:40 +08:00
Louis Lam
73b603dd10
Merge pull request #1627 from karelkryda/wrong-uptime-for-push
Fixed incorrect uptime calculation for push monitors
2022-05-14 14:18:19 +08:00
Louis Lam
92a43e1f30 Make the sibling beats a bit smaller 2022-05-14 14:11:43 +08:00
Louis Lam
0cf395dfc3 Fix merge issue 2022-05-14 14:06:35 +08:00
Louis Lam
749ca6f4a8 Merge remote-tracking branch 'origin/master' into feature-improve-status-styling
# Conflicts:
#	src/components/HeartbeatBar.vue
#	src/components/PublicGroupList.vue
2022-05-14 14:05:28 +08:00
Christopher Pickering
ef73af391f
added option for ntlm authorization 2022-05-13 12:58:23 -05:00
Christopher Pickering
44f6fca945
added finally to close connection pool 2022-05-13 09:34:31 -05:00
Christopher Pickering
23ce7c6623
started db update script 2022-05-13 09:06:41 -05:00
Christopher Pickering
c346ea7864
updated name on export 2022-05-13 08:57:06 -05:00
Christopher Pickering
f0ad32a252
merged 2022-05-13 08:41:31 -05:00
Christopher Pickering
5720017fb4
updated name on import 2022-05-13 08:40:46 -05:00
Christopher Pickering
b7dc8e3ef8
started ui update 2022-05-13 07:22:52 -05:00
sur.la.route
5bba19f866
updated format
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-05-12 19:54:12 -05:00
sur.la.route
e198f2f1ab
updated format
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-05-12 19:54:02 -05:00
Christopher Pickering
f91e5b98f9
[empty commit] pull request for Add NTML Auth Option for HTTP 2022-05-12 13:23:41 -05:00
Christopher Pickering
87f933df4f
added sqlserver monitor 2022-05-12 12:48:03 -05:00
Christopher Pickering
332b9ab248
[empty commit] pull request for Add SQLServer Monitor 2022-05-12 10:39:12 -05:00
Domingos Panta
7cc89979f0 Moving change from axios interceptor to specific request. 2022-05-12 15:52:21 +01:00
Sascha Kruse
398ecb7666 add radius check 2022-05-12 15:21:13 +02:00
Domingos Panta
668e97c5a9 fix: lint errors. 2022-05-12 13:39:10 +01:00
MrEddX
90473e7924
Merge branch 'louislam:master' into bulgarian 2022-05-12 13:34:19 +03:00
Domingos Panta
fdd781b081 Added a link to the home page on the lists of actions.
s new link was necessary to prevent a loop when the user tries to access a unknown resource, like status/123, and was redirected to /page-not-found. In this case going back to the last page would be /status/123 which does not exists.
2022-05-11 17:58:52 +01:00
Domingos Panta
373bd9b962 Added response interceptor to axios response.
This interceptor checks for response code 404 and redicts the user if that is the case.
2022-05-11 17:56:31 +01:00
Louis Lam
66971deaf4 Merge remote-tracking branch 'origin/master' into fix-1448-discord-service-url 2022-05-11 00:51:42 +08:00
Louis Lam
59be9bb971 working 2022-05-11 00:51:11 +08:00
Louis Lam
8077744c60
Merge pull request #1604 from c-w/fix-apprise-zulip
Fix apprise integration for Zulip Streams
2022-05-11 00:47:50 +08:00
Jordan Bertasso
c5faf709b8
Merge branch 'master' into fix-1448-discord-service-url 2022-05-10 22:53:55 +10:00
Karel Krýda
7da9f139c1 Bug fix 2022-05-09 21:10:12 +02:00
Karel Krýda
7acbfd2474 eslint fixes too much 2022-05-09 21:05:10 +02:00
Karel Krýda
9f493bbec7 clone master branch 2022-05-09 21:02:29 +02:00
Karel Krýda
42f931f6cf
Merge branch 'master' into master 2022-05-09 10:28:14 +02:00
Louis Lam
5bf58cc6c4
Merge pull request #1595 from Saibamen/fix_eslint
Fix ESLint warnings and errors
2022-05-09 13:55:08 +08:00
Louis Lam
d344914ca0
Update docker-compose.yml 2022-05-09 13:47:19 +08:00
Karel Krýda
2fe5c090aa small fixes 2022-05-08 20:50:08 +02:00
Karel Krýda
ed218e73bb UI improvements 2022-05-08 20:03:24 +02:00
Louis Lam
201a25c659 Draft 2022-05-09 00:26:49 +08:00
Clemens Wolff
b680371746 Make apprise notification title configurable in UI 2022-05-07 11:00:57 -04:00
Louis Lam
e488e2dc0a
Merge pull request #1119 from jensneuber/uptime-badges
Add badges
2022-05-07 13:44:20 +08:00
Louis Lam
4e3258579d Merge branch 'master' into uptime-badges
# Conflicts:
#	server/util-server.js
2022-05-07 13:26:47 +08:00
MrEddX
aa8ea6d398
Update bg-BG.js (#1617)
Translation Fixes
2022-05-07 13:01:06 +08:00
Aram Akhavan
cd3fbc80b4
Add first parameter back to logging in api router 2022-05-06 16:05:24 -07:00
Aram Akhavan
bb7d67f717
Apply suggestions from code review
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-05-06 09:58:05 -07:00
Karel Krýda
9a35386841
Merge branch 'master' into master 2022-05-06 11:24:21 +02:00
Louis Lam
8b0813ceff Fix #1596 hopefully 2022-05-06 14:52:09 +08:00
Louis Lam
91178ce6a5 Merge remote-tracking branch 'origin/master' 2022-05-06 14:41:46 +08:00
Louis Lam
429ad384d0 Fix hardcoded path for error.log and move errorLog() to UptimeKumaServer.errorLog() 2022-05-06 14:41:34 +08:00
MrEddX
24e52726b2
Merge branch 'louislam:master' into bulgarian 2022-05-05 23:03:11 +03:00
MrEddX
e0a0a5db4c
Update bg-BG.js
Translation Fixes
2022-05-05 22:46:34 +03: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
Greg Smith
cbfecab850 switch to the more-up-to-date esm-wallaby
https://github.com/wallabyjs/esm
2022-05-04 15:45:18 +09:30
Louis Lam
25cc54bf72 Try to give more time for axios-cached-dns-resolve test 2022-05-04 13:24:18 +08:00
Louis Lam
3700b16c5b Copy and add axios-cached-dns-resolve test 2022-05-04 13:16:22 +08:00
Clemens Wolff
4b9dc2890d Convert let to const 2022-05-02 11:16:08 -04:00
Clemens Wolff
f9004bcbed Add optional title to apprise notification 2022-05-02 11:14:26 -04:00
Clemens Wolff
bc174c3325 Extract child process args into variable 2022-05-02 11:00:14 -04:00
Louis Lam
4c2753af46 Remove an unused variable 2022-05-02 13:36:35 +08:00
Louis Lam
c6ba5b621c Remove isPublished, checkPublished which had been removed in upstream. 2022-05-02 13:32:19 +08:00
Louis Lam
96536ae391 Rebuild package-lock.json 2022-05-02 12:36:12 +08:00
Louis Lam
ba46544772
Merge pull request #1603 from Saibamen/fix_task_name
Fix actions/setup-node task name
2022-05-02 12:35:21 +08:00
Adam Stachowicz
5c852db1cf Fix actions/setup-node task name
Addendum to 000cbeb0ce1921f36314ea904fcf5b23e61bd179
2022-05-02 01:23:05 +02:00
Adam Stachowicz
069d3765f0 Revert change for StatusPage 2022-05-02 01:13:17 +02:00
Louis Lam
15820c6937 Update SQLite 2022-05-01 19:45:00 +08:00
Karel Krýda
2b14bdae62
Merge branch 'master' into master 2022-05-01 12:40:34 +02:00
Louis Lam
000cbeb0ce Lower check-linters node version to 14, add Node.js 18, set timeout 15mins for each job 2022-05-01 18:25:52 +08:00
Louis Lam
e118d59ac8 Merge branch 'master' into uptime-badges 2022-05-01 18:01:26 +08:00
Louis Lam
39aa0a7f07 Merge branch 'fix/chart-error' 2022-05-01 17:57:17 +08:00
Louis Lam
a12dffd1bc Fallback to eqeq for PingChart.vue 2022-05-01 17:56:42 +08:00
Louis Lam
410805052e Log this.chartPeriodHrs 2022-05-01 17:46:43 +08:00
Louis Lam
02a8147f22 Remove undefined variable forceShowContent 2022-05-01 17:31:58 +08:00
Louis Lam
d962ab7a1c Merge branch 'master' into uptime-badges
# Conflicts:
#	package-lock.json
#	server/routers/api-router.js
2022-05-01 17:03:11 +08:00
Louis Lam
63c8d24d6f As legacy-peer-deps is specified in .npmrc, install-legacy and update-legacy are not actually needed. 2022-05-01 12:32:06 +08:00
Louis Lam
254a6bfd36 [CI] Run check linters first 2022-05-01 12:23:28 +08:00
Louis Lam
29f3cbe8c6
Merge pull request #1594 from GOGOsu/patch-1
Fix aliyun-sms "SignatureDoesNotMatch" Error
2022-05-01 12:14:09 +08:00
Louis Lam
53b98ad3e4 Add more comment for aliyun-sms fix 2022-05-01 12:10:47 +08:00
Louis Lam
dbd7c087e0
Merge pull request #1597 from chakflying/fix/chart-error
Fix: Fix chart error on switch back to recent
2022-05-01 11:09:57 +08:00
Greg Smith
d0546afe71 fix esm require: no ugly warnings 2022-05-01 10:22:16 +09:30
Nelson Chan
272956025c Fix: Fix chart error on switch back to recent 2022-05-01 05:18:08 +08:00
Karel Krýda
31b90d12a4 Added the ability to choose on which status pages maintenance information should be displayed 2022-04-30 17:17:22 +02:00
Karel Krýda
b4ffcc5555 Added JSDoc 2022-04-30 15:50:05 +02:00
Louis Lam
db50ba91cc Fix #1593 2022-04-30 21:44:03 +08:00
Louis Lam
42ea3fb412
Update server/util-server.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-30 21:36:07 +08:00
Louis Lam
9f8b3151d8
Update server/util-server.js
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-30 21:36:00 +08:00
Karel Krýda
57368c8c6c More modern look of maintenance information on status page (same design as for the new incident system) 2022-04-30 15:32:56 +02:00
Karel Krýda
11ef22edec Fixed remaining lint errors 2022-04-30 15:13:13 +02:00
GOGOsu
73e38a13d2
Update server/notification-providers/aliyun-sms.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-30 21:08:35 +08:00
Karel Krýda
f78d01d770 Resolve lint errors 2022-04-30 14:57:08 +02:00
Karel Krýda
7532acc95d Resolve conflicts 2022-04-30 14:33:54 +02:00
Greg Smith
f4515ad8c5 add axios cached dns resolve to monitor 2022-04-30 21:40:47 +09:30
Karel Krýda
ed84e56a85 Merge remote-tracking branch 'origin_kuma/master'
# Conflicts:
#	package-lock.json
#	server/database.js
#	server/model/monitor.js
#	server/routers/api-router.js
#	server/server.js
#	src/components/MonitorList.vue
#	src/components/PingChart.vue
#	src/icon.js
#	src/pages/DashboardHome.vue
#	src/pages/StatusPage.vue
#	src/router.js
#	src/util.js
2022-04-30 13:40:34 +02:00
GOGOsu
369477b4b9
Update aliyun-sms.js 2022-04-30 10:45:38 +08:00
GOGOsu
2347a01f7c
Update aliyun-sms.js
Add comments for the changed code.
2022-04-30 10:42:59 +08:00
Adam Stachowicz
c114c053d6 Fix ESLint warnings and errors 2022-04-30 03:51:14 +02:00
GOGOsu
ae2c49a729
Update aliyun-sms.js 2022-04-30 06:28:16 +08:00
GOGOsu
b9e72b9645
Update aliyun-sms.js
aliyun-sms.js: escape more characters than encodeURIComponent
see https://help.aliyun.com/document_detail/315526.html
字符A~Z、a~z、0~9以及字符-、_、.、~不编码。对其它ASCII码字符进行编码。
2022-04-30 05:56:10 +08:00
AnnAngela
5a069b278d
Update src/components/notifications/PromoSMS.vue
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-29 21:42:54 +08:00
AnnAngela
65ea2e6aeb
Update src/components/notifications/PromoSMS.vue
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-29 21:42:48 +08:00
AnnAngela-work
e82fc1df61 Match up en lang file 2022-04-29 20:31:36 +08:00
AnnAngela-work
7dd5f5ea0d Improve translation 2022-04-29 20:26:56 +08:00
AnnAngela-work
45da7c5431 Improve translation work 2022-04-29 20:17:15 +08:00
Louis Lam
26230a3d3a Update to 1.15.1 2022-04-29 13:52:14 +08:00
Louis Lam
82aa52b330 Update Apprise to 0.9.8.3 2022-04-29 13:49:32 +08:00
Louis Lam
fa7d15cf64 Merge remote-tracking branch 'origin/master' 2022-04-29 13:40:17 +08:00
Louis Lam
d7f16908d8 Update CONTRIBUTING.md 2022-04-29 13:39:30 +08:00
Louis Lam
bddd5de22b
Update CONTRIBUTING.md 2022-04-29 11:35:03 +08:00
Louis Lam
6333231f1b
Merge pull request #1108 from trogper/push-status-param
Add status parameter to push monitor
2022-04-29 00:12:44 +08:00
Louis Lam
60538036c6 [#1108] Change "true" to "up" 2022-04-28 23:44:08 +08:00
Louis Lam
0ba5d031d0 Merge branch 'master' into push-status-param
# Conflicts:
#	server/routers/api-router.js
2022-04-28 23:34:51 +08:00
Louis Lam
66e4c89897
Merge pull request #1560 from MrEddX/bulgarian
Update bg-BG.js
2022-04-28 23:23:09 +08:00
Louis Lam
d210548ae8
Merge pull request #1581 from NixNotCastey/update-pl
Update polish translation
2022-04-28 23:22:31 +08:00
Louis Lam
023db1450d Fix #1577 2022-04-28 23:12:16 +08:00
Louis Lam
824c16a07c
Merge pull request #1578 from kadavr95/typos-fixes
Typos fixes
2022-04-28 17:27:22 +08:00
Łukasz Szczepański
09fdef9bdc Update polish translation 2022-04-28 11:14:02 +02:00
Dmitry Yaskovich
7078b06272
Fix typo in Russian localization 2022-04-27 21:22:42 +03:00
Dmitry Yaskovich
d3bd2976c5
Fix typo in CONTRIBUTING.md 2022-04-27 21:18:47 +03:00
Dmitry Yaskovich
db646aa40b
Fix typo in README 2022-04-27 21:10:47 +03:00
Matthew Nickson
3c01e8732c
Merge branch 'master' into #1059-specify-dns-resolver-port 2022-04-27 18:26:11 +01:00
Louis Lam
b50f1bb7e8 No more opening browser 2022-04-27 15:29:54 +08:00
Phuong Nguyen Minh
a3baa3c149
Update language vi.js (#1572)
Update vi-VN.js
2022-04-27 15:07:42 +08:00
Louis Lam
2adb142ae2
Merge pull request #1571 from MarkusDick/update-german-translations
lang: update german translations
2022-04-27 15:04:04 +08:00
Louis Lam
752415dae6
Merge pull request #1566 from Saibamen/fix_duplicated_PR_comments
Fix duplicated PR comments
2022-04-27 15:01:52 +08:00
Louis Lam
1687de163c
Merge pull request #1565 from Saibamen/eslint
Fix some of ESLint warnings
2022-04-27 15:00:49 +08:00
Louis Lam
245b13d3c8
Merge pull request #1542 from Computroniks/jsdoc-for-tests
JSDoc for test/*
2022-04-27 14:48:46 +08:00
Louis Lam
d6c3fdb6fb
Merge pull request #1499 from Computroniks/add-JSDoc-comments
Add JSDoc comments for server/*/*
2022-04-27 14:46:23 +08:00
MrEddX
372bf57e9f
Update bg-BG.js
Translation fixes
2022-04-27 09:19:13 +03:00
Aram Akhavan
39df4eea92 Ssynchronize push monitor heartbeats to api calls
Includes a 1s buffer time to allow the push url to be called before the monitor is checked
2022-04-26 13:48:44 -07:00
MrEddX
03e6f0a6c8
Update bg-BG.js
Translation fixes.
2022-04-26 21:39:14 +03:00
Markus Dick
dcec53a755 lang: update german translations 2022-04-26 20:27:00 +02:00
MrEddX
ce17ed163e
Merge branch 'louislam:master' into bulgarian 2022-04-26 21:26:39 +03:00
Adam Stachowicz
3019d5dd64 Shorter node matrix 2022-04-26 02:03:47 +02:00
Adam Stachowicz
dcdbb7be8b Use separate job for linters 2022-04-26 01:57:49 +02:00
Adam Stachowicz
b874ea8b28 Add missing lint-fix:style command 2022-04-26 01:37:20 +02:00
Adam Stachowicz
1e595eaa76 Update linters 2022-04-26 01:26:57 +02:00
Adam Stachowicz
5fbfacf5ce Fix ESlint warnings 2022-04-26 00:26:26 +02:00
Louis Lam
d39dc94496 Add more info 2022-04-26 02:27:37 +08:00
Louis Lam
94ada36dfa Update dev guideline 2022-04-26 02:20:13 +08:00
Louis Lam
4114f43b48 Start both dev servers in one command 2022-04-26 02:18:14 +08:00
MrEddX
4c8da89c36
Update bg-BG.js
Translation fixes
2022-04-25 07:26:40 +03:00
Dick Tang
db3ef3805b
correct wordings for Certificate Expiry Notification (#1554) 2022-04-25 08:25:06 +08:00
Louis Lam
751924b335 Update to 1.15.0 2022-04-24 22:57:42 +08:00
Louis Lam
edec1024b5 Merge remote-tracking branch 'origin/master' 2022-04-24 22:56:52 +08:00
Louis Lam
5f9f29f527
Update SECURITY.md 2022-04-24 22:54:06 +08:00
Louis Lam
13a3dd91bb Merge remote-tracking branch 'origin/master' 2022-04-24 22:41:29 +08:00
Matthew Nickson
d1a3cd047a
Merge branch 'master' into #1059-specify-dns-resolver-port 2022-04-24 01:06:45 +01:00
Louis Lam
d9c5a7812c
Merge pull request #1544 from mathiskir/readme-improvements
readme improvements
2022-04-24 03:44:21 +08:00
Sneeex
484d4a20ab
Small improvements 2022-04-23 19:29:34 +02:00
Louis Lam
3582e99770
Merge pull request #1543 from gaby/github-actions
Upgrade to actions/checkout@v3
2022-04-24 01:22:56 +08:00
Juan Calderon-Perez
2197b98444
Upgrade to actions/checkout@v3 2022-04-23 09:47:57 -04:00
Matthew Nickson
b641c8a878
Add JSDoc to test/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-22 23:24:14 +01:00
Matthew Nickson
9130b3762c
[empty commit] pull request for JSDoc test/* 2022-04-22 23:05:18 +01:00
Matthew Nickson
587faecf87
Made value nullable in apicache JSDoc
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-22 19:42:42 +01:00
Matthew Nickson
46da5e51be
Fix JSDoc grammar
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-22 19:10:13 +01:00
Matthew Nickson
1eecdec2d9
Update JSDoc for better clarity
Co-authored-by: Nelson Chan <chakflying@hotmail.com>
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-22 18:42:47 +01:00
Sneeex
e6a1719ab4
Change notification count (#1536) 2022-04-22 15:59:34 +08:00
Louis Lam
7d5e7a577d
Merge pull request #1535 from Computroniks/add-jsdoc-to-contributing
Added JSDoc requirement in contributing docs
2022-04-22 14:04:00 +08:00
Jens Neuber
64a33d7455
Update server/util-server.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-22 07:54:13 +02:00
Matthew Nickson
09e61d9d63
Changed Array<T> to type[]
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 20:02:18 +01:00
Matthew Nickson
9996ba1636
Add JSDoc to server/modules/apicache/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 19:55:01 +01:00
Matthew Nickson
c2f6c5b42e
Added JSDoc docs for mqttAsync
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 18:53:07 +01:00
Matthew Nickson
0083485d4c
Updated server/model/* JSDoc to match new methods
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 18:30:04 +01:00
Louis Lam
630bb03d9c Update package-lock.json during release process 2022-04-22 00:47:04 +08:00
OidaTiftla
7ed8ae9f7c Fix trailing space warning 2022-04-21 18:23:32 +02:00
Matthew Nickson
4ddbf71920
Fixed trailing spaces in database.js
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 17:15:39 +01:00
Matthew Nickson
068b920553
Add JSDoc to server/socket-handlers/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 17:10:23 +01:00
Louis Lam
f1c83bb838 Merge remote-tracking branch 'origin/master' 2022-04-22 00:06:59 +08:00
Louis Lam
303a226ab7 Update eslint rule 2022-04-22 00:06:46 +08: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
Matthew Nickson
3d04befc1f
Add JSDoc to server/routers/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 16:43:24 +01:00
Matthew Nickson
d3f0bdb440
Added JSDoc requirement in contributing docs
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-21 16:30:53 +01:00
Matthew Nickson
6d22ebedca
Merge branch 'master' into add-JSDoc-comments 2022-04-21 13:01:22 +01: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
Louis Lam
e56ac7b03b
Merge pull request #1530 from MrEddX/bulgarian
Bulgarian
2022-04-21 14:37:20 +08:00
Louis Lam
aafcbaf098
Update README.md 2022-04-21 10:22:18 +08:00
MrEddX
4d4d04adbd
Update bg-BG.js
Some translation fixes
2022-04-20 22:01:57 +03:00
Matthew Nickson
03b2d8d521
Add JSDoc to server/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-20 19:56:40 +01:00
MrEddX
f8c9472ea2
Update bg-BG.js
- Updated and fixed
2022-04-20 21:54:57 +03:00
Louis Lam
4e28ad4ac2
Merge pull request #1524 from chakflying/fix/disable-auth-icon
Fix: Handle disabled auth in user dropdown
2022-04-20 23:50:33 +08:00
Louis Lam
06f326e49e
Merge pull request #1527 from SiderealArt/patch-1
Update Traditional Chinese (Taiwan) translation
2022-04-20 22:43:41 +08:00
Louis Lam
07c0801ad5 Make logout button reactive, improve dropdown menu css 2022-04-20 22:39:07 +08:00
SiderealArt
8cefc96c78
Update Traditional Chinese (Taiwan) translation 2022-04-20 18:11:26 +08:00
Louis Lam
b326a69838
Merge pull request #1523 from koen20/patch-1
Update dutch translations
2022-04-20 17:24:36 +08:00
Jens Neuber
e103ac8335 Merge branch 'master' of https://github.com/louislam/uptime-kuma into uptime-badges 2022-04-20 10:10:14 +02:00
Nelson Chan
a391576285 Chore: Add translation 2022-04-20 15:09:31 +08:00
Nelson Chan
e0966e55c8 Fix: Handle disabled auth in user dropdown 2022-04-20 15:01:13 +08:00
Koen Habets
59d9891105
Update nl-NL.js 2022-04-19 21:17:33 +02:00
Louis Lam
f8f19d8dc5 Merge remote-tracking branch 'origin/master' 2022-04-20 02:57:52 +08:00
Louis Lam
a3d79a93e9 Update Apprise to 0.9.8 2022-04-20 02:56:33 +08:00
Louis Lam
bdc23a3f57
Merge pull request #1519 from AnnAngela/1.15.0_zh-cn
Update en&zh-CN lang file with 1 new i18n entry
2022-04-19 23:48:07 +08:00
Louis Lam
7c13b1b6cb Update to 1.15.0-beta.1 2022-04-19 20:07:18 +08:00
Louis Lam
10f6a3c4f5
Merge pull request #1229 from Computroniks/#1209-Logout-button-in-navbar
Add #1209: logout button in navbar
2022-04-19 19:59:52 +08:00
Louis Lam
cd7c2beca6 Update CSS for dropdown menu 2022-04-19 19:46:21 +08:00
Louis Lam
8ee99760ec Minor lint 2022-04-19 19:41:52 +08:00
Louis Lam
cb55e23718 Add $root.username 2022-04-19 19:40:28 +08:00
Louis Lam
200fdfb808 Merge code manually since some code moved to another file 2022-04-19 16:46:45 +08:00
Louis Lam
29d2d95c71 Merge branch '1.14.X'
# Conflicts:
#	package.json
#	server/server.js
2022-04-19 16:43:13 +08:00
Louis Lam
b782b25e17 Update to 1.14.1 2022-04-19 16:01:08 +08:00
Louis Lam
919393cac9 Partially change the server core into a class, remove all require("./server") #1520 2022-04-19 15:38:59 +08:00
AnnAngela-work
18925293fb Update en&zh-CN lang file with 1 new i18n entry 2022-04-19 10:48:20 +08:00
Louis Lam
17d4003e5c Add dropdown menu 2022-04-19 00:39:49 +08:00
Louis Lam
cefb5bb60a Merge branch 'master' into #1209-Logout-button-in-navbar 2022-04-18 20:39:24 +08:00
Louis Lam
9bf3b3a0f4
Update README.md 2022-04-18 19:15:50 +08:00
Louis Lam
e2c45f93bf
Merge pull request #1509 from chakflying/feat/mqtt-optional-message
Feat: Allow MQTT successMessage to be optional
2022-04-18 19:06:39 +08:00
Louis Lam
addf75daa7 Fix MQTT password do not save 2022-04-18 19:05:14 +08:00
Louis Lam
359a490ae3 Fix #1510 2022-04-18 15:21:58 +08:00
Nelson Chan
cd38dd3f68 Feat: Allow MQTT successMessage to be optional 2022-04-18 13:04:55 +08:00
Louis Lam
f712fe85e5 Update node-sqlite, sqlite from 3.36 to 3.38 2022-04-18 12:44:32 +08:00
Louis Lam
c28b90feb4 Update to 1.15.0-beta.0 2022-04-17 20:07:32 +08:00
Louis Lam
ceba096f3e
Merge pull request #875 from tarun7singh/master
Added MQTT Monitor type
2022-04-17 20:05:41 +08:00
Louis Lam
2a248ad73f Change mqtt_topic from VARCHAR to TEXT 2022-04-17 19:56:47 +08:00
Louis Lam
5fa62a888c Merge branch 'master' into mqtt2
# Conflicts:
#	server/database.js
#	server/util-server.js
2022-04-17 19:46:33 +08:00
Louis Lam
e6a8a84278 Include only nessacary data in webhook 2022-04-17 19:30:58 +08:00
Louis Lam
47c72192e1 [eslint] Enable yoda and eqeqeq 2022-04-17 15:43:03 +08:00
Louis Lam
d71c086447 Standardize array bracket spacing 2022-04-17 15:27:35 +08:00
Louis Lam
46e1a628a7 Update package-lock.json 2022-04-17 15:04:59 +08:00
Louis Lam
cd3dfd3146
Merge pull request #1083 from patrickhafner/customstatuspage
Custom status page
2022-04-17 15:04:02 +08:00
Louis Lam
572f2b9838 eslint 2022-04-17 14:57:31 +08:00
Louis Lam
8eb83394f7 Refine UI/UX for custom css / footer text. Add switch for show/hide powered by 2022-04-17 14:53:13 +08:00
Louis Lam
1bc01d1077 Merge branch 'master' into customstatuspage
# Conflicts:
#	src/languages/de-DE.js
2022-04-17 13:21:41 +08:00
Matthew Nickson
45f44b183d
Add JSDoc to server/model/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-16 21:11:45 +01:00
Matthew Nickson
5a209c74e1
Add JSDoc to server/notification-providers/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-16 20:24:53 +01:00
Louis Lam
4e6ddc8880
Merge pull request #1497 from MrEddX/bulgarian
Bulgarian
2022-04-17 01:40:43 +08:00
Louis Lam
07c474db0b Merge remote-tracking branch 'origin/master' 2022-04-17 01:40:05 +08:00
Louis Lam
8d8c38b1a8 Allow unused vars in args and fix more eslint issues 2022-04-17 01:39:49 +08:00
Louis Lam
03bcf5c766 Add a simple mqtt server for testing 2022-04-17 01:07:54 +08:00
Louis Lam
136fdf3768 MQTT password field to password type 2022-04-17 01:07:36 +08:00
Louis Lam
e34420368b Remove try-catch and fix username/password/port not working for mqtt 2022-04-17 01:06:47 +08:00
Matthew Nickson
60c63cc18e
Add JSDoc to server/jobs/*
Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-16 11:10:51 +01:00
Louis Lam
566133e350 Domain Name Expiry Notification for https monitor only 2022-04-16 15:01:53 +08:00
Louis Lam
30e113755e Add HIDE_LOG and catch error if cannot subscribe topic 2022-04-16 14:50:48 +08:00
Louis Lam
083e8355b7 Change debug to log.debug 2022-04-16 13:37:17 +08:00
Louis Lam
64a0e1aa9b Update package-lock.json 2022-04-16 13:31:40 +08:00
Louis Lam
b1c7915bc1 Merge branch 'master' into mqtt2
# Conflicts:
#	package-lock.json
#	package.json
#	server/database.js
#	server/model/monitor.js
#	server/server.js
#	src/pages/EditMonitor.vue
2022-04-16 13:28:39 +08:00
Matthew Nickson
6fb66728e6
[empty commit] pull request for Add JSDoc comments 2022-04-15 20:08:54 +01:00
Matthew Nickson
a680331dd7
Fixes issue with ::1 port 5300 requests
Now the address is wrapped in `[]` in order to prevent ::1 port 5300
being interpreted as ::1:5300. Wrapping the IPv4 address in `[]` does
seem to have any effect on correct domain name resolution. In order to
prevent issues if a user inputs an address with brackets, they are
removed from the string if present before being re-added when it is
passed to `setServers`. I have also removed the JSDoc comment as this
will be added in a seperate PR

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-15 19:59:32 +01:00
Louis Lam
b7aebceaab
Update bg-BG.js 2022-04-15 19:49:16 +08:00
MrEddX
0302fdbc96
Update bg-BG.js
Status pages - fix
2022-04-15 13:10:14 +03:00
MrEddX
84a50f058f
Update bg-BG.js 2022-04-15 13:06:22 +03:00
MrEddX
9ec652639b
Merge branch 'louislam:master' into bulgarian 2022-04-15 13:03:34 +03:00
Louis Lam
0c40e32d75
Merge pull request #1007 from chakflying/feat/save-chart-period
Feat: Save and restore chart period
2022-04-15 12:34:53 +08:00
Jordan Bertasso
288ed1e3ca
Merge branch 'master' into fix-1448-discord-service-url 2022-04-15 14:13:44 +10:00
Nelson Chan
6f99d7577b Fix: Limit saved period & clear when set to recent 2022-04-15 03:24:58 +08:00
Nelson Chan
1417b6eacf Feat: Save and restore chart period 2022-04-15 02:56:21 +08:00
MrEddX
1baee42cf5
Merge branch 'louislam:master' into bulgarian 2022-04-14 10:55:04 +03:00
Louis Lam
fb0064082e Change Pushdeer to PushDeer 2022-04-14 14:34:30 +08:00
ngc7331
93c51504f9 fixes: formatting and security issues
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-14 14:34:30 +08:00
ngc7331
fb059f5e91 Add support for Pushdeer notifications 2022-04-14 14:34:30 +08:00
PhyxionNL
2e3414135f Update src/components/PingChart.vue
Co-authored-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-14 12:27:38 +08:00
PhyxionNL
e44699216e Fix readability of chart hover 2022-04-14 12:27:38 +08:00
DX37
fd8cba1dad nudge nodemailer strings; translate new ones 2022-04-14 11:10:24 +08:00
sovushik
03dd02fd38 Update ru-RU.js
Add RU for 1.14 version
2022-04-14 11:04:46 +08:00
Louis Lam
d0b5f147e2 Fix spelling and merge mistake 2022-04-14 10:58:28 +08:00
Louis Lam
ddf8a7a692 Fix camelCase 2022-04-14 10:58:28 +08:00
ColdThunder11
bd9df09f87 Apply suggestions from code review, fix style
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-14 10:58:28 +08:00
ColdThunder11
4656ab3d57 Add OneBot notification service 2022-04-14 10:58:28 +08:00
Louis Lam
0a5db0cecb Fix #1478 2022-04-14 10:12:31 +08:00
MrEddX
60b44c2cdd Update bg-BG.js
Fixed translation.
2022-04-14 09:46:43 +08:00
Matthew Nickson
8c8eeaf627
Merge branch 'master' into #1059-specify-dns-resolver-port 2022-04-13 21:24:04 +01:00
Matthew Nickson
b893d50e45
Implement specify Port for DNS Monitor #1059
This commit should fully implement #1059. When the user selects the DNS
monitor option, a new input box has been added below the resolver
address allowing the user to implement the port to access the resolver
on. This uses the same `monitor.port` as the TCP monitor but a monitor
has been added to prefill the port value to the default of `53` if the
value in this field has not already been set. This is then cleared if
the user selects a different monitor type and has not changed the port
value. A translation has also been added explaining what this field
does in order to reduce any confusion. JSDoc documentation has also been
added to the `dnsResolve` function in `util-server.js`.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
2022-04-13 21:02:19 +01:00
MrEddX
16b61dba27
Merge branch 'louislam:master' into bulgarian 2022-04-13 21:59:53 +03:00
Louis Lam
2b0c184a88 Update package-lock 2022-04-14 01:21:43 +08:00
Louis Lam
2642e70fc8 Fix auto test failed due to autocrlf 2022-04-14 01:20:54 +08:00
Louis Lam
8d0446dc38 Add lint as part of test 2022-04-14 01:20:54 +08:00
Louis Lam
3436e26ed4 Fix styleline, fix css format issues globally 2022-04-14 01:20:54 +08:00
Louis Lam
649f3106e1 Enforce semicolon, fix format globally 2022-04-14 01:20:54 +08:00
Louis Lam
6f72ca481f
Merge pull request #1479 from AnnAngela/1.14.0_translation
New translation for zh-CN
2022-04-14 00:05:07 +08:00
Louis Lam
670ea415b2
Merge pull request #1488 from c0derMo/update-german-translation
updating german translation
2022-04-14 00:03:53 +08:00
Louis Lam
17dcf6d3a2
Merge pull request #910 from andreasbrett/logging
introduce consistent logging
2022-04-13 23:47:08 +08:00
Louis Lam
e9ce1433cd Change log_info to log.info by making it into an object 2022-04-13 23:33:37 +08:00
c0derMo
f5d006add8 updating german translation 2022-04-13 14:45:41 +00:00
Moritz R
361e44ad6a
Merge branch 'louislam:master' into master 2022-04-13 15:58:17 +02:00
Louis Lam
4df147786d
Merge pull request #1483 from Alexandre-Gliganic/master
Add automatic restart for docker-compose.yml
2022-04-12 22:39:29 +08:00
Alexandre Gliganic
27861f0d14
Add automatic restart docker-compose.yml 2022-04-12 16:09:01 +02:00
AnnAngela-work
5aa747a301 New translation 2022-04-12 20:41:25 +08:00
Louis Lam
81de2eedfb Fix template can contain one tag only, disable vue/require-component-is eslint rule 2022-04-12 20:23:11 +08:00
Louis Lam
4a6d7207ef Merge branch 'master' into customstatuspage
# Conflicts:
#	src/languages/de-DE.js
#	src/languages/en.js
#	src/pages/StatusPage.vue
2022-04-12 19:39:42 +08:00
Louis Lam
4053b9db1f Merge remote-tracking branch 'origin/master' 2022-04-12 17:46:24 +08:00
Louis Lam
772d009f43 Merge branch 'master' into fluencydoc_master
# Conflicts:
#	extra/update-version.js
#	server/client.js
#	server/server.js
2022-04-12 17:44:04 +08:00
MrEddX
ae54d9c011
Merge branch 'louislam:master' into bulgarian 2022-04-12 12:37:52 +03:00
Louis Lam
5ca606fe99
Merge pull request #1141 from marcules/issue/1138
Issue/1138
2022-04-12 17:32:52 +08:00
Louis Lam
6179f6c982 Merge branch 'master' into issue/1138
# Conflicts:
#	server/server.js
2022-04-12 17:15:33 +08:00
Louis Lam
94770cf865 Resolve log message null reference 2022-04-12 16:57:22 +08:00
Louis Lam
9ec29c1bc4 Add back debug() for safe, but it is marked as deprecated 2022-04-12 16:37:05 +08:00
Louis Lam
279e2eb3f6 Merge branch 'master' into logging
# Conflicts:
#	server/database.js
#	server/jobs.js
#	server/model/monitor.js
#	server/routers/api-router.js
#	server/server.js
#	server/socket-handlers/status-page-socket-handler.js
#	server/util-server.js
2022-04-12 16:32:14 +08:00
Louis Lam
1ba92d803e Update to 1.14.0 2022-04-12 14:17:13 +08:00
Louis Lam
45ca3085b2
Update CONTRIBUTING.md 2022-04-12 13:53:52 +08:00
jordanbertasso
0765f05090 Update Discord tests 2022-04-12 09:52:16 +10:00
jordanbertasso
2638d68c97 Cover dns and steam types in Discord notifs 2022-04-12 09:52:07 +10:00
Matthew Nickson
e38742a2d0
[empty commit] pull request for #1059 2022-04-11 19:58:31 +01:00
Louis Lam
a0d1ae2cce Better alignment of monitor list item 2022-04-11 18:02:18 +08:00
jordanbertasso
1b1e0f6dd9 Add Discord tests 2022-04-10 22:02:30 +10:00
jordanbertasso
0961c6d9b3 Check for ping and port type in discord notifs 2022-04-10 21:45:07 +10:00
jordanbertasso
ce7d8c38c5 [empty commit] pull request for issue #1448 2022-04-10 21:43:52 +10:00
Louis Lam
f030487f7d Fix theme color that do not apply to status page with a custom domain 2022-04-10 13:46:00 +08:00
Louis Lam
316e65d35a Update to 1.14.0-beta.2 2022-04-10 00:46:34 +08:00
Louis Lam
df5ba02f3f
Merge pull request #1415 from louislam/status-page-domain
[Status Page] Map domain names to status pages
2022-04-10 00:42:31 +08:00
Louis Lam
c9fa183712 Manage domain names 2022-04-10 00:25:27 +08:00
Louis Lam
0b9b5102ec Minor 2022-04-09 17:23:22 +08:00
Louis Lam
c399984b7f Improve status page sidebar 2022-04-09 17:03:10 +08:00
Louis Lam
0afa0be5c2 Merge branch 'master' into status-page-domain
# Conflicts:
#	server/database.js
2022-04-09 16:07:09 +08:00
Louis Lam
6a30dbd71a Fix Mattermost when channel is empty #1468 2022-04-09 15:44:50 +08:00
Louis Lam
a2d9474e85 Copy some keys from zh-TW to zh-HK 2022-04-09 14:51:26 +08:00
Louis Lam
8479e772cd
Merge pull request #1463 from JohnnyChiang/update-zh-TW-translation
Update zh-TW translation
2022-04-09 14:44:44 +08:00
Louis Lam
2e50ef0e8f
Merge pull request #1450 from AnnAngela/1.14.0-zh_cn
1.14.0 translation improvement
2022-04-09 14:40:38 +08:00
Louis Lam
4fb2c69dd1
Merge pull request #1461 from louislam/proxy-improvement
Proxy Improvements
2022-04-09 13:54:28 +08:00
Louis Lam
c08910a65c
Update README.md 2022-04-08 19:45:39 +08:00
Louis Lam
943c904256
Update docker-compose.yml 2022-04-08 19:43:51 +08:00
JohnnyChiang
25b5edea7f Update zh-TW translation 2022-04-08 01:47:01 +08:00
Louis Lam
7bbaeffd3e Fix reset-password (issue caused by 5027fcd320fe7fbf09d8742c8f6d5e3538e2c380) 2022-04-08 00:56:56 +08:00
Louis Lam
008dc27f52 Reload proxy settings for monitors in the monitorList 2022-04-07 23:03:45 +08:00
Louis Lam
5027fcd320 Export server using an object class 2022-04-07 23:02:57 +08:00
Louis Lam
d5e68f8453 Export monitor list 2022-04-07 22:53:32 +08:00
Louis Lam
fcb577097b [Proxy] Change to radio button 2022-04-07 15:26:00 +08:00
Louis Lam
082c2dd32d Remove restartMonitors() and move proxy socket events to a socket handler file 2022-04-07 14:45:37 +08:00
Louis Lam
e89356b283 Show proxy option for http monitor only 2022-04-07 14:37:33 +08:00
Louis Lam
6014b9534f Merge remote-tracking branch 'origin/master' 2022-04-06 23:20:40 +08:00
Louis Lam
8b45a95cc3 Merge branch '1.13.X'
# Conflicts:
#	package.json
2022-04-06 23:20:22 +08:00
Louis Lam
02becfd113 Update to 1.13.2 2022-04-06 22:54:03 +08:00
Louis Lam
8ad992eac8 Fix setup issue when using npm 8.6.0 2022-04-06 22:50:21 +08:00
Louis Lam
c4e74c9943 Render <StatusPage> if domain matched 2022-04-06 22:43:22 +08:00
Louis Lam
fee88b32e3 Set PRAGMA synchronous = FULL 2022-04-06 20:48:13 +08:00
Louis Lam
ffc5bca51d
Update required tools' links 2022-04-06 13:18:12 +08:00
AnnAngela
511b9dd425
Update fs-rmSync.js 2022-04-06 10:31:01 +08:00
AnnAngela
e9dd64b6f0
Update comments of fs-rmSync.js 2022-04-06 10:20:57 +08:00
Louis Lam
355aec46dc Merge branch 'master' into status-page-domain 2022-04-05 22:59:39 +08:00
Louis Lam
c9deea9fdf
Merge pull request #1456 from Arubinu/alerta
Fix "API key parameter 'undefined' is invalid"
2022-04-05 22:51:33 +08:00
Louis Lam
70311f7a5a Add an option to enable/disable the domain name expiry notification #1364 2022-04-05 21:27:50 +08:00
Louis Lam
4b99160b1f Fix "Check Update" is not checked by default 2022-04-05 19:43:23 +08:00
Louis Lam
48d679234a Stop bree and cloudflared while the server shutting down 2022-04-05 19:41:29 +08:00
Louis Lam
d8b32d652f Update .dockerignore 2022-04-05 16:44:55 +08:00
Alvin Pergens
d3d1656625
Fix "API key parameter 'undefined' is invalid" 2022-04-05 08:47:35 +02:00
AnnAngela-work
8e78e62eee Make translation better 2022-04-04 17:24:22 +08:00
AnnAngela
706d6cee07
Update some components to use i18n function, update en & zh-CN translation 2022-04-04 11:33:02 +08: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
AnnAngela-work
43eed45bae first part of zh-CN.js translation 2022-04-03 22:08:24 +08:00
AnnAngela-work
19b7e2ba5e Using grep to search $t("foo")-like pattern to fill up the missing part of en i18n file 2022-04-03 22:08:03 +08:00
Louis Lam
99042e6991 Update to 1.14.0-beta.1 2022-04-03 22:06:39 +08:00
Louis Lam
f54084c888 Update beta release process 2022-04-03 22:06:36 +08:00
Louis Lam
87d3853b8e
Merge pull request #1348 from AnnAngela/master
Detect if `fs.rmSync` is available to avoid the runtime deprecation warning
2022-04-02 18:21:12 +08:00
Louis Lam
4738581c66 Update dependencies 2022-04-02 11:34:00 +08:00
Louis Lam
3218a0eee8 Merge remote-tracking branch 'origin/master' 2022-04-02 11:26:24 +08:00
Louis Lam
87ee3c20bd Update proxy password field 2022-04-02 11:25:27 +08:00
Louis Lam
38e6e846bf
Refresh sponsor list 2022-04-01 23:22:15 +08:00
Louis Lam
92ab2b12d0
Refresh sponsor list 2022-04-01 17:37:04 +08:00
Jimmy Huang
a4be651118
Update server/model/monitor.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-04-01 15:26:50 +08:00
Louis Lam
04e3394d02 Merge branch 'master' into feature/request-with-http-proxy
# Conflicts:
#	package-lock.json
#	package.json
#	server/database.js
#	src/languages/en.js
#	src/mixins/socket.js
2022-04-01 14:57:35 +08:00
Louis Lam
f6cd2f60ca
Merge pull request #1442 from BCsabaEngine/master
fix: update hu lang
2022-04-01 14:46:56 +08:00
Balázs Csaba
53cea7f8d3 fix: update hu lang 2022-03-31 22:25:22 +02:00
Louis Lam
aef7719426
Merge pull request #1435 from LoaderB0T/favico
feat: Favicon is updated based on satus page logo
2022-03-31 21:32:13 +08:00
Louis Lam
514b9fb68a Add remark 2022-03-31 21:30:07 +08:00
Louis Lam
da32a1aa19 Add uk-UA to the languageList 2022-03-31 16:24:28 +08:00
Louis Lam
7a69f9f56f
Merge pull request #1438 from Deni7/master
Add ukrainian translation
2022-03-31 16:22:29 +08:00
Louis Lam
c50c20faa4 Minor fix for uk-UA 2022-03-31 16:19:04 +08:00
Louis Lam
cb6eeaef34 Bring connection error bar to the top 2022-03-31 16:15:34 +08:00
Louis Lam
6674005e8b Fix storing cloudflared token while start cloudflared 2022-03-31 15:58:39 +08:00
Denis Stepanov
ee3d7d8b42
Add ukrainian translation 2022-03-30 23:21:09 +03:00
Denis Stepanov
a277cfe9e8
Add ukrainian translation 2022-03-30 23:16:04 +03:00
Denis Stepanov
95b0df0270
Add ukrainian translation 2022-03-30 23:15:28 +03:00
Louis Lam
f02e9c44ec Update to 1.14.0-beta.0 2022-03-30 23:37:23 +08:00
Louis Lam
bb2b5cd6ac
Merge pull request #1427 from louislam/cloudflared
Built-in ease-to-use reverse proxy with Cloudflare Tunnel
2022-03-30 20:15:48 +08:00
Louis Lam
b72a2d350f Set cloudflared token from env var or arg 2022-03-30 20:08:26 +08:00
Louis Lam
71be030733 Add package-lock.json and minor words 2022-03-30 18:52:10 +08:00
Janik Schumacher
73b338bba6 feat: Favicon is updated based on satus page logo 2022-03-30 12:09:38 +02:00
Louis Lam
82ea896bbc Improve the workflow of cloudflared 2022-03-30 11:59:49 +08:00
Louis Lam
f1f4b3b377 Add reverse proxy setting page for controlling cloudflared 2022-03-30 01:49:45 +08:00
Louis Lam
a6b52b7ba6 Merge branch 'master' into cloudflared 2022-03-29 17:42:55 +08:00
Louis Lam
b8dea3a823 Merge remote-tracking branch 'origin/master' 2022-03-29 17:39:12 +08:00
Louis Lam
0da6e6b1fb Some improvements 2022-03-29 17:38:48 +08:00
Louis Lam
44fb2a88f2 Add cloudflared socket handler 2022-03-29 14:48:02 +08:00
Louis Lam
623b06e33c
Merge pull request #1426 from DX37/translation-ru
update russian translation
2022-03-29 14:14:21 +08:00
Louis Lam
7d3cbff794 [Cloudflared] Install into base docker 2022-03-29 02:24:10 +08:00
DX37
61d0a0abce
update russian translation 2022-03-28 21:16:13 +07: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
AnnAngela
7fd5b61bab
Inproperly conflict resolving 2022-03-27 21:12:51 +08:00
AnnAngela
96289fe014
Update index.js 2022-03-27 20:56:42 +08:00
AnnAngela
381605aca1
Update update-version.js 2022-03-27 20:55:28 +08:00
AnnAngela
742c6bcaa3
Merge branch 'master' into master 2022-03-27 20:54:24 +08:00
Matthew Nickson
88604845e6
Merge branch 'master' into #1209-Logout-button-in-navbar 2022-03-27 13:48:50 +01:00
Louis Lam
be88351eb3
Merge pull request #1136 from chakflying/fix/prometheus-on-delete
Fix: Remove prometheus metrics on delete [Test needed]
2022-03-27 11:05:50 +08:00
Louis Lam
34a0b54b93
Merge pull request #1418 from sovushik/patch-11
Update ru-RU.js
2022-03-26 14:11:32 +08:00
sovushik
e11ea7b061
Update ru-RU.js
Add new string for 1.13.1
2022-03-26 10:46:07 +05:00
Louis Lam
12237dec6e Merge remote-tracking branch 'origin/master' 2022-03-26 02:09:25 +08:00
Louis Lam
f6272155af Show page not found for invalid routes 2022-03-26 02:09:12 +08:00
Louis Lam
630b441a2d
Merge pull request #1414 from ivanbratovic/croatian-language
Update croatian (hr-HR) translation file
2022-03-25 19:00:06 +08:00
Louis Lam
1ecd2e45d0 [Status Page] Plan to support domain names for status pages 2022-03-25 18:59:06 +08:00
Ivan Bratović
5922771909 Update croatian (hr-HR) translation file
Signed-off-by: Ivan Bratović <ivanbratovic4@gmail.com>
2022-03-25 11:05:51 +01:00
MrEddX
a7e1a78ea9
Update bg-BG.js
Fixed translation.
2022-03-25 07:31:26 +02:00
Louis Lam
623d03dc6f Fix release process 2022-03-25 00:03:25 +08:00
Louis Lam
f52e527850 Update to 1.13.1 2022-03-24 23:47:03 +08:00
Louis Lam
28d72fcd08 Fix #1409, slug cannot be empty 2022-03-24 23:43:07 +08:00
Louis Lam
6c7a0ff7d3 Fix release script 2022-03-24 22:44:22 +08:00
Louis Lam
2abdf2efad Update to 1.13.0 2022-03-24 22:21:19 +08:00
Louis Lam
71af08189e Clear useless code 2022-03-24 18:03:31 +08:00
Louis Lam
d32ba7cadd Fix #1318, basic auth is completely disabled if the auth is disabled 2022-03-24 18:02:34 +08:00
Louis Lam
775d1696fa Fix pushover device not working #1114 2022-03-24 12:14:17 +08:00
Louis Lam
7fb16d2f9a Limit the pm2 log size 2022-03-23 11:17:23 +08:00
Louis Lam
40991fbc28 Show reverse proxy guide along with websocket error 2022-03-22 23:46:13 +08:00
Louis Lam
bf20f9d290 Merge remote-tracking branch 'origin/master' 2022-03-22 21:37:18 +08:00
Louis Lam
5fa14161c4 Minor css 2022-03-22 21:37:04 +08:00
Louis Lam
5a2a59250d
Merge pull request #1405 from sovushik/patch-9
Update ru-RU.js
2022-03-22 17:17:37 +08:00
Louis Lam
fcee93cbea
Merge pull request #1404 from sovushik/patch-8
Update ru-RU.js
2022-03-22 17:16:55 +08:00
Louis Lam
668dffc2c5 Simplify final release 2022-03-22 16:45:07 +08:00
sovushik
210eebe144
Update ru-RU.js
Add some fix for 1.13
2022-03-22 13:00:16 +05:00
sovushik
4b04a9c214
Update ru-RU.js
Add new string for version 1.13
2022-03-22 12:58:38 +05:00
Louis Lam
909618a29a Update to 1.13.0-beta.2 2022-03-22 14:30:54 +08:00
Louis Lam
4a4ffc96dd Fix setup 2022-03-22 12:00:13 +08:00
Louis Lam
3713692bdd Merge remote-tracking branch 'origin/master' 2022-03-22 11:31:01 +08:00
Louis Lam
76f991ecd8 Update beta process 2022-03-22 11:30:45 +08:00
Louis Lam
84dcd81f21
Merge pull request #1400 from MrEddX/bulgarian
Update bg-BG.js
2022-03-22 10:50:59 +08:00
MrEddX
f65d0654a6
Update bg-BG.js
Added new field.
2022-03-21 21:12:15 +02:00
Louis Lam
b0bda9f9d2 Fix beta release script 2022-03-22 01:00:35 +08:00
Louis Lam
ad2130b7b5 [Status Page] Fix monitors are deleted unexpectedly #1399 2022-03-22 00:06:29 +08:00
Louis Lam
4545eec3fe Better sticky monitor list 2022-03-21 23:53:55 +08:00
Louis Lam
3adda48f3a Load the status page list earlier 2022-03-21 15:28:59 +08:00
Louis Lam
cafa61e3af Add beta tag 2022-03-21 14:32:55 +08:00
Louis Lam
58ee071fae Release process for beta 2022-03-21 14:31:29 +08:00
Louis Lam
9173838e1b Merge remote-tracking branch 'origin/master' 2022-03-21 11:50:27 +08:00
Louis Lam
833d9381ff
Merge pull request #1393 from burakurer/patch-1
Update tr-TR.js
2022-03-21 11:50:17 +08:00
burakurer
73d904952d
Update tr-TR.js
spelling correction "Sağlık Dırımları" => "Sağlık Durumları"
2022-03-20 17:03:32 +03:00
Louis Lam
4e95e9ea51 Add process for beta release 2022-03-20 11:08:33 +08:00
Louis Lam
c22cc4d794
Merge pull request #1385 from jtagcat/patch-1
Update et-EE.js
2022-03-20 10:56:24 +08:00
Louis Lam
8cbdefdc0d
Merge pull request #1390 from pemassi/patch-3
Update ko-KR.js
2022-03-20 10:55:51 +08:00
Kyungyoon Kim
2f5beefa37
Update ko-KR.js 2022-03-19 03:19:02 -06:00
jtagcat
dae5ff690a
Update et-EE.js 2022-03-18 13:56:45 +00:00
Louis Lam
fb9a206542 [Status Page] Fix - show no status page 2022-03-18 21:47:14 +08:00
jtagcat
dc3da45dd6
Update et-EE.js 2022-03-18 11:27:33 +00:00
Louis Lam
82049a2387
Merge pull request #863 from louislam/restructure-status-page
Restructure status page core implementation
2022-03-18 18:07:15 +08:00
Louis Lam
d7a839aa52 [Status Page] Fix reset entry page 2022-03-18 17:57:08 +08:00
Louis Lam
aef0a66205 [Status Page] Simplify show tags logic 2022-03-18 17:56:46 +08:00
Louis Lam
37be7df9b0 [Status Page] Delete status page 2022-03-18 15:19:52 +08:00
Louis Lam
243fab5f26 Rollback vite to 2.6.x (Not sure, but sometimes vue routes are no longer response during dev randomly) 2022-03-18 15:02:49 +08:00
Louis Lam
8d981c8f0b [Status Page] Fix migration and unpin incident 2022-03-18 14:14:22 +08:00
Louis Lam
220e46bc83 [Status Page] Fix theme bug 2022-03-18 12:57:37 +08:00
Louis Lam
59cdacc052 [Status Page] Enable Edit Mode only if the token is presented 2022-03-18 12:39:48 +08:00
Louis Lam
00738edbe7 [Status Page] Add ?edit 2022-03-18 00:00:56 +08:00
Louis Lam
27bfae67af [Status Page] Add a new status page 2022-03-17 23:38:43 +08:00
Louis Lam
719a136d1e [Status Page] Improved entry page 2022-03-17 22:44:47 +08:00
Louis Lam
502c7f87e7 [Status Page] Listing: Better loading effect 2022-03-17 19:07:05 +08:00
Louis Lam
78a732409b [Status Page] Fix translations 2022-03-17 18:56:59 +08:00
Louis Lam
c0c6419980 [Status Page] align icon and title using flexbox 2022-03-17 17:07:23 +08:00
Louis Lam
5474368263 Update vite to 2.8.6 2022-03-17 16:56:25 +08:00
Louis Lam
e87cdf4d09 [Status Page] wip, upload logo and status page listing 2022-03-17 16:42:26 +08:00
Louis Lam
bb1c951a96 Update node.js from 14 to 16 2022-03-17 13:04:43 +08:00
Louis Lam
1033ca5cf4 [Status Page] wip, combine api, add status_page_id into group and incident tables 2022-03-16 15:38:10 +08:00
Louis Lam
18ec42b060 [Status Page] wip 2022-03-16 14:14:47 +08:00
Louis Lam
7c7dbf68c1 [Status Page] wip, sidebar for editor 2022-03-15 12:00:29 +08:00
Louis Lam
3e96504813 Update denpendencies 2022-03-13 17:14:57 +08:00
Louis Lam
d765b1c57a Merge branch 'master' into restructure-status-page
# Conflicts:
#	src/pages/StatusPage.vue
2022-03-12 15:50:42 +08:00
Louis Lam
5f778b9763
Merge pull request #835 from willianrod/feat/add-favicon-badges
Add badges to favicon
2022-03-12 15:39:18 +08:00
Louis Lam
c68f7944e3 [Favicon] minor 2022-03-12 15:31:01 +08:00
Louis Lam
a9efdabcec [Favicon] Prevent error when no heartbeat 2022-03-12 15:30:02 +08:00
Louis Lam
b9dfcd1291 [Favicon] Code refactoring 2022-03-12 15:10:45 +08:00
Louis Lam
04d93c2747 Merge branch 'master' into willianrod_feat/add-favicon-badges
# Conflicts:
#	package-lock.json
#	src/mixins/socket.js
2022-03-12 11:17:32 +08:00
Louis Lam
c65d771fad
Merge pull request #1358 from BCsabaEngine/master
fix: .hu lang
2022-03-12 10:38:37 +08:00
Louis Lam
3f8a396090
Merge pull request #1362 from MrEddX/bulgarian
Bulgarian
2022-03-12 10:37:46 +08:00
Louis Lam
9681957adf
Merge pull request #1366 from deanilvincent/update-version-of-check-password-strength
check-password-strength new version update 2.0.5
2022-03-12 10:25:06 +08:00
Mark Vicente
95a2c967c6 check-password-strength new version 2.0.5 that support additional symbols/special characters referenced from owasp list. 2022-03-11 23:48:35 +08:00
Louis Lam
50d6e888c2 [new status page] wip 2022-03-10 21:34:30 +08:00
Louis Lam
ae14ad5a84 Add a word "Status Pages" 2022-03-09 22:14:07 +08:00
MrEddX
edd9202de9
Update bg-BG.js
Translation fix.
2022-03-08 22:14:07 +02:00
MrEddX
a97d2a5498
Update bg-BG.js
Added new fields.
2022-03-08 22:10:17 +02:00
Louis Lam
72ce28a541 Migrate status page table 2022-03-08 14:33:35 +08:00
Louis Lam
1e2a8453c6 Merge branch 'master' into restructure-status-page 2022-03-08 14:21:04 +08:00
Louis Lam
1fa4a16663 Check beta release 2022-03-07 16:24:24 +08:00
Louis Lam
6a57c443fd Set telegram as the default notification type 2022-03-07 15:52:17 +08:00
Uğur Erkan
8078d0618d Add socks proxy support to proxy feature
- Socks proxy support implemented.
- Monitor proxy agent create flow refactored
  and moved under proxy class.

Thanks for suggestion @thomasleveil
2022-03-06 19:34:51 +03:00
Uğur Erkan
9e27acb511 Add socks proxy agent 2022-03-06 19:34:51 +03:00
Uğur Erkan
78d76512ba Add http and https proxy feature
Added new proxy feature based on http and https proxy agents.
Proxy feature works like notifications, there is many proxy
could be related one proxy entry.

Supported features
- Proxies can activate and disable in bulk
- Proxies auto enabled by default for new monitors
- Proxies could be applied in bulk to current monitors
- Both authenticated and anonymous proxies supported
- Export and import support for proxies
2022-03-06 19:34:49 +03:00
Uğur Erkan
2cc7a990ff Add http and https agents 2022-03-06 19:29:28 +03:00
Balázs Csaba
157f0de61a fix: .hu lang 2022-03-05 21:24:50 +01:00
Louis Lam
88c3d952d3 Improve settings page's UI/UX on mobile 2022-03-04 23:20:42 +08:00
Louis Lam
e3a0eaf6af Sort notification types in case-insensitive 2022-03-04 21:48:35 +08:00
Louis Lam
8bbf55777e
Merge pull request #1205 from arjunkomath/master
Add notification provider - Push
2022-03-04 21:39:59 +08:00
Louis Lam
c0e0698c21
Merge pull request #1225 from Computroniks/fix-checkbox-css
Fixed dark mode checkbox
2022-03-04 14:35:15 +08:00
Louis Lam
14d8095f12
Merge pull request #1228 from Arubinu/alerta
Alerta Notification Service
2022-03-04 14:19:53 +08:00
Louis Lam
fa490d0bf1 [Alerta] Handle general message 2022-03-04 14:13:44 +08:00
Louis Lam
c52c8a4206 Merge branch 'master' into alerta
# Conflicts:
#	server/notification.js
#	src/components/notifications/index.js
#	src/languages/en.js
2022-03-04 14:10:37 +08:00
Louis Lam
9789d8cde8 Merge branch 'master' into alerta 2022-03-04 14:09:01 +08:00
Louis Lam
ccb3d85a48
Merge pull request #1157 from zackelia/master
Implement gorush notifications
2022-03-03 22:03:09 +08:00
Louis Lam
333505b039 Merge remote-tracking branch 'origin/master' 2022-03-03 20:49:13 +08:00
Louis Lam
602da565eb Sort notification types 2022-03-03 20:49:00 +08:00
Louis Lam
b62d94184a Merge branch 'master' into restructure-status-page 2022-03-03 17:09:15 +08:00
Louis Lam
e0175d0010
Delete stale-bot.yml, no idea why it deleted some feature request 2022-03-03 10:21:34 +08:00
Louis Lam
3246055696
Merge pull request #1350 from deluxghost/patch-1
Update zh-CN.js
2022-03-02 23:20:47 +08:00
deluxghost
b3a690f3b1
Update zh-CN.js 2022-03-02 23:12:30 +08:00
Louis Lam
7bc8c447cd Merge branch 'MikMuellerDev_master'
# Conflicts:
#	src/languages/de-DE.js
2022-03-02 17:17:15 +08:00
Louis Lam
69ff6831ab
Merge pull request #1311 from deluxghost/update-zh-cn
Update zh-CN translations
2022-03-02 16:58:54 +08:00
AnnAngela
88a798704b
Update fs-rmSync.js 2022-03-02 16:10:14 +08:00
AnnAngela-work
783173fd1f Add a helper function 2022-03-02 15:48:08 +08:00
DX
0dba06e48b Update zh-CN translations 2022-03-02 15:34:11 +08:00
AnnAngela-work
281fe365c0 Mark the version as 1.11.4 in package-lock.json 2022-03-02 15:23:08 +08:00
Louis Lam
8e7c0a6163 Update pull request rules 2022-03-02 14:25:37 +08:00
Louis Lam
0671e4ea2b Merge remote-tracking branch 'AnnAngela/master'
# Conflicts:
#	src/languages/zh-CN.js
2022-03-02 13:43:34 +08:00
Louis Lam
cd8eaef903
Merge pull request #1187 from pfandie/translations-de
Updates some DE translations
2022-03-02 13:39:19 +08:00
Louis Lam
51f5c009e3 Merge remote-tracking branch 'PrikolMen/patch-1'
# Conflicts:
#	src/languages/ru-RU.js
2022-03-02 13:37:21 +08:00
Louis Lam
3bf62c9ceb Merge branch 'patch-7-ru'
# Conflicts:
#	src/languages/ru-RU.js
2022-03-02 13:33:37 +08:00
Louis Lam
7b11539cff Merge branch 'patch-62'
# Conflicts:
#	src/languages/ru-RU.js
2022-03-02 13:31:43 +08:00
PrikolMen:-b
b4a3d68356
More correct Russian translation
I tried to fix most of the shortcomings of the Russian translation...
2022-02-28 14:55:23 +04:00
Louis Lam
b31af8a15c update to 1.12.1 2022-02-26 17:05:13 +08:00
Louis Lam
60f67ccb35 Revert commit: a6fd626f 2022-02-26 16:57:13 +08:00
Louis Lam
81a9807a0a Update release procedures 2022-02-26 16:03:43 +08:00
Louis Lam
3681934d05 Update Apprise to 0.9.7 2022-02-26 15:57:26 +08:00
Mik Mueller
a997f8e4f9 Update de-DE.js 2022-02-15 12:58:02 +01:00
Mik Mueller
09dbb143ea
Merge branch 'louislam:master' into master 2022-02-15 12:51:21 +01:00
Hans Mayer
f19e983818
Merge remote-tracking branch 'origin/master' into translations-de 2022-02-14 14:39:21 +01:00
Jens Neuber
454c1687cf Merge branch 'master' of https://github.com/louislam/uptime-kuma into uptime-badges 2022-02-13 11:12:22 +01:00
AnnAngela
c75c6c5640
Update zh-CN.js
Update DingDing and AliyunSms setting dialogs for better translations and document links
2022-02-11 22:50:46 +08:00
AnnAngela
5aed36b470
Update zh-CN
----
关于 smtpDkimKeySelector:
Google Workspace 的帮助里用词为
[前缀选择器](https://annangela.page.link/smtpDkimKeySelector)
2022-02-10 22:45:24 +08:00
sovushik
76b9fb967f
Update ru-RU.js
Add new string
2022-02-09 21:37:45 +05:00
sovushik
b58120d258
Update ru-RU.js
Correct some words on Russian
2022-02-09 21:26:47 +05:00
Jimmy Huang
244a7b3671
Update server/model/monitor.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-02-07 18:46:16 +08:00
Mik Mueller
7d8b72c6c0
Merge branch 'louislam:master' into master 2022-02-06 10:57:10 +01:00
Hans Mayer
40cc885eb8
resolve conflict after update state 2022-02-05 11:48:48 +01:00
Mik Mueller
f1007ad42f Update de-DE.js 2022-02-02 22:59:13 +01:00
Mik Mueller
dd28ecaa2d Update de-DE.js 2022-02-02 22:57:02 +01:00
Mik Mueller
ffa585376d
Merge branch 'louislam:master' into master 2022-02-02 22:54:23 +01:00
Mik Mueller
11c2e86bfe
Update src/languages/de-DE.js
Co-authored-by: Alf <62615304+Alf-Melmac@users.noreply.github.com>
2022-02-01 08:13:30 +01:00
Mik Mueller
1bbf17f3da
Update src/languages/de-DE.js
Co-authored-by: Alf <62615304+Alf-Melmac@users.noreply.github.com>
2022-02-01 08:13:23 +01:00
Mik Mueller
39f8b30b36
Update src/languages/de-DE.js
Co-authored-by: Alf <62615304+Alf-Melmac@users.noreply.github.com>
2022-02-01 08:13:13 +01:00
Mik Mueller
ffb2c2996b
Update src/languages/de-DE.js
Co-authored-by: Alf <62615304+Alf-Melmac@users.noreply.github.com>
2022-02-01 08:12:42 +01:00
Mik Mueller
b13b20bd95 improve certain German words and phrases, improve grammer in README.md 2022-01-30 00:17:25 +01:00
Alvin Pergens
8febff9282 fix comments 2022-01-28 15:35:33 +01:00
Alvin Pergens
90f2497548 change data for Alerta 2022-01-28 15:14:34 +01:00
Jens Neuber
28be32fc68 Merge branch 'master' of https://github.com/louislam/uptime-kuma into uptime-badges 2022-01-28 08:36:05 +01:00
Alvin Pergens
cefe43800f add alerta service 2022-01-27 20:54:04 +01:00
Computroniks
97a5b400db
Added log out button to nav bar
Implements Logout button in navbar #1209

Signed-off-by: Computroniks <mnickson@sidingsmedia.com>
2022-01-27 19:45:31 +00:00
Computroniks
ca89f84b9a
Added sign-out-alt icon
Signed-off-by: Computroniks <mnickson@sidingsmedia.com>
2022-01-27 18:57:14 +00:00
Computroniks
eaf370637e
Fixed dark mode checkbox
The border colour of the checkbox has been changed to make it more
visible to the user when the dark mode is in use.

Signed-off-by: Computroniks <mnickson@sidingsmedia.com>
2022-01-27 17:40:03 +00:00
Karel Krýda
b49e5d5c39 The SQL query to determine if the monitor is under maintenance is now in its own method. 2022-01-25 19:07:27 +01:00
Jimmy Huang
ee90d2713f refs issue-1201 in upstream.
Add 100 characters from response body to bean.msg after keyword not match.
2022-01-25 17:39:19 +08:00
Karel Krýda
e7b2832967 The start and end dates of the maintenance are now stored in UTC, which allows it to be converted between time zones 2022-01-24 22:33:15 +01: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
Karel Krýda
5fda1f0f59 minor fixes (missing commas, spaces, translations) 2022-01-23 20:33:39 +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
Karel Krýda
0d3414c6d6 A complete maintenance planning system has been created 2022-01-23 15:22:00 +01:00
Raphael Bernhart
dd3992063e
Apply suggestions from code review
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-22 13:59:36 +01:00
c0derMo
29df70949d Add ability to connect to daemon via http / tcp for windows compatibility 2022-01-22 01:57:37 +00:00
Raphael Bernhart
0313acd4c5 🐛 Fix bug where a condition was wrong-false 2022-01-21 17:22:30 +01:00
Raphael Bernhart
cd19b9fc49 💫 Improve hearbeat animation 2022-01-21 17:13:38 +01:00
Raphael Bernhart
c57b2c4d28 💄 Fix spacing to get pixel perfectness 2022-01-21 17:13:24 +01:00
Raphael Bernhart
3dda5938f2 💄 Add condition to div tag for styling reasons 2022-01-21 15:39:49 +01:00
Arjun Komath
23796723dd
Address code review
Add missing comma

Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-21 20:42:08 +11:00
Arjun Komath
51b7a2badb remove log 2022-01-21 07:43:14 +00:00
Arjun Komath
74c584f544 Add Push by Techulus 2022-01-21 07:42:03 +00:00
Tarun Singh
0345719e53 added cleartimeout in case client is already ended 2022-01-20 13:20:54 -05:00
Tarun Singh
22256dfcd2 added timeout for removing the dead loop state 2022-01-20 13:04:59 -05:00
Hans Mayer
3e87eb596f
change wording, according to PR suggestions 2022-01-15 12:25:17 +01:00
Hans Mayer
c679613f7e
Updates some DE translations, fix typo in resolverserverDescription, removes some duplicates in languages 2022-01-14 19:06:21 +01: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
Louis Lam
227bbdea2f [MQTT] Try to improve error handling 2022-01-13 12:42:34 +08:00
Louis Lam
6272514820 [MQTT] Use existing fields instead of creating new ones (Server) 2022-01-13 11:53:08 +08:00
Louis Lam
1c8407a433 [MQTT] Use existing fields instead of creating new ones (UI) 2022-01-13 11:36:55 +08:00
Louis Lam
32ec4beda0 Merge branch 'master' into mqtt 2022-01-13 11:24:45 +08:00
Louis Lam
9462646ad3 Fix vulnerabilities 2022-01-13 11:22:58 +08:00
Louis Lam
482b3f9233
Update server/util-server.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-13 11:20:32 +08:00
Louis Lam
6014ed1156 Fix conflict 2022-01-13 11:19:26 +08:00
Louis Lam
bfee63452d Merge branch 'master' into mqtt 2022-01-13 11:16:58 +08:00
Louis Lam
076d6bdbb6 Merge branch 'master' into mqtt
# Conflicts:
#	package-lock.json
#	server/database.js
2022-01-13 11:09:16 +08:00
Zack Elia
ea43422ccf Implement gorush notifications 2022-01-09 12:05:11 -05:00
Marc Harnos
0bbe157099
change parsing priority for all passed arguments
update all passed args in server.js to prioritize command line, then use
env.UPTIME_KUMA_ environment variables, then use the generic environment
variable versions env.HOST, env.PORT, env.SSL_KEY, env.SSL_CERT and fall
back to default values where applicable
2022-01-08 18:32:42 +01:00
Marc Harnos
0053a29d10
add validation to port value parsing
only port configurations that are valid (not isNaN) after parseInt
are considered to be used in port variable
2022-01-08 18:27:39 +01:00
Marc Harnos
2c8d5d28e9
simplify host fallback logic
move decision logic for freeBSD HOST environment var into temp var
2022-01-08 18:25:12 +01:00
Nelson Chan
1bbd744d02 Chore: Improve syntax 2022-01-07 14:29:42 +08:00
Nelson Chan
2e0e35a1ee Fix: Fix typo 2022-01-07 12:34:01 +08:00
Nelson Chan
1e92487f30 Chore: Remove onDelete as unused 2022-01-07 12:28:08 +08:00
Nelson Chan
edd2534a1b Fix: Clear metrics also on stop and edit 2022-01-07 12:26:26 +08:00
Nelson Chan
f6ef390c76 Fix: Remove Prom. metrics on delete monitor 2022-01-07 12:04:57 +08:00
Jens Neuber
f00ec4dfef
PR feedback: remove spaces in parenthesis
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-05 15:26:29 +01:00
Jens Neuber
43f8fc701c
PR feedback: remove spaces in parenthesis
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-05 15:26:23 +01:00
Jens Neuber
499042504f
PR feedback: remove spaces in parenthesis
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-05 15:26:07 +01:00
Jens Neuber
faf6719e7c
PR feedback: remove spaces in parenthesis
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-05 15:25:56 +01:00
Jens Neuber
a9d264ccfc
PR feedback: remove spaces in comments
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2022-01-05 15:25:42 +01:00
Jens Neuber
df8f93f0c2 clean uptime percentage display 2022-01-05 11:48:25 +01:00
Jens Neuber
28c0e16a0c PR feedback 2022-01-04 16:01:40 +01:00
Jens Neuber
6acc9546a0 PR feedback + remove redundant code + add a test 2022-01-04 16:00:21 +01:00
Jens Neuber
f455e3a454 add shields.io 'style' parameter 2022-01-04 13:43:13 +01:00
Jens Neuber
7abbf421d0 PR feedback 2022-01-04 12:23:16 +01:00
Jens Neuber
3625915a85 add ping, status badge 2022-01-04 12:21:53 +01:00
Jens Neuber
d74404e106 minor fixes 2022-01-03 16:23:23 +01:00
Jens Neuber
1c5bce8afa a little documentation 2022-01-03 16:04:37 +01:00
Jens Neuber
8b5997691e Merge branch 'master' of https://github.com/louislam/uptime-kuma into uptime-badges 2022-01-03 15:49:00 +01:00
Jens Neuber
35360e2069 add badges 2022-01-03 15:48:52 +01:00
Louis Lam
72a59ce7a4 add status page table 2021-12-27 18:54:48 +08:00
Jakub Blažej
3d002b3ce9 add status boolean parameter to push monitor 2021-12-25 20:25:21 +01:00
Patrick Hafner
3d6c52fbea
Merge branch 'master' into customstatuspage 2021-12-25 04:12:05 +01:00
Patrick Hafner
9ee591417d Footer HTML support, updated german translation 2021-12-25 04:09:41 +01:00
Tarun Singh
4118de6d53 fix protocol not defined bug 2021-12-23 19:39:47 -05:00
Patrick Hafner
3a12e209da Edit: editMode check before toggle 2021-12-21 03:55:25 +01:00
Patrick Hafner
2c2a824f97 Add: en & de-DE language 2021-12-21 03:31:09 +01:00
Patrick Hafner
931ca6a3ef Add: customize status page (css and poweredby) 2021-12-21 03:27:05 +01:00
Tarun Singh
d3c90df8a8 fixed edit monitor fields empty issues 2021-12-18 16:35:18 -05:00
Andreas Brett
38f8a8ac2f
Merge branch 'louislam:master' into logging 2021-12-10 17:21:55 +01:00
Louis Lam
807519d07d Merge branch 'master' into restructure-status-page 2021-12-09 21:46:35 +08:00
Andreas Brett
e684712a77
Merge branch 'louislam:master' into logging 2021-12-07 18:21:56 +01:00
Tarun Singh
5afc6a41e3 removed https requirement for url 2021-12-06 11:28:23 -05:00
Andreas Brett
dcc7856b5d
Merge branch 'louislam:master' into logging 2021-12-04 09:59:10 +01:00
Andreas Brett
c9b0a81cdc
Update MonitorHistory.vue 2021-11-29 20:39:57 +01:00
Andreas Brett
2f97f44086
Update MonitorHistory.vue 2021-11-29 20:37:44 +01:00
Andreas Brett
a13bdaac84
Merge branch 'master' into logging 2021-11-29 20:32:42 +01:00
Fluency
e3745da986
Merge branch 'master' into master 2021-11-23 10:26:45 -08:00
Tarun Singh
35da8c78f4 added connection timeout and refactored code 2021-11-22 03:21:53 -05:00
Fluency
7179c6cc4c
Fix punctuation in extra/update-version.js
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2021-11-19 10:30:31 -08:00
Andreas Brett
ed96757b24
Merge branch 'louislam:master' into logging 2021-11-19 08:56:25 +01:00
Tarun Singh
3306f4a8e0 removed extra logging 2021-11-18 14:03:23 -05:00
Fluency
a2de9e4e36
Fixed export-function signature being scrambled. 2021-11-17 16:02:31 -08:00
Tarun Singh
3f5133d1ba Added authentication logic 2021-11-16 20:44:10 -05:00
Andreas Brett
6f2dcc6dd7 using provided tsc config 2021-11-15 18:07:18 +01:00
Andreas Brett
57bed4d672
Merge branch 'louislam:master' into logging 2021-11-15 18:04:45 +01:00
Andreas Brett
df36a4bb3c console.info for level "info" 2021-11-15 18:02:14 +01:00
Andreas Brett
e5913c5abc separate log functions 2021-11-15 17:52:28 +01:00
Andreas Brett
d21f7971b5 missed settings 2021-11-11 12:56:53 +01:00
Andreas Brett
bdcdf47e52 introduce consistent logging 2021-11-11 12:31:28 +01:00
Calum Bird
f55350bebc Generated documentation :) 2021-11-09 21:24:31 -08:00
Tarun Singh
3721d11259 changed table column names for more specifity 2021-11-09 18:53:00 -05:00
Tarun Singh
149015556b server url changes 2021-11-04 22:25:29 -04:00
Tarun Singh
2bcbeba384
update review suggestions
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2021-11-04 22:23:02 -04:00
Tarun Singh
d5d07da4ee
update review suggestions
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2021-11-04 22:22:53 -04:00
Tarun Singh
2d802585ff
Update review suggestions
Co-authored-by: Adam Stachowicz <saibamenppl@gmail.com>
2021-11-04 22:21:54 -04:00
Tarun Singh
6828e8ef6d Merge branch 'master' of https://github.com/tarun7singh/uptime-kuma 2021-11-03 21:47:44 -04:00
Tarun Singh
670754b697 added MQTT monitor type 2021-11-03 21:46:43 -04:00
Louis Lam
6d1baa329a draft for restructure status page 2021-11-02 12:26:22 +08:00
Willian Rodrigues Barbosa
036218f711 Add badges to favicon 2021-10-29 22:25:32 -03:00
320 changed files with 40633 additions and 11091 deletions

View File

@ -1,6 +1,7 @@
/.idea /.idea
/node_modules /node_modules
/data /data
/cypress
/out /out
/test /test
/kubernetes /kubernetes
@ -28,6 +29,11 @@ SECURITY.md
tsconfig.json tsconfig.json
.env .env
/tmp /tmp
/babel.config.js
/ecosystem.config.js
/extra/healthcheck.exe
/extra/healthcheck
### .gitignore content (commented rules are duplicated) ### .gitignore content (commented rules are duplicated)
@ -42,4 +48,6 @@ dist-ssr
#!/data/.gitkeep #!/data/.gitkeep
#.vscode #.vscode
### End of .gitignore content ### End of .gitignore content

View File

@ -19,3 +19,6 @@ indent_size = 2
[*.vue] [*.vue]
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.go]
indent_style = tab

View File

@ -1,4 +1,9 @@
module.exports = { module.exports = {
ignorePatterns: [
"test/*",
"server/modules/apicache/*",
"src/util.js"
],
root: true, root: true,
env: { env: {
browser: true, browser: true,
@ -17,39 +22,48 @@ module.exports = {
requireConfigFile: false, requireConfigFile: false,
}, },
rules: { rules: {
"linebreak-style": ["error", "unix"], "yoda": "error",
"camelcase": ["warn", { eqeqeq: [ "warn", "smart" ],
"linebreak-style": [ "error", "unix" ],
"camelcase": [ "warn", {
"properties": "never", "properties": "never",
"ignoreImports": true "ignoreImports": true
}], }],
// override/add rules settings here, such as: "no-unused-vars": [ "warn", {
// 'vue/no-unused-vars': 'error' "args": "none"
"no-unused-vars": "warn", }],
indent: [ indent: [
"error", "error",
4, 4,
{ {
ignoredNodes: ["TemplateLiteral"], ignoredNodes: [ "TemplateLiteral" ],
SwitchCase: 1, SwitchCase: 1,
}, },
], ],
quotes: ["warn", "double"], quotes: [ "error", "double" ],
semi: "warn", semi: "error",
"vue/html-indent": ["warn", 4], // default: 2 "vue/html-indent": [ "error", 4 ], // default: 2
"vue/max-attributes-per-line": "off", "vue/max-attributes-per-line": "off",
"vue/singleline-html-element-content-newline": "off", "vue/singleline-html-element-content-newline": "off",
"vue/html-self-closing": "off", "vue/html-self-closing": "off",
"vue/require-component-is": "off", // not allow is="style" https://github.com/vuejs/eslint-plugin-vue/issues/462#issuecomment-430234675
"vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly "vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly
"no-multi-spaces": ["error", { "vue/multi-word-component-names": "off",
"no-multi-spaces": [ "error", {
ignoreEOLComments: true, ignoreEOLComments: true,
}], }],
"space-before-function-paren": ["error", { "array-bracket-spacing": [ "warn", "always", {
"singleValue": true,
"objectsInArrays": false,
"arraysInArrays": false
}],
"space-before-function-paren": [ "error", {
"anonymous": "always", "anonymous": "always",
"named": "never", "named": "never",
"asyncArrow": "always" "asyncArrow": "always"
}], }],
"curly": "error", "curly": "error",
"object-curly-spacing": ["error", "always"], "object-curly-spacing": [ "error", "always" ],
"object-curly-newline": "off", "object-curly-newline": "off",
"object-property-newline": "error", "object-property-newline": "error",
"comma-spacing": "error", "comma-spacing": "error",
@ -59,37 +73,37 @@ module.exports = {
"keyword-spacing": "warn", "keyword-spacing": "warn",
"space-infix-ops": "warn", "space-infix-ops": "warn",
"arrow-spacing": "warn", "arrow-spacing": "warn",
"no-trailing-spaces": "warn", "no-trailing-spaces": "error",
"no-constant-condition": ["error", { "no-constant-condition": [ "error", {
"checkLoops": false, "checkLoops": false,
}], }],
"space-before-blocks": "warn", "space-before-blocks": "warn",
//'no-console': 'warn', //'no-console': 'warn',
"no-extra-boolean-cast": "off", "no-extra-boolean-cast": "off",
"no-multiple-empty-lines": ["warn", { "no-multiple-empty-lines": [ "warn", {
"max": 1, "max": 1,
"maxBOF": 0, "maxBOF": 0,
}], }],
"lines-between-class-members": ["warn", "always", { "lines-between-class-members": [ "warn", "always", {
exceptAfterSingleLine: true, exceptAfterSingleLine: true,
}], }],
"no-unneeded-ternary": "error", "no-unneeded-ternary": "error",
"array-bracket-newline": ["error", "consistent"], "array-bracket-newline": [ "error", "consistent" ],
"eol-last": ["error", "always"], "eol-last": [ "error", "always" ],
//'prefer-template': 'error', //'prefer-template': 'error',
"comma-dangle": ["warn", "only-multiline"], "comma-dangle": [ "warn", "only-multiline" ],
"no-empty": ["error", { "no-empty": [ "error", {
"allowEmptyCatch": true "allowEmptyCatch": true
}], }],
"no-control-regex": "off", "no-control-regex": "off",
"one-var": ["error", "never"], "one-var": [ "error", "never" ],
"max-statements-per-line": ["error", { "max": 1 }] "max-statements-per-line": [ "error", { "max": 1 }]
}, },
"overrides": [ "overrides": [
{ {
"files": [ "src/languages/*.js", "src/icon.js" ], "files": [ "src/languages/*.js", "src/icon.js" ],
"rules": { "rules": {
"comma-dangle": ["error", "always-multiline"], "comma-dangle": [ "error", "always-multiline" ],
} }
}, },

View File

@ -1,3 +1,9 @@
⚠️⚠️⚠️ Since we do not accept all types of pull requests and do not want to waste your time. Please be sure that you have read pull request rules:
https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma
Tick the checkbox if you understand [x]:
- [ ] I have read and understand the pull request rules.
# Description # Description
Fixes #(issue) Fixes #(issue)
@ -20,6 +26,7 @@ Please delete any options that are not relevant.
- [ ] I ran ESLint and other linters for modified files - [ ] I ran ESLint and other linters for modified files
- [ ] I have performed a self-review of my own code and tested it - [ ] I have performed a self-review of my own code and tested it
- [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have commented my code, particularly in hard-to-understand areas
(including JSDoc for methods)
- [ ] My changes generate no new warnings - [ ] My changes generate no new warnings
- [ ] My code needed automated testing. I have added them (this is optional task) - [ ] My code needed automated testing. I have added them (this is optional task)

View File

@ -11,25 +11,74 @@ on:
jobs: jobs:
auto-test: auto-test:
needs: [ check-linters ]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy: strategy:
matrix: matrix:
os: [macos-latest, ubuntu-latest, windows-latest] os: [macos-latest, ubuntu-latest, windows-latest]
node-version: [14.x, 16.x, 17.x] node: [ 14, 16, 18, 19 ]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps: steps:
- uses: actions/checkout@v2 - run: git config --global core.autocrlf false # Mainly for Windows
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v2 uses: actions/setup-node@v3
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node }}
cache: 'npm' cache: 'npm'
- run: npm run install-legacy - run: npm install
- run: npm run build - run: npm run build
- run: npm test - run: npm test
env: env:
HEADLESS_TEST: 1 HEADLESS_TEST: 1
JUST_FOR_TEST: ${{ secrets.JUST_FOR_TEST }} JUST_FOR_TEST: ${{ secrets.JUST_FOR_TEST }}
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 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
frontend-unit-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:run:unit

View File

@ -1,22 +1,22 @@
name: 'Automatically close stale issues and PRs' name: 'Automatically close stale issues and PRs'
on: on:
workflow_dispatch:
schedule: schedule:
- cron: '0 0 * * *' - cron: '0 */6 * * *'
#Run once a day at midnight #Run every 6 hours
jobs: jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v4 - uses: actions/stale@v5
with: with:
stale-issue-message: 'We are clearing up our old issues and your ticket has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' 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 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' close-issue-message: 'This issue was closed because it has been stalled for 2 days with no activity.'
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' days-before-stale: 90
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' days-before-close: 2
days-before-stale: 180 days-before-pr-stale: 999999999
days-before-close: 0 days-before-pr-close: 1
exempt-issue-labels: 'News,Medium,High,discussion,bug,doc,' 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-issue-assignees: 'louislam'
exempt-pr-assignees: 'louislam' operations-per-run: 200

7
.gitignore vendored
View File

@ -13,3 +13,10 @@ dist-ssr
/out /out
/tmp /tmp
.env .env
cypress/videos
cypress/screenshots
/extra/healthcheck.exe
/extra/healthcheck
/extra/healthcheck-armv7

1
.npmrc Normal file
View File

@ -0,0 +1 @@
legacy-peer-deps=true

View File

@ -1,9 +1,14 @@
{ {
"extends": "stylelint-config-standard", "extends": "stylelint-config-standard",
"customSyntax": "postcss-html",
"rules": { "rules": {
"indentation": 4, "indentation": 4,
"no-descending-specificity": null, "no-descending-specificity": null,
"selector-list-comma-newline-after": null, "selector-list-comma-newline-after": null,
"declaration-empty-line-before": null "declaration-empty-line-before": null,
"alpha-value-notation": "number",
"color-function-notation": "legacy",
"shorthand-property-no-redundant-values": null,
"color-hex-length": null,
} }
} }

View File

@ -1,6 +1,6 @@
# Project Info # Project Info
First of all, thank you everyone who made pull requests for Uptime Kuma, I never thought GitHub Community can be that nice! And also because of this, I also never thought other people actually read my code and edit my code. It is not structured and commented so well, lol. Sorry about that. First of all, I want to thank everyone who made pull requests for Uptime Kuma. I never thought the GitHub Community would be so nice! Because of this, I also never thought that other people would actually read and edit my code. It is not very well structured or commented, sorry about that.
The project was created with vite.js (vue3). Then I created a subdirectory called "server" for server part. Both frontend and backend share the same package.json. The project was created with vite.js (vue3). Then I created a subdirectory called "server" for server part. Both frontend and backend share the same package.json.
@ -27,12 +27,43 @@ The frontend code build into "dist" directory. The server (express.js) exposes t
## Can I create a pull request for Uptime Kuma? ## Can I create a pull request for Uptime Kuma?
Generally, if the pull request is working fine, and it does not affect any existing logic, workflow and performance, I will merge into the master branch once it is tested. 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 have a discussion first**. Especially for a large pull request or you don't know it will be merged or not.
Here are some references:
✅ Usually Accept:
- Bug/Security fix
- Translations
- Adding notification providers
⚠️ Discussion First
- Large pull requests
- New features
❌ Won't Merge
- Do not pass auto test
- 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
- Convert existing code into other programming languages
- Unnecessary large code changes (Hard to review, causes code conflicts to other pull requests)
The above cases cannot cover all situations.
I (@louislam) have the final say. If your pull request does not meet my expectations, I will reject it, no matter how much time you spend on it. Therefore, it is essential to have a discussion beforehand.
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.
If you are not sure whether I will accept your pull request, feel free to create an empty pull request draft first.
### Recommended Pull Request Guideline ### Recommended Pull Request Guideline
Before deep into coding, discussion first is preferred. Creating an empty pull request for discussion would be recommended.
1. Fork the project 1. Fork the project
1. Clone your fork repo to local 1. Clone your fork repo to local
1. Create a new branch 1. Create a new branch
@ -42,78 +73,38 @@ If you are not sure whether I will accept your pull request, feel free to create
1. Create a pull request: https://github.com/louislam/uptime-kuma/compare 1. Create a pull request: https://github.com/louislam/uptime-kuma/compare
1. Write a proper description 1. Write a proper description
1. Click "Change to draft" 1. Click "Change to draft"
1. Discussion
### Pull Request Examples
Here are some example situations in the past.
#### ✅ High - Medium Priority
Easy to review, no breaking change and not touching the existing code
- Add a new notification
- Add a chart
- Fix a bug
- Translations
- Add a independent new feature
#### *️⃣ Requires one more reviewer
I do not have such knowledge to test it.
- Add k8s supports
#### ⚠ Low Priority - Harsh Mode
Some pull requests are required to modify the core. To be honest, I do not want anyone to try to do that, because it would spend a lot of your time. I will review your pull request harshly. Also, you may need to write a lot of unit tests to ensure that there is no breaking change.
- Touch large parts of code of any very important features
- Touch monitoring logic
- Drop a table or drop a column for any reason
- Touch the entry point of Docker or Node.js
- Modify auth
#### *️⃣ Low Priority
It changed my current workflow and require further studies.
- Change my release approach
#### ❌ Won't Merge
- Any breaking changes
- Duplicated pull request
- Buggy
- Existing logic is completely modified or deleted
- A function that is completely out of scope
## Project Styles ## Project Styles
I personally do not like something need to learn so much and need to config so much before you can finally start the app. I personally do not like it when something requires so much learning and configuration before you can finally start the app.
- Easy to install for non-Docker users, no native build dependency is needed (at least for x86_64), no extra config, no extra effort to get it run - Easy to install for non-Docker users, no native build dependency is needed (at least for x86_64), no extra config, no extra effort required to get it running
- Single container for Docker users, no very complex docker-compose file. Just map the volume and expose the port, then good to go - Single container for Docker users, no very complex docker-compose file. Just map the volume and expose the port, then good to go
- Settings should be configurable in the frontend. Env var is not encouraged. - Settings should be configurable in the frontend. Environment variable is not encouraged, unless it is related to startup such as `DATA_DIR`.
- Easy to use - Easy to use
- The web UI styling should be consistent and nice.
## Coding Styles ## Coding Styles
- 4 spaces indentation - 4 spaces indentation
- Follow `.editorconfig` - Follow `.editorconfig`
- Follow ESLint - Follow ESLint
- Methods and functions should be documented with JSDoc
## Name convention ## Name convention
- Javascript/Typescript: camelCaseType - Javascript/Typescript: camelCaseType
- SQLite: underscore_type - SQLite: snake_case (Underscore)
- CSS/SCSS: dash-type - CSS/SCSS: kebab-case (Dash)
## Tools ## Tools
- Node.js >= 14 - Node.js >= 14
- NPM >= 8.5
- Git - Git
- IDE that supports ESLint and EditorConfig (I am using IntelliJ IDEA) - IDE that supports ESLint and EditorConfig (I am using IntelliJ IDEA)
- A SQLite tool (SQLite Expert Personal is suggested) - A SQLite GUI tool (SQLite Expert Personal is suggested)
## Install dependencies ## Install dependencies
@ -121,39 +112,45 @@ I personally do not like something need to learn so much and need to config so m
npm ci npm ci
``` ```
## How to start the Backend Dev Server ## Dev Server
(2021-09-23 Update) (2022-04-26 Update)
We can start the frontend dev server and the backend dev server in one command.
Port `3000` and port `3001` will be used.
```bash ```bash
npm run start-server-dev npm run dev
``` ```
## Backend Server
It binds to `0.0.0.0:3001` by default. It binds to `0.0.0.0:3001` by default.
### Backend Details
It is mainly a socket.io app + express.js. It is mainly a socket.io app + express.js.
express.js is just used for serving the frontend built files (index.html, .js and .css etc.) express.js is used for:
- entry point such as redirecting to a status page or the dashboard
- serving the frontend built files (index.html, .js and .css etc.)
- serving internal APIs of status page
### Structure in /server/
- model/ (Object model, auto mapping to the database table name) - model/ (Object model, auto mapping to the database table name)
- modules/ (Modified 3rd-party modules) - modules/ (Modified 3rd-party modules)
- notification-providers/ (individual notification logic) - notification-providers/ (individual notification logic)
- routers/ (Express Routers) - routers/ (Express Routers)
- socket-handler (Socket.io Handlers) - socket-handler (Socket.io Handlers)
- server.js (Server main logic) - server.js (Server entry point and main logic)
## How to start the Frontend Dev Server ## Frontend Dev Server
1. Set the env var `NODE_ENV` to "development". It binds to `0.0.0.0:3000` by default. Frontend dev server is used for development only.
2. Start the frontend dev server by the following command.
```bash For production, it is not used. It will be compiled to `dist` directory instead.
npm run dev
```
It binds to `0.0.0.0:3000` by default.
You can use Vue.js devtools Chrome extension for debugging. You can use Vue.js devtools Chrome extension for debugging.
@ -180,16 +177,23 @@ The data and socket logic are in `src/mixins/socket.js`.
## Unit Test ## Unit Test
It is an end-to-end testing. It is using Jest and Puppeteer.
```bash ```bash
npm run build npm run build
npm test npm test
``` ```
By default, the Chromium window will be shown up during the test. Specifying `HEADLESS_TEST=1` for terminal environments. ## Dependencies
## Update 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` Install `ncu`
https://github.com/raineorshine/npm-check-updates https://github.com/raineorshine/npm-check-updates
@ -221,14 +225,13 @@ https://github.com/louislam/uptime-kuma/issues?q=sort%3Aupdated-desc
### Release Procedures ### Release Procedures
1. Draft a release note 1. Draft a release note
1. Make sure the repo is cleared 2. Make sure the repo is cleared
1. `npm run update-version 1.X.X` 3. `npm run release-final with env vars: `VERSION` and `GITHUB_TOKEN`
1. `npm run build` 4. Wait until the `Press any key to continue`
1. `npm run build-docker` 5. `git push`
1. `git push` 6. Publish the release note as 1.X.X
1. Publish the release note as 1.X.X 7. Press any key to continue
1. `npm run upload-artifacts` 8. SSH to demo site server and update to 1.X.X
1. SSH to demo site server and update to 1.X.X
Checking: Checking:
@ -236,6 +239,15 @@ Checking:
- Try the Docker image with tag 1.X.X (Clean install / amd64 / arm64 / armv7) - Try the Docker image with tag 1.X.X (Clean install / amd64 / arm64 / armv7)
- Try clean installation with Node.js - Try clean installation with Node.js
### Release Beta Procedures
1. Draft a release note, check "This is a pre-release"
2. Make sure the repo is cleared
3. `npm run release-beta` with env vars: `VERSION` and `GITHUB_TOKEN`
4. Wait until the `Press any key to continue`
5. Publish the release note as 1.X.X-beta.X
6. Press any key to continue
### Release Wiki ### Release Wiki
#### Setup Repo #### Setup Repo

View File

@ -7,47 +7,51 @@
<img src="./public/icon.svg" width="128" alt="" /> <img src="./public/icon.svg" width="128" alt="" />
</div> </div>
It is a self-hosted monitoring tool like "Uptime Robot". Uptime Kuma is an easy-to-use self-hosted monitoring tool.
<img src="https://uptime.kuma.pet/img/dark.jpg" width="700" alt="" /> <img src="https://user-images.githubusercontent.com/1336778/212262296-e6205815-ad62-488c-83ec-a5b0d0689f7c.jpg" width="700" alt="" />
## 🥔 Live Demo ## 🥔 Live Demo
Try it! Try it!
https://demo.uptime.kuma.pet - Tokyo Demo Server: https://demo.uptime.kuma.pet (Sponsored by [Uptime Kuma Sponsors](https://github.com/louislam/uptime-kuma#%EF%B8%8F-sponsors))
- Europe Demo Server: https://demo.uptime-kuma.karimi.dev:27000 (Provided by [@mhkarimi1383](https://github.com/mhkarimi1383))
It is a temporary live demo, all data will be deleted after 10 minutes. The server is located in Tokyo, so if you live far from there, it may affect your experience. I suggest that you should install and try it out for the best demo experience. It is a temporary live demo, all data will be deleted after 10 minutes. Use the one that is closer to you, but I suggest that you should install and try it out for the best demo experience.
VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollective.com/uptime-kuma)! Thank you so much!
## ⭐ Features ## ⭐ 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. * Fancy, Reactive, Fast UI/UX
* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications). * 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. * 20 second intervals
* [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages) * [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages)
* Simple Status Page * Multiple status pages
* Ping Chart * Map status pages to specific domains
* Certificate Info * Ping chart
* Certificate info
* Proxy support
* 2FA support
## 🔧 How to Install ## 🔧 How to Install
### 🐳 Docker ### 🐳 Docker
```bash ```bash
docker volume create uptime-kuma
docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1 docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
``` ```
⚠️ Please use a **local volume** only. Other types such as NFS are not supported. ⚠️ Please use a **local volume** only. Other types such as NFS are not supported.
Browse to http://localhost:3001 after starting. Uptime Kuma is now running on http://localhost:3001
### 💪🏻 Non-Docker ### 💪🏻 Non-Docker
Required Tools: Node.js >= 14, git and pm2. Required Tools:
- [Node.js](https://nodejs.org/en/download/) >= 14
- [Git](https://git-scm.com/downloads)
- [pm2](https://pm2.keymetrics.io/) - For running Uptime Kuma in the background
```bash ```bash
# Update your npm to the latest version # Update your npm to the latest version
@ -61,11 +65,25 @@ npm run setup
node server/server.js node server/server.js
# (Recommended) Option 2. Run in background using PM2 # (Recommended) Option 2. Run in background using PM2
# Install PM2 if you don't have it: npm install pm2 -g # Install PM2 if you don't have it:
pm2 start server/server.js --name uptime-kuma npm install pm2 -g && pm2 install pm2-logrotate
```
Browse to http://localhost:3001 after starting. # Start Server
pm2 start server/server.js --name uptime-kuma
```
Uptime Kuma is now running on http://localhost:3001
More useful PM2 Commands
```bash
# If you want to see the current console output
pm2 monit
# If you want to add it to startup
pm2 save && pm2 startup
```
### Advanced Installation ### Advanced Installation
@ -87,13 +105,13 @@ https://github.com/louislam/uptime-kuma/milestones
Project Plan: Project Plan:
https://github.com/louislam/uptime-kuma/projects/1 https://github.com/users/louislam/projects/4/views/1
## ❤️ Sponsors ## ❤️ Sponsors
Thank you so much! (GitHub Sponsors will be updated manually. OpenCollective sponsors will be updated automatically, the list will be cached by GitHub though. It may need some time to be updated) Thank you so much! (GitHub Sponsors will be updated manually. OpenCollective sponsors will be updated automatically, the list will be cached by GitHub though. It may need some time to be updated)
<img src="https://uptime.kuma.pet/sponsors?v=3" alt /> <img src="https://uptime.kuma.pet/sponsors?v=6" alt />
## 🖼 More Screenshots ## 🖼 More Screenshots
@ -115,7 +133,7 @@ Telegram Notification Sample:
## Motivation ## Motivation
* I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the close ones is statping. Unfortunately, it is not stable and unmaintained. * I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the close ones is statping. Unfortunately, it is not stable and no longer maintained.
* Want to build a fancy UI. * Want to build a fancy UI.
* Learn Vue 3 and vite.js. * Learn Vue 3 and vite.js.
* Show the power of Bootstrap 5. * Show the power of Bootstrap 5.
@ -132,16 +150,30 @@ You can discuss or ask for help in [issues](https://github.com/louislam/uptime-k
### Subreddit ### 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. 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 ## Contribute
If you want to report a bug or request a new feature. Free feel to open a [new issue](https://github.com/louislam/uptime-kuma/issues). ### 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
### Bug Reports / Feature Requests
If you want to report a bug or request a new feature, feel free to open a [new issue](https://github.com/louislam/uptime-kuma/issues).
### Translations
If you want to translate Uptime Kuma into your language, please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages If you want to translate Uptime Kuma into your language, please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages
If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md 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.
English proofreading is needed too because my grammar is not that great, sadly. Feel free to correct my grammar in this README, source code, or wiki. ### 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

@ -2,21 +2,15 @@
## Reporting a Vulnerability ## Reporting a Vulnerability
Please report security issues to uptime@kuma.pet. Please report security issues to https://github.com/louislam/uptime-kuma/security/advisories/new.
Do not use the issue tracker or discuss it in the public as it will cause more damage. Do not use the public issue tracker or discuss it in the public as it will cause more damage.
## Supported Versions ## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
### Uptime Kuma Versions ### Uptime Kuma Versions
| Version | Supported | You should use or upgrade to the latest version of Uptime Kuma. All `1.X.X` versions are upgradable to the lastest version.
| ------- | ------------------ |
| 1.9.X | :white_check_mark: |
| <= 1.8.X | ❌ |
### Upgradable Docker Tags ### Upgradable Docker Tags
@ -24,8 +18,8 @@ currently being supported with security updates.
| ------- | ------------------ | | ------- | ------------------ |
| 1 | :white_check_mark: | | 1 | :white_check_mark: |
| 1-debian | :white_check_mark: | | 1-debian | :white_check_mark: |
| 1-alpine | :white_check_mark: |
| latest | :white_check_mark: | | latest | :white_check_mark: |
| debian | :white_check_mark: | | debian | :white_check_mark: |
| alpine | :white_check_mark: | | 1-alpine | ⚠️ Deprecated |
| alpine | ⚠️ Deprecated |
| All other tags | ❌ | | All other tags | ❌ |

View File

@ -1,11 +1,11 @@
const config = {}; const config = {};
if (process.env.TEST_FRONTEND) { if (process.env.TEST_FRONTEND) {
config.presets = ["@babel/preset-env"]; config.presets = [ "@babel/preset-env" ];
} }
if (process.env.TEST_BACKEND) { if (process.env.TEST_BACKEND) {
config.plugins = ["babel-plugin-rewire"]; config.plugins = [ "babel-plugin-rewire" ];
} }
module.exports = config; module.exports = config;

28
config/cypress.config.js Normal file
View File

@ -0,0 +1,28 @@
const { defineConfig } = require("cypress");
module.exports = defineConfig({
projectId: "vyjuem",
e2e: {
experimentalStudio: true,
setupNodeEvents(on, config) {
},
fixturesFolder: "test/cypress/fixtures",
screenshotsFolder: "test/cypress/screenshots",
videosFolder: "test/cypress/videos",
downloadsFolder: "test/cypress/downloads",
supportFile: "test/cypress/support/e2e.js",
baseUrl: "http://localhost:3002",
defaultCommandTimeout: 10000,
pageLoadTimeout: 60000,
viewportWidth: 1920,
viewportHeight: 1080,
specPattern: [
"test/cypress/e2e/setup.cy.js",
"test/cypress/e2e/**/*.js"
],
},
env: {
baseUrl: "http://localhost:3002",
},
});

View File

@ -0,0 +1,10 @@
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
supportFile: false,
specPattern: [
"test/cypress/unit/**/*.js"
],
}
});

View File

@ -1,33 +0,0 @@
const PuppeteerEnvironment = require("jest-environment-puppeteer");
const util = require("util");
class DebugEnv extends PuppeteerEnvironment {
async handleTestEvent(event, state) {
const ignoredEvents = [
"setup",
"add_hook",
"start_describe_definition",
"add_test",
"finish_describe_definition",
"run_start",
"run_describe_start",
"test_start",
"hook_start",
"hook_success",
"test_fn_start",
"test_fn_success",
"test_done",
"run_describe_finish",
"run_finish",
"teardown",
"test_fn_failure",
];
if (!ignoredEvents.includes(event.name)) {
console.log(
new Date().toString() + ` Unhandled event [${event.name}] ` + util.inspect(event)
);
}
}
}
module.exports = DebugEnv;

View File

@ -1,5 +0,0 @@
module.exports = {
"rootDir": "..",
"testRegex": "./test/frontend.spec.js",
};

View File

@ -1,20 +0,0 @@
module.exports = {
"launch": {
"dumpio": true,
"slowMo": 500,
"headless": process.env.HEADLESS_TEST || false,
"userDataDir": "./data/test-chrome-profile",
args: [
"--disable-setuid-sandbox",
"--disable-gpu",
"--disable-dev-shm-usage",
"--no-default-browser-check",
"--no-experiments",
"--no-first-run",
"--no-pings",
"--no-sandbox",
"--no-zygote",
"--single-process",
],
}
};

View File

@ -1,12 +0,0 @@
module.exports = {
"verbose": true,
"preset": "jest-puppeteer",
"globals": {
"__DEV__": true
},
"testRegex": "./test/e2e.spec.js",
"testEnvironment": "./config/jest-debug-env.js",
"rootDir": "..",
"testTimeout": 30000,
};

View File

@ -1,24 +1,53 @@
import legacy from "@vitejs/plugin-legacy"; import legacy from "@vitejs/plugin-legacy";
import vue from "@vitejs/plugin-vue"; import vue from "@vitejs/plugin-vue";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import visualizer from "rollup-plugin-visualizer";
import viteCompression from "vite-plugin-compression";
const postCssScss = require("postcss-scss"); const postCssScss = require("postcss-scss");
const postcssRTLCSS = require("postcss-rtlcss"); const postcssRTLCSS = require("postcss-rtlcss");
const viteCompressionFilter = /\.(js|mjs|json|css|html|svg)$/i;
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
server: {
port: 3000,
},
define: {
"FRONTEND_VERSION": JSON.stringify(process.env.npm_package_version),
},
plugins: [ plugins: [
vue(), vue(),
legacy({ legacy({
targets: ["ie > 11"], targets: [ "since 2015" ],
additionalLegacyPolyfills: ["regenerator-runtime/runtime"] }),
}) visualizer({
filename: "tmp/dist-stats.html"
}),
viteCompression({
algorithm: "gzip",
filter: viteCompressionFilter,
}),
viteCompression({
algorithm: "brotliCompress",
filter: viteCompressionFilter,
}),
], ],
css: { css: {
postcss: { postcss: {
"parser": postCssScss, "parser": postCssScss,
"map": false, "map": false,
"plugins": [postcssRTLCSS] "plugins": [ postcssRTLCSS ]
} }
}, },
build: {
rollupOptions: {
output: {
manualChunks(id, { getModuleInfo, getModuleIds }) {
}
}
},
}
}); });

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 auth_method VARCHAR(250);
ALTER TABLE monitor
ADD auth_domain TEXT;
ALTER TABLE monitor
ADD auth_workstation TEXT;
COMMIT;
BEGIN TRANSACTION;
UPDATE monitor
SET auth_method = 'basic'
WHERE basic_auth_user is not null;
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 @@
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD database_connection_string VARCHAR(2000);
ALTER TABLE monitor
ADD database_query TEXT;
COMMIT

View File

@ -0,0 +1,16 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD mqtt_topic TEXT;
ALTER TABLE monitor
ADD mqtt_success_message VARCHAR(255);
ALTER TABLE monitor
ADD mqtt_username VARCHAR(255);
ALTER TABLE monitor
ADD mqtt_password VARCHAR(255);
COMMIT;

25
db/patch-grpc-monitor.sql Normal file
View File

@ -0,0 +1,25 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD grpc_url VARCHAR(255) default null;
ALTER TABLE monitor
ADD grpc_protobuf TEXT default null;
ALTER TABLE monitor
ADD grpc_body TEXT default null;
ALTER TABLE monitor
ADD grpc_metadata TEXT default null;
ALTER TABLE monitor
ADD grpc_method VARCHAR(255) default null;
ALTER TABLE monitor
ADD grpc_service_name VARCHAR(255) default null;
ALTER TABLE monitor
ADD grpc_enable_tls BOOLEAN default 0 not null;
COMMIT;

View File

@ -0,0 +1,83 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
-- Just for someone who tested maintenance before (patch-maintenance-table.sql)
DROP TABLE IF EXISTS maintenance_status_page;
DROP TABLE IF EXISTS monitor_maintenance;
DROP TABLE IF EXISTS maintenance;
DROP TABLE IF EXISTS maintenance_timeslot;
-- maintenance
CREATE TABLE [maintenance] (
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[title] VARCHAR(150) NOT NULL,
[description] TEXT NOT NULL,
[user_id] INTEGER REFERENCES [user]([id]) ON DELETE SET NULL ON UPDATE CASCADE,
[active] BOOLEAN NOT NULL DEFAULT 1,
[strategy] VARCHAR(50) NOT NULL DEFAULT 'single',
[start_date] DATETIME,
[end_date] DATETIME,
[start_time] TIME,
[end_time] TIME,
[weekdays] VARCHAR2(250) DEFAULT '[]',
[days_of_month] TEXT DEFAULT '[]',
[interval_day] INTEGER
);
CREATE INDEX [manual_active] ON [maintenance] (
[strategy],
[active]
);
CREATE INDEX [active] ON [maintenance] ([active]);
CREATE INDEX [maintenance_user_id] ON [maintenance] ([user_id]);
-- maintenance_status_page
CREATE TABLE maintenance_status_page (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
status_page_id INTEGER NOT NULL,
maintenance_id INTEGER NOT NULL,
CONSTRAINT FK_maintenance FOREIGN KEY (maintenance_id) REFERENCES maintenance (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_status_page FOREIGN KEY (status_page_id) REFERENCES status_page (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX [status_page_id_index]
ON [maintenance_status_page]([status_page_id]);
CREATE INDEX [maintenance_id_index]
ON [maintenance_status_page]([maintenance_id]);
-- maintenance_timeslot
CREATE TABLE [maintenance_timeslot] (
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[maintenance_id] INTEGER NOT NULL CONSTRAINT [FK_maintenance] REFERENCES [maintenance]([id]) ON DELETE CASCADE ON UPDATE CASCADE,
[start_date] DATETIME NOT NULL,
[end_date] DATETIME,
[generated_next] BOOLEAN DEFAULT 0
);
CREATE INDEX [maintenance_id] ON [maintenance_timeslot] ([maintenance_id] DESC);
CREATE INDEX [active_timeslot_index] ON [maintenance_timeslot] (
[maintenance_id] DESC,
[start_date] DESC,
[end_date] DESC
);
CREATE INDEX [generated_next_index] ON [maintenance_timeslot] ([generated_next]);
-- monitor_maintenance
CREATE TABLE monitor_maintenance (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
monitor_id INTEGER NOT NULL,
maintenance_id INTEGER NOT NULL,
CONSTRAINT FK_maintenance FOREIGN KEY (maintenance_id) REFERENCES maintenance (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_monitor FOREIGN KEY (monitor_id) REFERENCES monitor (id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE INDEX [maintenance_id_index2] ON [monitor_maintenance]([maintenance_id]);
CREATE INDEX [monitor_id_index] ON [monitor_maintenance]([monitor_id]);
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

@ -0,0 +1,7 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor
ADD expiry_notification BOOLEAN default 1;
COMMIT;

23
db/patch-proxy.sql Normal file
View File

@ -0,0 +1,23 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
CREATE TABLE proxy (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
user_id INT NOT NULL,
protocol VARCHAR(10) NOT NULL,
host VARCHAR(255) NOT NULL,
port SMALLINT NOT NULL,
auth BOOLEAN NOT NULL,
username VARCHAR(255) NULL,
password VARCHAR(255) NULL,
active BOOLEAN NOT NULL DEFAULT 1,
'default' BOOLEAN NOT NULL DEFAULT 0,
created_date DATETIME DEFAULT (DATETIME('now')) NOT NULL
);
ALTER TABLE monitor ADD COLUMN proxy_id INTEGER REFERENCES proxy(id);
CREATE INDEX proxy_id ON monitor (proxy_id);
CREATE INDEX proxy_user_id ON proxy (user_id);
COMMIT;

View File

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

31
db/patch-status-page.sql Normal file
View File

@ -0,0 +1,31 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
CREATE TABLE [status_page](
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[slug] VARCHAR(255) NOT NULL UNIQUE,
[title] VARCHAR(255) NOT NULL,
[description] TEXT,
[icon] VARCHAR(255) NOT NULL,
[theme] VARCHAR(30) NOT NULL,
[published] BOOLEAN NOT NULL DEFAULT 1,
[search_engine_index] BOOLEAN NOT NULL DEFAULT 1,
[show_tags] BOOLEAN NOT NULL DEFAULT 0,
[password] VARCHAR,
[created_date] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
[modified_date] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX [slug] ON [status_page]([slug]);
CREATE TABLE [status_page_cname](
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[status_page_id] INTEGER NOT NULL REFERENCES [status_page]([id]) ON DELETE CASCADE ON UPDATE CASCADE,
[domain] VARCHAR NOT NULL UNIQUE
);
ALTER TABLE incident ADD status_page_id INTEGER;
ALTER TABLE [group] ADD status_page_id INTEGER;
COMMIT;

View File

@ -1,8 +1,8 @@
# DON'T UPDATE TO alpine3.13, 1.14, see #41. # DON'T UPDATE TO alpine3.13, 1.14, see #41.
FROM node:14-alpine3.12 FROM node:16-alpine3.12
WORKDIR /app WORKDIR /app
# Install apprise, iputils for non-root ping, setpriv # 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 && \ 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.6 && \ pip3 --no-cache-dir install apprise==1.2.1 && \
rm -rf /root/.cache rm -rf /root/.cache

View File

@ -0,0 +1,16 @@
############################################
# Build in Golang
# Run npm run build-healthcheck-armv7 in the host first, another it will be super slow where it is building the armv7 healthcheck
############################################
FROM golang:1.19.4-buster
WORKDIR /app
ARG TARGETPLATFORM
COPY ./extra/ ./extra/
# Compile healthcheck.go
RUN apt update && \
apt --yes --no-install-recommends install curl && \
curl -sL https://deb.nodesource.com/setup_18.x | bash && \
apt --yes --no-install-recommends install nodejs && \
node ./extra/build-healthcheck.js $TARGETPLATFORM && \
apt --yes remove nodejs

View File

@ -1,12 +1,28 @@
# DON'T UPDATE TO node:14-bullseye-slim, see #372. # DON'T UPDATE TO node:14-bullseye-slim, see #372.
# If the image changed, the second stage image should be changed too # If the image changed, the second stage image should be changed too
FROM node:14-buster-slim FROM node:16-buster-slim
ARG TARGETPLATFORM
WORKDIR /app WORKDIR /app
# Install Curl
# Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv # Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv
# Stupid python3 and python3-pip actually install a lot of useless things into Debian, specify --no-install-recommends to skip them, make the base even smaller than alpine! # Stupid python3 and python3-pip actually install a lot of useless things into Debian, specify --no-install-recommends to skip them, make the base even smaller than alpine!
RUN apt update && \ 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 \ 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 && \ sqlite3 iputils-ping util-linux dumb-init && \
pip3 --no-cache-dir install apprise==0.9.6 && \ pip3 --no-cache-dir install apprise==1.2.1 && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/* && \
apt --yes autoremove
# Install cloudflared
# dpkg --add-architecture arm: cloudflared do not provide armhf, this is workaround. Read more: https://github.com/cloudflare/cloudflared/issues/583
COPY extra/download-cloudflared.js ./extra/download-cloudflared.js
RUN node ./extra/download-cloudflared.js $TARGETPLATFORM && \
dpkg --add-architecture arm && \
apt update && \
apt --yes --no-install-recommends install ./cloudflared.deb && \
rm -rf /var/lib/apt/lists/* && \
rm -f cloudflared.deb && \
apt --yes autoremove

View File

@ -1,13 +1,14 @@
# Simple docker-composer.yml # Simple docker-compose.yml
# You can change your port or volume location # You can change your port or volume location
version: '3.3' version: '3.3'
services: services:
uptime-kuma: uptime-kuma:
image: louislam/uptime-kuma image: louislam/uptime-kuma:1
container_name: uptime-kuma container_name: uptime-kuma
volumes: volumes:
- ./uptime-kuma:/app/data - ./uptime-kuma-data:/app/data
ports: ports:
- 3001:3001 - 3001:3001 # <Host Port>:<Container Port>
restart: always

View File

@ -1,31 +1,82 @@
############################################
# Build in Golang
# Run npm run build-healthcheck-armv7 in the host first, another it will be super slow where it is building the armv7 healthcheck
# Check file: builder-go.dockerfile
############################################
FROM louislam/uptime-kuma:builder-go AS build_healthcheck
############################################
# Build in Node.js
############################################
FROM louislam/uptime-kuma:base-debian AS build FROM louislam/uptime-kuma:base-debian AS build
WORKDIR /app WORKDIR /app
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
COPY .npmrc .npmrc
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci --omit=dev
COPY . . COPY . .
RUN npm ci --production && \ COPY --from=build_healthcheck /app/extra/healthcheck /app/extra/healthcheck
chmod +x /app/extra/entrypoint.sh RUN chmod +x /app/extra/entrypoint.sh
############################################
# ⭐ Main Image
############################################
FROM louislam/uptime-kuma:base-debian AS release FROM louislam/uptime-kuma:base-debian AS release
WORKDIR /app WORKDIR /app
# Copy app files from build layer # Copy app files from build layer
COPY --from=build /app /app COPY --from=build /app /app
EXPOSE 3001 EXPOSE 3001
VOLUME ["/app/data"] VOLUME ["/app/data"]
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD extra/healthcheck
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"] ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"]
CMD ["node", "server/server.js"] CMD ["node", "server/server.js"]
############################################
# Mark as Nightly
############################################
FROM release AS nightly FROM release AS nightly
RUN npm run mark-as-nightly RUN npm run mark-as-nightly
############################################
# Build an image for testing pr
############################################
FROM louislam/uptime-kuma:base-debian AS pr-test
WORKDIR /app
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
## Install Git
RUN apt update \
&& apt --yes --no-install-recommends install curl \
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt update \
&& apt --yes --no-install-recommends install git
## Empty the directory, because we have to clone the Git repo.
RUN rm -rf ./* && chown node /app
USER node
RUN git config --global user.email "no-reply@no-reply.com"
RUN git config --global user.name "PR Tester"
RUN git clone https://github.com/louislam/uptime-kuma.git .
RUN npm ci
EXPOSE 3000 3001
VOLUME ["/app/data"]
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js
CMD ["npm", "run", "start-pr-test"]
############################################
# Upload the artifact to Github # Upload the artifact to Github
############################################
FROM louislam/uptime-kuma:base-debian AS upload-artifact FROM louislam/uptime-kuma:base-debian AS upload-artifact
WORKDIR / WORKDIR /
RUN apt update && \ RUN apt update && \

View File

@ -3,10 +3,12 @@ WORKDIR /app
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
COPY .npmrc .npmrc
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci --omit=dev
COPY . . COPY . .
RUN npm ci --production && \ RUN chmod +x /app/extra/entrypoint.sh
chmod +x /app/extra/entrypoint.sh
FROM louislam/uptime-kuma:base-alpine AS release FROM louislam/uptime-kuma:base-alpine AS release
WORKDIR /app WORKDIR /app

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
apps: [{ apps: [{
name: "uptime-kuma", name: "uptime-kuma",
script: "./server/server.js", script: "./server/server.js",
}] }]
} };

View File

@ -0,0 +1,79 @@
const pkg = require("../../package.json");
const fs = require("fs");
const childProcess = require("child_process");
const util = require("../../src/util");
util.polyfill();
const version = process.env.VERSION;
console.log("Beta Version: " + version);
if (!version || !version.includes("-beta.")) {
console.error("invalid version, beta version only");
process.exit(1);
}
const exists = tagExists(version);
if (! exists) {
// Process package.json
pkg.version = version;
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
// Also update package-lock.json
childProcess.spawnSync("npm", [ "install" ]);
commit(version);
tag(version);
} else {
console.log("version tag exists, please delete the tag or use another tag");
process.exit(1);
}
/**
* Commit updated files
* @param {string} version Version to update to
*/
function commit(version) {
let msg = "Update to " + version;
let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]);
let stdout = res.stdout.toString().trim();
console.log(stdout);
if (stdout.includes("no changes added to commit")) {
throw new Error("commit error");
}
res = childProcess.spawnSync("git", [ "push", "origin", "master" ]);
console.log(res.stdout.toString().trim());
}
/**
* Create a tag with the specified version
* @param {string} version Tag to create
*/
function tag(version) {
let res = childProcess.spawnSync("git", [ "tag", version ]);
console.log(res.stdout.toString().trim());
res = childProcess.spawnSync("git", [ "push", "origin", version ]);
console.log(res.stdout.toString().trim());
}
/**
* Check if a tag exists for the specified version
* @param {string} version Version to check
* @returns {boolean} Does the tag already exist
*/
function tagExists(version) {
if (! version) {
throw new Error("invalid version");
}
let res = childProcess.spawnSync("git", [ "tag", "-l", version ]);
return res.stdout.toString().trim() === version;
}

View File

@ -0,0 +1,27 @@
const childProcess = require("child_process");
const fs = require("fs");
const platform = process.argv[2];
if (!platform) {
console.error("No platform??");
process.exit(1);
}
if (platform === "linux/arm/v7") {
console.log("Arch: armv7");
if (fs.existsSync("./extra/healthcheck-armv7")) {
fs.renameSync("./extra/healthcheck-armv7", "./extra/healthcheck");
console.log("Already built in the host, skip.");
process.exit(0);
} else {
console.log("prebuilt not found, it will be slow! You should execute `npm run build-healthcheck-armv7` before build.");
}
} else {
if (fs.existsSync("./extra/healthcheck-armv7")) {
fs.rmSync("./extra/healthcheck-armv7");
}
}
const output = childProcess.execSync("go build -x -o ./extra/healthcheck ./extra/healthcheck.go").toString("utf8");
console.log(output);

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

@ -29,7 +29,7 @@ const github = require("@actions/github");
owner: issue.owner, owner: issue.owner,
repo: issue.repo, repo: issue.repo,
issue_number: issue.number, issue_number: issue.number,
labels: ["invalid-format"] labels: [ "invalid-format" ]
}); });
// Add the issue closing comment // Add the issue closing comment

View File

@ -0,0 +1,48 @@
//
const http = require("https"); // or 'https' for https:// URLs
const fs = require("fs");
const platform = process.argv[2];
if (!platform) {
console.error("No platform??");
process.exit(1);
}
let arch = null;
if (platform === "linux/amd64") {
arch = "amd64";
} else if (platform === "linux/arm64") {
arch = "arm64";
} else if (platform === "linux/arm/v7") {
arch = "arm";
} else {
console.error("Invalid platform?? " + platform);
}
const file = fs.createWriteStream("cloudflared.deb");
get("https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-" + arch + ".deb");
/**
* Download specified file
* @param {string} url URL to request
*/
function get(url) {
http.get(url, function (res) {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
console.log("Redirect to " + res.headers.location);
get(res.headers.location);
} else if (res.statusCode >= 200 && res.statusCode < 300) {
res.pipe(file);
res.on("end", function () {
console.log("Downloaded");
});
} else {
console.error(res.statusCode);
process.exit(1);
}
});
}

View File

@ -4,6 +4,7 @@ const tar = require("tar");
const packageJSON = require("../package.json"); const packageJSON = require("../package.json");
const fs = require("fs"); const fs = require("fs");
const rmSync = require("./fs-rmSync.js");
const version = packageJSON.version; const version = packageJSON.version;
const filename = "dist.tar.gz"; const filename = "dist.tar.gz";
@ -11,6 +12,12 @@ const filename = "dist.tar.gz";
const url = `https://github.com/louislam/uptime-kuma/releases/download/${version}/${filename}`; const url = `https://github.com/louislam/uptime-kuma/releases/download/${version}/${filename}`;
download(url); download(url);
/**
* Downloads the latest version of the dist from a GitHub release.
* @param {string} url The URL to download from.
*
* Generated by Trelent
*/
function download(url) { function download(url) {
console.log(url); console.log(url);
@ -21,7 +28,7 @@ function download(url) {
if (fs.existsSync("./dist")) { if (fs.existsSync("./dist")) {
if (fs.existsSync("./dist-backup")) { if (fs.existsSync("./dist-backup")) {
fs.rmdirSync("./dist-backup", { rmSync("./dist-backup", {
recursive: true recursive: true
}); });
} }
@ -35,7 +42,7 @@ function download(url) {
tarStream.on("close", () => { tarStream.on("close", () => {
if (fs.existsSync("./dist-backup")) { if (fs.existsSync("./dist-backup")) {
fs.rmdirSync("./dist-backup", { rmSync("./dist-backup", {
recursive: true recursive: true
}); });
} }

19
extra/env2arg.js Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env node
const childProcess = require("child_process");
let env = process.env;
let cmd = process.argv[2];
let args = process.argv.slice(3);
let replacedArgs = [];
for (let arg of args) {
for (let key in env) {
arg = arg.replaceAll(`$${key}`, env[key]);
}
replacedArgs.push(arg);
}
let child = childProcess.spawn(cmd, replacedArgs);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

23
extra/fs-rmSync.js Normal file
View File

@ -0,0 +1,23 @@
const fs = require("fs");
/**
* Detect if `fs.rmSync` is available
* to avoid the runtime deprecation warning triggered for using `fs.rmdirSync` with `{ recursive: true }` in Node.js v16,
* or the `recursive` property removing completely in the future Node.js version.
* See the link below.
*
* @todo Once we drop the support for Node.js v14 (or at least versions before v14.14.0), we can safely replace this function with `fs.rmSync`, since `fs.rmSync` was add in Node.js v14.14.0 and currently we supports all the Node.js v14 versions that include the versions before the v14.14.0, and this function have almost the same signature with `fs.rmSync`.
* @link https://nodejs.org/docs/latest-v16.x/api/deprecations.html#dep0147-fsrmdirpath--recursive-true- the deprecation infomation of `fs.rmdirSync`
* @link https://nodejs.org/docs/latest-v16.x/api/fs.html#fsrmsyncpath-options the document of `fs.rmSync`
* @param {fs.PathLike} path Valid types for path values in "fs".
* @param {fs.RmDirOptions} [options] options for `fs.rmdirSync`, if `fs.rmSync` is available and property `recursive` is true, it will automatically have property `force` with value `true`.
*/
const rmSync = (path, options) => {
if (typeof fs.rmSync === "function") {
if (options.recursive) {
options.force = true;
}
return fs.rmSync(path, options);
}
return fs.rmdirSync(path, options);
};
module.exports = rmSync;

81
extra/healthcheck.go Normal file
View File

@ -0,0 +1,81 @@
/*
* If changed, have to run `npm run build-docker-builder-go`.
* This script should be run after a period of time (180s), because the server may need some time to prepare.
*/
package main
import (
"crypto/tls"
"io/ioutil"
"log"
"net/http"
"os"
"runtime"
"time"
)
func main() {
isFreeBSD := runtime.GOOS == "freebsd"
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
client := http.Client{
Timeout: 28 * time.Second,
}
sslKey := os.Getenv("UPTIME_KUMA_SSL_KEY")
if len(sslKey) == 0 {
sslKey = os.Getenv("SSL_KEY")
}
sslCert := os.Getenv("UPTIME_KUMA_SSL_CERT")
if len(sslCert) == 0 {
sslCert = os.Getenv("SSL_CERT")
}
hostname := os.Getenv("UPTIME_KUMA_HOST")
if len(hostname) == 0 && !isFreeBSD {
hostname = os.Getenv("HOST")
}
if len(hostname) == 0 {
hostname = "127.0.0.1"
}
port := os.Getenv("UPTIME_KUMA_PORT")
if len(port) == 0 {
port = os.Getenv("PORT")
}
if len(port) == 0 {
port = "3001"
}
protocol := ""
if len(sslKey) != 0 && len(sslCert) != 0 {
protocol = "https"
} else {
protocol = "http"
}
url := protocol + "://" + hostname + ":" + port
log.Println("Checking " + url)
resp, err := client.Get(url)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Printf("Health Check OK [Res Code: %d]\n", resp.StatusCode)
}

View File

@ -1,4 +1,5 @@
/* /*
* Deprecated: Changed to healthcheck.go, it will be deleted in the future.
* This script should be run after a period of time (180s), because the server may need some time to prepare. * This script should be run after a period of time (180s), because the server may need some time to prepare.
*/ */
const { FBSD } = require("../server/util-server"); const { FBSD } = require("../server/util-server");

View File

@ -189,7 +189,7 @@ if (type == "local") {
bash("check=$(pm2 --version)"); bash("check=$(pm2 --version)");
if (check == "") { if (check == "") {
println("Installing PM2"); println("Installing PM2");
bash("npm install pm2 -g"); bash("npm install pm2 -g && pm2 install pm2-logrotate");
bash("pm2 startup"); bash("pm2 startup");
} }

View File

@ -4,21 +4,21 @@ const util = require("../src/util");
util.polyfill(); util.polyfill();
const oldVersion = pkg.version const oldVersion = pkg.version;
const newVersion = oldVersion + "-nightly" const newVersion = oldVersion + "-nightly-" + util.genSecret(8);
console.log("Old Version: " + oldVersion) console.log("Old Version: " + oldVersion);
console.log("New Version: " + newVersion) console.log("New Version: " + newVersion);
if (newVersion) { if (newVersion) {
// Process package.json // Process package.json
pkg.version = newVersion pkg.version = newVersion;
pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion) pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion);
pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion) pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion);
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n") fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
// Process README.md // Process README.md
if (fs.existsSync("README.md")) { if (fs.existsSync("README.md")) {
fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion)) fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion));
} }
} }

6
extra/press-any-key.js Normal file
View File

@ -0,0 +1,6 @@
console.log("Git Push and Publish the release note on github, then press any key to continue");
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on("data", process.exit.bind(process, 0));

View File

@ -43,6 +43,11 @@ const main = async () => {
console.log("Finished."); console.log("Finished.");
}; };
/**
* Ask question of user
* @param {string} question Question to ask
* @returns {Promise<string>} Users response
*/
function question(question) { function question(question) {
return new Promise((resolve) => { return new Promise((resolve) => {
rl.question(question, (answer) => { rl.question(question, (answer) => {

View File

@ -1,11 +1,10 @@
console.log("== Uptime Kuma Reset Password Tool =="); console.log("== Uptime Kuma Reset Password Tool ==");
console.log("Loading the database");
const Database = require("../server/database"); const Database = require("../server/database");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const readline = require("readline"); const readline = require("readline");
const { initJWTSecret } = require("../server/util-server"); const { initJWTSecret } = require("../server/util-server");
const User = require("../server/model/user");
const args = require("args-parser")(process.argv); const args = require("args-parser")(process.argv);
const rl = readline.createInterface({ const rl = readline.createInterface({
input: process.stdin, input: process.stdin,
@ -13,8 +12,9 @@ const rl = readline.createInterface({
}); });
const main = async () => { const main = async () => {
console.log("Connecting the database");
Database.init(args); Database.init(args);
await Database.connect(); await Database.connect(false, false, true);
try { try {
// No need to actually reset the password for testing, just make sure no connection problem. It is ok for now. // No need to actually reset the password for testing, just make sure no connection problem. It is ok for now.
@ -31,7 +31,7 @@ const main = async () => {
let confirmPassword = await question("Confirm New Password: "); let confirmPassword = await question("Confirm New Password: ");
if (password === confirmPassword) { if (password === confirmPassword) {
await user.resetPassword(password); await User.resetPassword(user.id, password);
// Reset all sessions by reset jwt secret // Reset all sessions by reset jwt secret
await initJWTSecret(); await initJWTSecret();
@ -53,6 +53,11 @@ const main = async () => {
console.log("Finished."); console.log("Finished.");
}; };
/**
* Ask question of user
* @param {string} question Question to ask
* @returns {Promise<string>} Users response
*/
function question(question) { function question(question) {
return new Promise((resolve) => { return new Promise((resolve) => {
rl.question(question, (answer) => { rl.question(question, (answer) => {

View File

@ -26,7 +26,7 @@ server.on("request", (request, send, rinfo) => {
ttl: 300, ttl: 300,
address: "1.2.3.4" address: "1.2.3.4"
}); });
} if (question.type === Packet.TYPE.AAAA) { } else if (question.type === Packet.TYPE.AAAA) {
response.answers.push({ response.answers.push({
name: question.name, name: question.name,
type: question.type, type: question.type,
@ -135,6 +135,11 @@ server.listen({
udp: 5300 udp: 5300
}); });
/**
* Get human readable request type from request code
* @param {number} code Request code to translate
* @returns {string} Human readable request type
*/
function type(code) { function type(code) {
for (let name in Packet.TYPE) { for (let name in Packet.TYPE) {
if (Packet.TYPE[name] === code) { if (Packet.TYPE[name] === code) {

View File

@ -0,0 +1,51 @@
const { log } = require("../src/util");
const mqttUsername = "louis1";
const mqttPassword = "!@#$LLam";
class SimpleMqttServer {
aedes = require("aedes")();
server = require("net").createServer(this.aedes.handle);
constructor(port) {
this.port = port;
}
/** Start the MQTT server */
start() {
this.server.listen(this.port, () => {
console.log("server started and listening on port ", this.port);
});
}
}
let server1 = new SimpleMqttServer(10000);
server1.aedes.authenticate = function (client, username, password, callback) {
if (username && password) {
console.log(password.toString("utf-8"));
callback(null, username === mqttUsername && password.toString("utf-8") === mqttPassword);
} else {
callback(null, false);
}
};
server1.aedes.on("subscribe", (subscriptions, client) => {
console.log(subscriptions);
for (let s of subscriptions) {
if (s.topic === "test") {
server1.aedes.publish({
topic: "test",
payload: Buffer.from("ok"),
}, (error) => {
if (error) {
log.error("mqtt_server", error);
}
});
}
}
});
server1.start();

View File

@ -1,50 +1,45 @@
// Need to use ES6 to read language files // Need to use ES6 to read language files
import fs from "fs"; import fs from "fs";
import path from "path";
import util from "util"; import util from "util";
import rmSync from "../fs-rmSync.js";
// https://stackoverflow.com/questions/13786160/copy-folder-recursively-in-node-js
/** /**
* Look ma, it's cp -R. * Copy across the required language files
* @param {string} src The path to the thing to copy. * Creates a local directory (./languages) and copies the required files
* @param {string} dest The path to the new copy. * into it.
* @param {string} langCode Code of language to update. A file will be
* created with this code if one does not already exist
* @param {string} baseLang The second base language file to copy. This
* will be ignored if set to "en" as en.js is copied by default
*/ */
const copyRecursiveSync = function (src, dest) { function copyFiles(langCode, baseLang) {
let exists = fs.existsSync(src); if (fs.existsSync("./languages")) {
let stats = exists && fs.statSync(src); rmSync("./languages", { recursive: true });
let isDirectory = exists && stats.isDirectory(); }
fs.mkdirSync("./languages");
if (isDirectory) { if (!fs.existsSync(`../../src/languages/${langCode}.js`)) {
fs.mkdirSync(dest); fs.closeSync(fs.openSync(`./languages/${langCode}.js`, "a"));
fs.readdirSync(src).forEach(function (childItemName) {
copyRecursiveSync(path.join(src, childItemName),
path.join(dest, childItemName));
});
} else { } else {
fs.copyFileSync(src, dest); fs.copyFileSync(`../../src/languages/${langCode}.js`, `./languages/${langCode}.js`);
}
fs.copyFileSync("../../src/languages/en.js", "./languages/en.js");
if (baseLang !== "en") {
fs.copyFileSync(`../../src/languages/${baseLang}.js`, `./languages/${baseLang}.js`);
} }
};
console.log("Arguments:", process.argv);
const baseLangCode = process.argv[2] || "en";
console.log("Base Lang: " + baseLangCode);
if (fs.existsSync("./languages")) {
fs.rmdirSync("./languages", { recursive: true });
} }
copyRecursiveSync("../../src/languages", "./languages");
const en = (await import("./languages/en.js")).default; /**
const baseLang = (await import(`./languages/${baseLangCode}.js`)).default; * Update the specified language file
const files = fs.readdirSync("./languages"); * @param {string} langCode Language code to update
console.log("Files:", files); * @param {string} baseLang Second language to copy keys from
*/
for (const file of files) { async function updateLanguage(langCode, baseLangCode) {
if (!file.endsWith(".js")) { const en = (await import("./languages/en.js")).default;
console.log("Skipping " + file); const baseLang = (await import(`./languages/${baseLangCode}.js`)).default;
continue;
}
let file = langCode + ".js";
console.log("Processing " + file); console.log("Processing " + file);
const lang = await import("./languages/" + file); const lang = await import("./languages/" + file);
@ -82,5 +77,20 @@ for (const file of files) {
fs.writeFileSync(`../../src/languages/${file}`, code); fs.writeFileSync(`../../src/languages/${file}`, code);
} }
fs.rmdirSync("./languages", { recursive: true }); // Get command line arguments
const baseLangCode = process.env.npm_config_baselang || "en";
const langCode = process.env.npm_config_language;
// We need the file to edit
if (langCode == null) {
throw new Error("Argument --language=<code> must be provided");
}
console.log("Base Lang: " + baseLangCode);
console.log("Updating: " + langCode);
copyFiles(langCode, baseLangCode);
await updateLanguage(langCode, baseLangCode);
rmSync("./languages", { recursive: true });
console.log("Done. Fixing formatting by ESLint..."); console.log("Done. Fixing formatting by ESLint...");

View File

@ -1,14 +1,12 @@
const pkg = require("../package.json"); const pkg = require("../package.json");
const fs = require("fs"); const fs = require("fs");
const child_process = require("child_process"); const childProcess = require("child_process");
const util = require("../src/util"); const util = require("../src/util");
util.polyfill(); util.polyfill();
const oldVersion = pkg.version; const newVersion = process.env.VERSION;
const newVersion = process.argv[2];
console.log("Old Version: " + oldVersion);
console.log("New Version: " + newVersion); console.log("New Version: " + newVersion);
if (! newVersion) { if (! newVersion) {
@ -22,25 +20,29 @@ if (! exists) {
// Process package.json // Process package.json
pkg.version = newVersion; pkg.version = newVersion;
pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion);
pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion); // Replace the version: https://regex101.com/r/hmj2Bc/1
pkg.scripts["build-docker-alpine"] = pkg.scripts["build-docker-alpine"].replaceAll(oldVersion, newVersion); pkg.scripts.setup = pkg.scripts.setup.replace(/(git checkout )([^\s]+)/, `$1${newVersion}`);
pkg.scripts["build-docker-debian"] = pkg.scripts["build-docker-debian"].replaceAll(oldVersion, newVersion);
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
// Also update package-lock.json
childProcess.spawnSync("npm", [ "install" ]);
commit(newVersion); commit(newVersion);
tag(newVersion); tag(newVersion);
updateWiki(oldVersion, newVersion);
} else { } else {
console.log("version exists"); console.log("version exists");
} }
/**
* Commit updated files
* @param {string} version Version to update to
*/
function commit(version) { function commit(version) {
let msg = "update to " + version; let msg = "Update to " + version;
let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]); let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]);
let stdout = res.stdout.toString().trim(); let stdout = res.stdout.toString().trim();
console.log(stdout); console.log(stdout);
@ -49,52 +51,26 @@ function commit(version) {
} }
} }
/**
* Create a tag with the specified version
* @param {string} version Tag to create
*/
function tag(version) { function tag(version) {
let res = child_process.spawnSync("git", ["tag", version]); let res = childProcess.spawnSync("git", [ "tag", version ]);
console.log(res.stdout.toString().trim()); console.log(res.stdout.toString().trim());
} }
/**
* Check if a tag exists for the specified version
* @param {string} version Version to check
* @returns {boolean} Does the tag already exist
*/
function tagExists(version) { function tagExists(version) {
if (! version) { if (! version) {
throw new Error("invalid version"); throw new Error("invalid version");
} }
let res = child_process.spawnSync("git", ["tag", "-l", version]); let res = childProcess.spawnSync("git", [ "tag", "-l", version ]);
return res.stdout.toString().trim() === version; return res.stdout.toString().trim() === version;
} }
function updateWiki(oldVersion, newVersion) {
const wikiDir = "./tmp/wiki";
const howToUpdateFilename = "./tmp/wiki/🆙-How-to-Update.md";
safeDelete(wikiDir);
child_process.spawnSync("git", ["clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir]);
let content = fs.readFileSync(howToUpdateFilename).toString();
content = content.replaceAll(`git checkout ${oldVersion}`, `git checkout ${newVersion}`);
fs.writeFileSync(howToUpdateFilename, content);
child_process.spawnSync("git", ["add", "-A"], {
cwd: wikiDir,
});
child_process.spawnSync("git", ["commit", "-m", `Update to ${newVersion} from ${oldVersion}`], {
cwd: wikiDir,
});
console.log("Pushing to Github");
child_process.spawnSync("git", ["push"], {
cwd: wikiDir,
});
safeDelete(wikiDir);
}
function safeDelete(dir) {
if (fs.existsSync(dir)) {
fs.rmdirSync(dir, {
recursive: true,
});
}
}

View File

@ -0,0 +1,56 @@
const childProcess = require("child_process");
const fs = require("fs");
const newVersion = process.env.VERSION;
if (!newVersion) {
console.log("Missing version");
process.exit(1);
}
updateWiki(newVersion);
/**
* Update the wiki with new version number
* @param {string} newVersion Version to update to
*/
function updateWiki(newVersion) {
const wikiDir = "./tmp/wiki";
const howToUpdateFilename = "./tmp/wiki/🆙-How-to-Update.md";
safeDelete(wikiDir);
childProcess.spawnSync("git", [ "clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir ]);
let content = fs.readFileSync(howToUpdateFilename).toString();
// Replace the version: https://regex101.com/r/hmj2Bc/1
content = content.replace(/(git checkout )([^\s]+)/, `$1${newVersion}`);
fs.writeFileSync(howToUpdateFilename, content);
childProcess.spawnSync("git", [ "add", "-A" ], {
cwd: wikiDir,
});
childProcess.spawnSync("git", [ "commit", "-m", `Update to ${newVersion}` ], {
cwd: wikiDir,
});
console.log("Pushing to Github");
childProcess.spawnSync("git", [ "push" ], {
cwd: wikiDir,
});
safeDelete(wikiDir);
}
/**
* Check if a directory exists and then delete it
* @param {string} dir Directory to delete
*/
function safeDelete(dir) {
if (fs.existsSync(dir)) {
fs.rm(dir, {
recursive: true,
});
}
}

View File

@ -159,7 +159,7 @@ fi
check=$(pm2 --version) check=$(pm2 --version)
if [ "$check" == "" ]; then if [ "$check" == "" ]; then
"echo" "-e" "Installing PM2" "echo" "-e" "Installing PM2"
npm install pm2 -g npm install pm2 -g && pm2 install pm2-logrotate
pm2 startup pm2 startup
fi fi
mkdir -p $installPath mkdir -p $installPath

22386
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "1.12.0", "version": "1.19.6",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
@ -10,35 +10,37 @@
"node": "14.* || >=16.*" "node": "14.* || >=16.*"
}, },
"scripts": { "scripts": {
"install-legacy": "npm install --legacy-peer-deps", "install-legacy": "npm install",
"update-legacy": "npm update --legacy-peer-deps", "update-legacy": "npm update",
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
"lint-fix:js": "eslint --ext \".js,.vue\" --fix --ignore-path .gitignore .",
"lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore",
"lint-fix:style": "stylelint \"**/*.{vue,css,scss}\" --fix --ignore-path .gitignore",
"lint": "npm run lint:js && npm run lint:style", "lint": "npm run lint:js && npm run lint:style",
"dev": "vite --host --config ./config/vite.config.js", "dev": "concurrently -k -r \"wait-on tcp:3000 && npm run start-server-dev \" \"npm run start-frontend-dev\"",
"start-frontend-dev": "cross-env NODE_ENV=development vite --host --config ./config/vite.config.js",
"start": "npm run start-server", "start": "npm run start-server",
"start-server": "node server/server.js", "start-server": "node server/server.js",
"start-server-dev": "cross-env NODE_ENV=development node server/server.js", "start-server-dev": "cross-env NODE_ENV=development node server/server.js",
"build": "vite build --config ./config/vite.config.js", "build": "vite build --config ./config/vite.config.js",
"test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --test", "test": "node test/prepare-test-server.js && npm run jest-backend",
"test-with-build": "npm run build && npm test", "test-with-build": "npm run build && npm test",
"jest": "node test/prepare-jest.js && npm run jest-frontend && npm run jest-backend", "jest-backend": "cross-env TEST_BACKEND=1 jest --runInBand --detectOpenHandles --forceExit --config=./config/jest-backend.config.js",
"jest-frontend": "cross-env TEST_FRONTEND=1 jest --config=./config/jest-frontend.config.js",
"jest-backend": "cross-env TEST_BACKEND=1 jest --config=./config/jest-backend.config.js",
"tsc": "tsc", "tsc": "tsc",
"vite-preview-dist": "vite preview --host --config ./config/vite.config.js", "vite-preview-dist": "vite preview --host --config ./config/vite.config.js",
"build-docker": "npm run build && npm run build-docker-debian && npm run build-docker-alpine", "build-docker": "npm run build && npm run build-docker-debian && npm run build-docker-alpine",
"build-docker-alpine-base": "docker buildx build -f docker/alpine-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-alpine . --push", "build-docker-alpine-base": "docker buildx build -f docker/alpine-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-alpine . --push",
"build-docker-debian-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-debian . --push", "build-docker-debian-base": "docker buildx build -f docker/debian-base.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:base-debian . --push",
"build-docker-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:alpine -t louislam/uptime-kuma:1-alpine -t louislam/uptime-kuma:1.12.0-alpine --target release . --push", "build-docker-builder-go": "docker buildx build -f docker/builder-go.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:builder-go . --push",
"build-docker-debian": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.12.0 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.12.0-debian --target release . --push", "build-docker-alpine": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:alpine -t louislam/uptime-kuma:1-alpine -t louislam/uptime-kuma:$VERSION-alpine --target release . --push",
"build-docker-debian": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:$VERSION-debian --target release . --push",
"build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push", "build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push",
"build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push", "build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push",
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain", "build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", "upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"setup": "git checkout 1.12.0 && npm ci --production && npm run download-dist", "setup": "git checkout 1.19.6 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js", "download-dist": "node extra/download-dist.js",
"update-version": "node extra/update-version.js",
"mark-as-nightly": "node extra/mark-as-nightly.js", "mark-as-nightly": "node extra/mark-as-nightly.js",
"reset-password": "node extra/reset-password.js", "reset-password": "node extra/reset-password.js",
"remove-2fa": "node extra/remove-2fa.js", "remove-2fa": "node extra/remove-2fa.js",
@ -49,86 +51,130 @@
"test-install-script-ubuntu1604": "npm run compile-install-script && docker build --progress plain -f test/test_install_script/ubuntu1604.dockerfile .", "test-install-script-ubuntu1604": "npm run compile-install-script && docker build --progress plain -f test/test_install_script/ubuntu1604.dockerfile .",
"test-nodejs16": "docker build --progress plain -f test/ubuntu-nodejs16.dockerfile .", "test-nodejs16": "docker build --progress plain -f test/ubuntu-nodejs16.dockerfile .",
"simple-dns-server": "node extra/simple-dns-server.js", "simple-dns-server": "node extra/simple-dns-server.js",
"update-language-files-with-base-lang": "cd extra/update-language-files && node index.js %npm_config_base_lang% && eslint ../../src/languages/**.js --fix", "simple-mqtt-server": "node extra/simple-mqtt-server.js",
"update-language-files": "cd extra/update-language-files && node index.js && eslint ../../src/languages/**.js --fix", "update-language-files": "cd extra/update-language-files && node index.js && cross-env-shell eslint ../../src/languages/$npm_config_language.js --fix",
"ncu-patch": "ncu -u -t patch" "ncu-patch": "npm-check-updates -u -t patch",
"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",
"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 --config-file ./config/cypress.config.js",
"cy:run:unit": "npx cypress run --browser chrome --headless --config-file ./config/cypress.frontend.config.js",
"cypress-open": "concurrently -k -r \"node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/\" \"cypress open --config-file ./config/cypress.config.js\"",
"build-healthcheck-armv7": "cross-env GOOS=linux GOARCH=arm GOARM=7 go build -x -o ./extra/healthcheck-armv7 ./extra/healthcheck.go"
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "~1.7.3",
"@louislam/ping": "~0.4.2-mod.1",
"@louislam/sqlite3": "15.1.2",
"args-parser": "~1.3.0",
"axios": "~0.27.0",
"axios-ntlm": "1.3.0",
"badge-maker": "~3.3.1",
"bcryptjs": "~2.4.3",
"bree": "~7.1.5",
"cacheable-lookup": "~6.0.4",
"chardet": "~1.4.0",
"check-password-strength": "^2.0.5",
"cheerio": "~1.0.0-rc.12",
"chroma-js": "~2.4.2",
"command-exists": "~1.2.9",
"compare-versions": "~3.6.0",
"compression": "~1.7.4",
"dayjs": "~1.11.5",
"express": "~4.17.3",
"express-basic-auth": "~1.2.1",
"express-static-gzip": "~2.1.7",
"form-data": "~4.0.0",
"http-graceful-shutdown": "~3.1.7",
"http-proxy-agent": "~5.0.0",
"https-proxy-agent": "~5.0.1",
"iconv-lite": "~0.6.3",
"jsesc": "~3.0.2",
"jsonwebtoken": "~9.0.0",
"jwt-decode": "~3.1.2",
"limiter": "~2.1.0",
"mongodb": "~4.13.0",
"mqtt": "~4.3.7",
"mssql": "~8.1.4",
"mysql2": "~2.3.3",
"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",
"pg": "~8.8.0",
"pg-connection-string": "~2.5.0",
"prom-client": "~13.2.0",
"prometheus-api-metrics": "~3.2.1",
"protobufjs": "~7.1.1",
"redbean-node": "~0.2.0",
"redis": "~4.5.1",
"socket.io": "~4.5.3",
"socket.io-client": "~4.5.3",
"socks-proxy-agent": "6.1.1",
"tar": "~6.1.11",
"tcp-ping": "~0.1.1",
"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/fontawesome-svg-core": "~1.2.36",
"@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-regular-svg-icons": "~5.15.4",
"@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4",
"@fortawesome/vue-fontawesome": "~3.0.0-5", "@fortawesome/vue-fontawesome": "~3.0.0-5",
"@louislam/sqlite3": "~6.0.1",
"@popperjs/core": "~2.10.2", "@popperjs/core": "~2.10.2",
"args-parser": "~1.3.0", "@types/bootstrap": "~5.1.9",
"axios": "~0.26.0", "@vitejs/plugin-legacy": "~2.1.0",
"bcryptjs": "~2.4.3", "@vitejs/plugin-vue": "~3.1.0",
"@vue/compiler-sfc": "~3.2.36",
"@vuepic/vue-datepicker": "~3.4.8",
"aedes": "^0.46.3",
"babel-plugin-rewire": "~1.2.0",
"bootstrap": "5.1.3", "bootstrap": "5.1.3",
"bree": "~7.1.0", "chart.js": "~3.6.2",
"chardet": "^1.3.0",
"chart.js": "~3.6.0",
"chartjs-adapter-dayjs": "~1.0.0", "chartjs-adapter-dayjs": "~1.0.0",
"check-password-strength": "^2.0.3", "concurrently": "^7.1.0",
"command-exists": "~1.2.9", "core-js": "~3.26.1",
"compare-versions": "~3.6.0", "cross-env": "~7.0.3",
"dayjs": "~1.10.7", "cypress": "^10.1.0",
"express": "~4.17.1", "delay": "^5.0.0",
"express-basic-auth": "~1.2.0", "dns2": "~2.0.1",
"form-data": "~4.0.0", "eslint": "~8.14.0",
"http-graceful-shutdown": "~3.1.5", "eslint-plugin-vue": "~8.7.1",
"iconv-lite": "^0.6.3", "favico.js": "~0.3.10",
"jsonwebtoken": "~8.5.1", "jest": "~27.2.5",
"jwt-decode": "^3.1.2", "postcss-html": "~1.5.0",
"limiter": "^2.1.0", "postcss-rtlcss": "~3.7.2",
"nodemailer": "~6.6.5", "postcss-scss": "~4.0.4",
"notp": "~2.0.3", "prismjs": "~1.29.0",
"password-hash": "~1.2.2",
"postcss-rtlcss": "~3.4.1",
"postcss-scss": "~4.0.2",
"prom-client": "~13.2.0",
"prometheus-api-metrics": "~3.2.0",
"qrcode": "~1.5.0", "qrcode": "~1.5.0",
"redbean-node": "0.1.3", "rollup-plugin-visualizer": "^5.6.0",
"socket.io": "~4.4.1", "sass": "~1.42.1",
"socket.io-client": "~4.4.1", "stylelint": "~14.7.1",
"tar": "^6.1.11", "stylelint-config-standard": "~25.0.0",
"tcp-ping": "~0.1.1", "terser": "~5.15.0",
"thirty-two": "~1.0.2",
"timezones-list": "~3.0.1", "timezones-list": "~3.0.1",
"typescript": "~4.4.4",
"v-pagination-3": "~0.1.7", "v-pagination-3": "~0.1.7",
"vite": "~3.1.0",
"vite-plugin-compression": "^0.5.1",
"vue": "next", "vue": "next",
"vue-chart-3": "3.0.9", "vue-chart-3": "3.0.9",
"vue-confirm-dialog": "~1.0.2", "vue-confirm-dialog": "~1.0.2",
"vue-contenteditable": "~3.0.4", "vue-contenteditable": "~3.0.4",
"vue-i18n": "~9.1.9", "vue-i18n": "~9.2.2",
"vue-image-crop-upload": "~3.0.3", "vue-image-crop-upload": "~3.0.3",
"vue-multiselect": "~3.0.0-alpha.2", "vue-multiselect": "~3.0.0-alpha.2",
"vue-prism-editor": "~2.0.0-alpha.2",
"vue-qrcode": "~1.0.0", "vue-qrcode": "~1.0.0",
"vue-router": "~4.0.12", "vue-router": "~4.0.14",
"vue-toastification": "~2.0.0-rc.5", "vue-toastification": "~2.0.0-rc.5",
"vuedraggable": "~4.1.0" "vuedraggable": "~4.1.0",
}, "wait-on": "^6.0.1"
"devDependencies": {
"@actions/github": "~5.0.0",
"@babel/eslint-parser": "~7.15.8",
"@babel/preset-env": "^7.15.8",
"@types/bootstrap": "~5.1.6",
"@vitejs/plugin-legacy": "~1.6.3",
"@vitejs/plugin-vue": "~1.9.4",
"@vue/compiler-sfc": "~3.2.22",
"babel-plugin-rewire": "~1.2.0",
"core-js": "~3.18.3",
"cross-env": "~7.0.3",
"dns2": "~2.0.1",
"eslint": "~7.32.0",
"eslint-plugin-vue": "~7.18.0",
"jest": "~27.2.5",
"jest-puppeteer": "~6.0.0",
"puppeteer": "~13.1.3",
"sass": "~1.42.1",
"stylelint": "~14.2.0",
"stylelint-config-standard": "~24.0.0",
"typescript": "~4.4.4",
"vite": "~2.6.14"
} }
} }

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

@ -1,8 +1,12 @@
const { checkLogin } = require("./util-server");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
class TwoFA { class TwoFA {
/**
* Disable 2FA for specified user
* @param {number} userID ID of user to disable
* @returns {Promise<void>}
*/
static async disable2FA(userID) { static async disable2FA(userID) {
return await R.exec("UPDATE `user` SET twofa_status = 0 WHERE id = ? ", [ return await R.exec("UPDATE `user` SET twofa_status = 0 WHERE id = ? ", [
userID, userID,

View File

@ -2,16 +2,19 @@ const basicAuth = require("express-basic-auth");
const passwordHash = require("./password-hash"); const passwordHash = require("./password-hash");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { setting } = require("./util-server"); const { setting } = require("./util-server");
const { debug } = require("../src/util");
const { loginRateLimiter } = require("./rate-limiter"); const { loginRateLimiter } = require("./rate-limiter");
/** /**
* * Login to web app
* @param username : string * @param {string} username
* @param password : string * @param {string} password
* @returns {Promise<Bean|null>} * @returns {Promise<(Bean|null)>}
*/ */
exports.login = async function (username, password) { exports.login = async function (username, password) {
if (typeof username !== "string" || typeof password !== "string") {
return null;
}
let user = await R.findOne("user", " username = ? AND active = 1 ", [ let user = await R.findOne("user", " username = ? AND active = 1 ", [
username, username,
]); ]);
@ -30,32 +33,54 @@ exports.login = async function (username, password) {
return null; return null;
}; };
function myAuthorizer(username, password, callback) { /**
setting("disableAuth").then((result) => { * Callback for myAuthorizer
if (result) { * @callback myAuthorizerCB
callback(null, true); * @param {any} err Any error encountered
} else { * @param {boolean} authorized Is the client authorized?
// Login Rate Limit */
loginRateLimiter.pass(null, 0).then((pass) => {
if (pass) {
exports.login(username, password).then((user) => {
callback(null, user != null);
if (user == null) { /**
loginRateLimiter.removeTokens(1); * Custom authorizer for express-basic-auth
} * @param {string} username
}); * @param {string} password
} else { * @param {myAuthorizerCB} callback
callback(null, false); */
function myAuthorizer(username, password, callback) {
// Login Rate Limit
loginRateLimiter.pass(null, 0).then((pass) => {
if (pass) {
exports.login(username, password).then((user) => {
callback(null, user != null);
if (user == null) {
loginRateLimiter.removeTokens(1);
} }
}); });
} else {
callback(null, false);
} }
}); });
} }
exports.basicAuth = basicAuth({ /**
authorizer: myAuthorizer, * Use basic auth if auth is not disabled
authorizeAsync: true, * @param {express.Request} req Express request object
challenge: true, * @param {express.Response} res Express response object
}); * @param {express.NextFunction} next
*/
exports.basicAuth = async function (req, res, next) {
const middleware = basicAuth({
authorizer: myAuthorizer,
authorizeAsync: true,
challenge: true,
});
const disabledAuth = await setting("disableAuth");
if (!disabledAuth) {
middleware(req, res, next);
} else {
next();
}
};

View File

@ -0,0 +1,86 @@
const https = require("https");
const http = require("http");
const CacheableLookup = require("cacheable-lookup");
const { Settings } = require("./settings");
const { log } = require("../src/util");
class CacheableDnsHttpAgent {
static cacheable = new CacheableLookup();
static httpAgentList = {};
static httpsAgentList = {};
static enable = false;
/**
* Register/Disable cacheable to global agents
*/
static async update() {
log.debug("CacheableDnsHttpAgent", "update");
let isEnable = await Settings.get("dnsCache");
if (isEnable !== this.enable) {
log.debug("CacheableDnsHttpAgent", "value changed");
if (isEnable) {
log.debug("CacheableDnsHttpAgent", "enable");
this.cacheable.install(http.globalAgent);
this.cacheable.install(https.globalAgent);
} else {
log.debug("CacheableDnsHttpAgent", "disable");
this.cacheable.uninstall(http.globalAgent);
this.cacheable.uninstall(https.globalAgent);
}
}
this.enable = isEnable;
}
/**
* Attach cacheable to HTTP agent
* @param {http.Agent} agent Agent to install
*/
static install(agent) {
this.cacheable.install(agent);
}
/**
* @var {https.AgentOptions} agentOptions
* @return {https.Agent}
*/
static getHttpsAgent(agentOptions) {
if (!this.enable) {
return new https.Agent(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) {
if (!this.enable) {
return new http.Agent(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

@ -1,11 +1,13 @@
const { setSetting } = require("./util-server"); const { setSetting, setting } = require("./util-server");
const axios = require("axios"); const axios = require("axios");
const compareVersions = require("compare-versions");
exports.version = require("../package.json").version; exports.version = require("../package.json").version;
exports.latestVersion = null; exports.latestVersion = null;
let interval; let interval;
/** Start 48 hour check interval */
exports.startInterval = () => { exports.startInterval = () => {
let check = async () => { let check = async () => {
try { try {
@ -16,6 +18,19 @@ exports.startInterval = () => {
res.data.slow = "1000.0.0"; res.data.slow = "1000.0.0";
} }
if (await setting("checkUpdate") === false) {
return;
}
let checkBeta = await setting("checkBeta");
if (checkBeta && res.data.beta) {
if (compareVersions.compare(res.data.beta, res.data.slow, ">")) {
exports.latestVersion = res.data.beta;
return;
}
}
if (res.data.slow) { if (res.data.slow) {
exports.latestVersion = res.data.slow; exports.latestVersion = res.data.slow;
} }
@ -28,6 +43,11 @@ exports.startInterval = () => {
interval = setInterval(check, 3600 * 1000 * 48); interval = setInterval(check, 3600 * 1000 * 48);
}; };
/**
* Enable the check update feature
* @param {boolean} value Should the check update feature be enabled?
* @returns {Promise<void>}
*/
exports.enableCheckUpdate = async (value) => { exports.enableCheckUpdate = async (value) => {
await setSetting("checkUpdate", value); await setSetting("checkUpdate", value);

View File

@ -3,10 +3,17 @@
*/ */
const { TimeLogger } = require("../src/util"); const { TimeLogger } = require("../src/util");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { io } = require("./server"); const { UptimeKumaServer } = require("./uptime-kuma-server");
const server = UptimeKumaServer.getInstance();
const io = server.io;
const { setting } = require("./util-server"); const { setting } = require("./util-server");
const checkVersion = require("./check-version"); const checkVersion = require("./check-version");
/**
* Send list of notification providers to client
* @param {Socket} socket Socket.io socket instance
* @returns {Promise<Bean[]>}
*/
async function sendNotificationList(socket) { async function sendNotificationList(socket) {
const timeLogger = new TimeLogger(); const timeLogger = new TimeLogger();
@ -16,7 +23,10 @@ async function sendNotificationList(socket) {
]); ]);
for (let bean of list) { for (let bean of list) {
result.push(bean.export()); let notificationObject = bean.export();
notificationObject.isDefault = (notificationObject.isDefault === 1);
notificationObject.active = (notificationObject.active === 1);
result.push(notificationObject);
} }
io.to(socket.userID).emit("notificationList", result); io.to(socket.userID).emit("notificationList", result);
@ -28,8 +38,11 @@ async function sendNotificationList(socket) {
/** /**
* Send Heartbeat History list to socket * Send Heartbeat History list to socket
* @param toUser True = send to all browsers with the same user id, False = send to the current browser only * @param {Socket} socket Socket.io instance
* @param overwrite Overwrite client-side's heartbeat list * @param {number} monitorID ID of monitor to send heartbeat history
* @param {boolean} [toUser=false] True = send to all browsers with the same user id, False = send to the current browser only
* @param {boolean} [overwrite=false] Overwrite client-side's heartbeat list
* @returns {Promise<void>}
*/ */
async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite = false) {
const timeLogger = new TimeLogger(); const timeLogger = new TimeLogger();
@ -55,11 +68,12 @@ async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite =
} }
/** /**
* Important Heart beat list (aka event list) * Important Heart beat list (aka event list)
* @param socket * @param {Socket} socket Socket.io instance
* @param monitorID * @param {number} monitorID ID of monitor to send heartbeat history
* @param toUser True = send to all browsers with the same user id, False = send to the current browser only * @param {boolean} [toUser=false] True = send to all browsers with the same user id, False = send to the current browser only
* @param overwrite Overwrite client-side's heartbeat list * @param {boolean} [overwrite=false] Overwrite client-side's heartbeat list
* @returns {Promise<void>}
*/ */
async function sendImportantHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { async function sendImportantHeartbeatList(socket, monitorID, toUser = false, overwrite = false) {
const timeLogger = new TimeLogger(); const timeLogger = new TimeLogger();
@ -83,18 +97,66 @@ async function sendImportantHeartbeatList(socket, monitorID, toUser = false, ove
} }
/**
* Emit proxy list to client
* @param {Socket} socket Socket.io socket instance
* @return {Promise<Bean[]>}
*/
async function sendProxyList(socket) {
const timeLogger = new TimeLogger();
const list = await R.find("proxy", " user_id = ? ", [ socket.userID ]);
io.to(socket.userID).emit("proxyList", list.map(bean => bean.export()));
timeLogger.print("Send Proxy List");
return list;
}
/**
* Emits the version information to the client.
* @param {Socket} socket Socket.io socket instance
* @returns {Promise<void>}
*/
async function sendInfo(socket) { async function sendInfo(socket) {
socket.emit("info", { socket.emit("info", {
version: checkVersion.version, version: checkVersion.version,
latestVersion: checkVersion.latestVersion, latestVersion: checkVersion.latestVersion,
primaryBaseURL: await setting("primaryBaseURL") primaryBaseURL: await setting("primaryBaseURL"),
serverTimezone: await server.getTimezone(),
serverTimezoneOffset: server.getTimezoneOffset(),
}); });
} }
/**
* 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 = { module.exports = {
sendNotificationList, sendNotificationList,
sendImportantHeartbeatList, sendImportantHeartbeatList,
sendHeartbeatList, sendHeartbeatList,
sendInfo sendProxyList,
sendInfo,
sendDockerHostList
}; };

View File

@ -1,7 +1,20 @@
const args = require("args-parser")(process.argv); const args = require("args-parser")(process.argv);
const demoMode = args["demo"] || false; const demoMode = args["demo"] || false;
const badgeConstants = {
naColor: "#999",
defaultUpColor: "#66c20a",
defaultDownColor: "#c2290a",
defaultPingColor: "blue", // as defined by badge-maker / shields.io
defaultStyle: "flat",
defaultPingValueSuffix: "ms",
defaultPingLabelSuffix: "h",
defaultUptimeValueSuffix: "%",
defaultUptimeLabelSuffix: "h",
};
module.exports = { module.exports = {
args, args,
demoMode demoMode,
badgeConstants,
}; };

View File

@ -1,7 +1,7 @@
const fs = require("fs"); const fs = require("fs");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { setSetting, setting } = require("./util-server"); const { setSetting, setting } = require("./util-server");
const { debug, sleep } = require("../src/util"); const { log, sleep } = require("../src/util");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const knex = require("knex"); const knex = require("knex");
@ -53,7 +53,20 @@ class Database {
"patch-2fa-invalidate-used-token.sql": true, "patch-2fa-invalidate-used-token.sql": true,
"patch-notification_sent_history.sql": true, "patch-notification_sent_history.sql": true,
"patch-monitor-basic-auth.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-grpc-monitor.sql": true,
"patch-add-radius-monitor.sql": true,
"patch-monitor-add-resend-interval.sql": true,
"patch-maintenance-table2.sql": true,
};
/** /**
* The final version should be 10 after merged tag feature * The final version should be 10 after merged tag feature
@ -63,6 +76,10 @@ class Database {
static noReject = true; static noReject = true;
/**
* Initialize the database
* @param {Object} args Arguments to initialize DB with
*/
static init(args) { static init(args) {
// Data Directory (must be end with "/") // Data Directory (must be end with "/")
Database.dataDir = process.env.DATA_DIR || args["data-dir"] || "./data/"; Database.dataDir = process.env.DATA_DIR || args["data-dir"] || "./data/";
@ -77,10 +94,19 @@ class Database {
fs.mkdirSync(Database.uploadDir, { recursive: true }); fs.mkdirSync(Database.uploadDir, { recursive: true });
} }
console.log(`Data Dir: ${Database.dataDir}`); log.info("db", `Data Dir: ${Database.dataDir}`);
} }
static async connect(testMode = false) { /**
* Connect to the database
* @param {boolean} [testMode=false] Should the connection be
* started in test mode?
* @param {boolean} [autoloadModels=true] Should models be
* automatically loaded?
* @param {boolean} [noLog=false] Should logs not be output?
* @returns {Promise<void>}
*/
static async connect(testMode = false, autoloadModels = true, noLog = false) {
const acquireConnectionTimeout = 120 * 1000; const acquireConnectionTimeout = 120 * 1000;
const Dialect = require("knex/lib/dialects/sqlite3/index.js"); const Dialect = require("knex/lib/dialects/sqlite3/index.js");
@ -110,7 +136,10 @@ class Database {
// Auto map the model to a bean object // Auto map the model to a bean object
R.freeze(true); R.freeze(true);
await R.autoloadModels("./server/model");
if (autoloadModels) {
await R.autoloadModels("./server/model");
}
await R.exec("PRAGMA foreign_keys = ON"); await R.exec("PRAGMA foreign_keys = ON");
if (testMode) { if (testMode) {
@ -123,12 +152,20 @@ class Database {
await R.exec("PRAGMA cache_size = -12000"); await R.exec("PRAGMA cache_size = -12000");
await R.exec("PRAGMA auto_vacuum = FULL"); await R.exec("PRAGMA auto_vacuum = FULL");
console.log("SQLite config:"); // This ensures that an operating system crash or power failure will not corrupt the database.
console.log(await R.getAll("PRAGMA journal_mode")); // FULL synchronous is very safe, but it is also slower.
console.log(await R.getAll("PRAGMA cache_size")); // Read more: https://sqlite.org/pragma.html#pragma_synchronous
console.log("SQLite Version: " + await R.getCell("SELECT sqlite_version()")); await R.exec("PRAGMA synchronous = FULL");
if (!noLog) {
log.info("db", "SQLite config:");
log.info("db", await R.getAll("PRAGMA journal_mode"));
log.info("db", await R.getAll("PRAGMA cache_size"));
log.info("db", "SQLite Version: " + await R.getCell("SELECT sqlite_version()"));
}
} }
/** Patch the database */
static async patch() { static async patch() {
let version = parseInt(await setting("database_version")); let version = parseInt(await setting("database_version"));
@ -136,33 +173,39 @@ class Database {
version = 0; version = 0;
} }
console.info("Your database version: " + version); log.info("db", "Your database version: " + version);
console.info("Latest database version: " + this.latestVersion); log.info("db", "Latest database version: " + this.latestVersion);
if (version === this.latestVersion) { if (version === this.latestVersion) {
console.info("Database patch not needed"); log.info("db", "Database patch not needed");
} else if (version > this.latestVersion) { } else if (version > this.latestVersion) {
console.info("Warning: Database version is newer than expected"); log.info("db", "Warning: Database version is newer than expected");
} else { } else {
console.info("Database patch is needed"); 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 catch anything here, if gone wrong, restore the backup
try { try {
for (let i = version + 1; i <= this.latestVersion; i++) { for (let i = version + 1; i <= this.latestVersion; i++) {
const sqlFile = `./db/patch${i}.sql`; const sqlFile = `./db/patch${i}.sql`;
console.info(`Patching ${sqlFile}`); log.info("db", `Patching ${sqlFile}`);
await Database.importSQLFile(sqlFile); await Database.importSQLFile(sqlFile);
console.info(`Patched ${sqlFile}`); log.info("db", `Patched ${sqlFile}`);
await setSetting("database_version", i); await setSetting("database_version", i);
} }
} catch (ex) { } catch (ex) {
await Database.close(); await Database.close();
console.error(ex); log.error("db", ex);
console.error("Start Uptime-Kuma failed due to issue patching the database"); log.error("db", "Start Uptime-Kuma failed due to issue patching the database");
console.error("Please submit a bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); log.error("db", "Please submit a bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
this.restore(); this.restore();
process.exit(1); process.exit(1);
@ -170,22 +213,25 @@ class Database {
} }
await this.patch2(); await this.patch2();
await this.migrateNewStatusPage();
} }
/** /**
* Patch DB using new process
* Call it from patch() only * Call it from patch() only
* @private
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async patch2() { static async patch2() {
console.log("Database Patch 2.0 Process"); log.info("db", "Database Patch 2.0 Process");
let databasePatchedFiles = await setting("databasePatchedFiles"); let databasePatchedFiles = await setting("databasePatchedFiles");
if (! databasePatchedFiles) { if (! databasePatchedFiles) {
databasePatchedFiles = {}; databasePatchedFiles = {};
} }
debug("Patched files:"); log.debug("db", "Patched files:");
debug(databasePatchedFiles); log.debug("db", databasePatchedFiles);
try { try {
for (let sqlFilename in this.patchList) { for (let sqlFilename in this.patchList) {
@ -193,15 +239,15 @@ class Database {
} }
if (this.patched) { if (this.patched) {
console.log("Database Patched Successfully"); log.info("db", "Database Patched Successfully");
} }
} catch (ex) { } catch (ex) {
await Database.close(); await Database.close();
console.error(ex); log.error("db", ex);
console.error("Start Uptime-Kuma failed due to issue patching the database"); log.error("db", "Start Uptime-Kuma failed due to issue patching the database");
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); log.error("db", "Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
this.restore(); this.restore();
@ -212,24 +258,95 @@ class Database {
} }
/** /**
* Migrate status page value in setting to "status_page" table
* @returns {Promise<void>}
*/
static async migrateNewStatusPage() {
// Fix 1.13.0 empty slug bug
await R.exec("UPDATE status_page SET slug = 'empty-slug-recover' WHERE TRIM(slug) = ''");
let title = await setting("title");
if (title) {
console.log("Migrating Status Page");
let statusPageCheck = await R.findOne("status_page", " slug = 'default' ");
if (statusPageCheck !== null) {
console.log("Migrating Status Page - Skip, default slug record is already existing");
return;
}
let statusPage = R.dispense("status_page");
statusPage.slug = "default";
statusPage.title = title;
statusPage.description = await setting("description");
statusPage.icon = await setting("icon");
statusPage.theme = await setting("statusPageTheme");
statusPage.published = !!await setting("statusPagePublished");
statusPage.search_engine_index = !!await setting("searchEngineIndex");
statusPage.show_tags = !!await setting("statusPageTags");
statusPage.password = null;
if (!statusPage.title) {
statusPage.title = "My Status Page";
}
if (!statusPage.icon) {
statusPage.icon = "";
}
if (!statusPage.theme) {
statusPage.theme = "light";
}
let id = await R.store(statusPage);
await R.exec("UPDATE incident SET status_page_id = ? WHERE status_page_id IS NULL", [
id
]);
await R.exec("UPDATE [group] SET status_page_id = ? WHERE status_page_id IS NULL", [
id
]);
await R.exec("DELETE FROM setting WHERE type = 'statusPage'");
// Migrate Entry Page if it is status page
let entryPage = await setting("entryPage");
if (entryPage === "statusPage") {
await setSetting("entryPage", "statusPage-default", "general");
}
console.log("Migrating Status Page - Done");
}
}
/**
* Patch database using new patching process
* Used it patch2() only * Used it patch2() only
* @private
* @param sqlFilename * @param sqlFilename
* @param databasePatchedFiles * @param databasePatchedFiles
* @returns {Promise<void>}
*/ */
static async patch2Recursion(sqlFilename, databasePatchedFiles) { static async patch2Recursion(sqlFilename, databasePatchedFiles) {
let value = this.patchList[sqlFilename]; let value = this.patchList[sqlFilename];
if (! value) { if (! value) {
console.log(sqlFilename + " skip"); log.info("db", sqlFilename + " skip");
return; return;
} }
// Check if patched // Check if patched
if (! databasePatchedFiles[sqlFilename]) { if (! databasePatchedFiles[sqlFilename]) {
console.log(sqlFilename + " is not patched"); log.info("db", sqlFilename + " is not patched");
if (value.parents) { if (value.parents) {
console.log(sqlFilename + " need parents"); log.info("db", sqlFilename + " need parents");
for (let parentSQLFilename of value.parents) { for (let parentSQLFilename of value.parents) {
await this.patch2Recursion(parentSQLFilename, databasePatchedFiles); await this.patch2Recursion(parentSQLFilename, databasePatchedFiles);
} }
@ -237,24 +354,24 @@ class Database {
this.backup(dayjs().format("YYYYMMDDHHmmss")); this.backup(dayjs().format("YYYYMMDDHHmmss"));
console.log(sqlFilename + " is patching"); log.info("db", sqlFilename + " is patching");
this.patched = true; this.patched = true;
await this.importSQLFile("./db/" + sqlFilename); await this.importSQLFile("./db/" + sqlFilename);
databasePatchedFiles[sqlFilename] = true; databasePatchedFiles[sqlFilename] = true;
console.log(sqlFilename + " was patched successfully"); log.info("db", sqlFilename + " was patched successfully");
} else { } else {
debug(sqlFilename + " is already patched, skip"); log.debug("db", sqlFilename + " is already patched, skip");
} }
} }
/** /**
* Sadly, multi sql statements is not supported by many sqlite libraries, I have to implement it myself * Load an SQL file and execute it
* @param filename * @param filename Filename of SQL file to import
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async importSQLFile(filename) { static async importSQLFile(filename) {
// Sadly, multi sql statements is not supported by many sqlite libraries, I have to implement it myself
await R.getCell("SELECT 1"); await R.getCell("SELECT 1");
let text = fs.readFileSync(filename).toString(); let text = fs.readFileSync(filename).toString();
@ -282,6 +399,10 @@ class Database {
} }
} }
/**
* Aquire a direct connection to database
* @returns {any}
*/
static getBetterSQLite3Database() { static getBetterSQLite3Database() {
return R.knex.client.acquireConnection(); return R.knex.client.acquireConnection();
} }
@ -296,7 +417,7 @@ class Database {
}; };
process.addListener("unhandledRejection", listener); process.addListener("unhandledRejection", listener);
console.log("Closing the database"); log.info("db", "Closing the database");
while (true) { while (true) {
Database.noReject = true; Database.noReject = true;
@ -306,10 +427,10 @@ class Database {
if (Database.noReject) { if (Database.noReject) {
break; break;
} else { } else {
console.log("Waiting to close the database"); log.info("db", "Waiting to close the database");
} }
} }
console.log("SQLite closed"); log.info("db", "SQLite closed");
process.removeListener("unhandledRejection", listener); process.removeListener("unhandledRejection", listener);
} }
@ -317,11 +438,11 @@ class Database {
/** /**
* One backup one time in this process. * One backup one time in this process.
* Reset this.backupPath if you want to backup again * Reset this.backupPath if you want to backup again
* @param version * @param {string} version Version code of backup
*/ */
static backup(version) { static backup(version) {
if (! this.backupPath) { if (! this.backupPath) {
console.info("Backing up the database"); log.info("db", "Backing up the database");
this.backupPath = this.dataDir + "kuma.db.bak" + version; this.backupPath = this.dataDir + "kuma.db.bak" + version;
fs.copyFileSync(Database.path, this.backupPath); fs.copyFileSync(Database.path, this.backupPath);
@ -336,15 +457,30 @@ class Database {
this.backupWalPath = walPath + ".bak" + version; this.backupWalPath = walPath + ".bak" + version;
fs.copyFileSync(walPath, this.backupWalPath); 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);
}
}
} }
} }
/** /** Restore from most recent backup */
*
*/
static restore() { static restore() {
if (this.backupPath) { if (this.backupPath) {
console.error("Patching the database failed!!! Restoring the backup"); log.error("db", "Patching the database failed!!! Restoring the backup");
const shmPath = Database.path + "-shm"; const shmPath = Database.path + "-shm";
const walPath = Database.path + "-wal"; const walPath = Database.path + "-wal";
@ -363,7 +499,7 @@ class Database {
fs.unlinkSync(walPath); fs.unlinkSync(walPath);
} }
} catch (e) { } catch (e) {
console.log("Restore failed; you may need to restore the backup manually"); log.error("db", "Restore failed; you may need to restore the backup manually");
process.exit(1); process.exit(1);
} }
@ -379,17 +515,22 @@ class Database {
} }
} else { } else {
console.log("Nothing to restore"); log.info("db", "Nothing to restore");
} }
} }
/** Get the size of the database */
static getSize() { static getSize() {
debug("Database.getSize()"); log.debug("db", "Database.getSize()");
let stats = fs.statSync(Database.path); let stats = fs.statSync(Database.path);
debug(stats); log.debug("db", stats);
return stats.size; return stats.size;
} }
/**
* Shrink the database
* @returns {Promise<void>}
*/
static async shrink() { static async shrink() {
await R.exec("VACUUM"); await R.exec("VACUUM");
} }

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

@ -3,12 +3,21 @@
Modified with 0 dependencies Modified with 0 dependencies
*/ */
let fs = require("fs"); let fs = require("fs");
const { log } = require("../src/util");
let ImageDataURI = (() => { let ImageDataURI = (() => {
/**
* Decode the data:image/ URI
* @param {string} dataURI data:image/ URI to decode
* @returns {?Object} An object with properties "imageType" and "dataBase64".
* The former is the image type, e.g., "png", and the latter is a base64
* encoded string of the image's binary data. If it fails to parse, returns
* null instead of an object.
*/
function decode(dataURI) { function decode(dataURI) {
if (!/data:image\//.test(dataURI)) { if (!/data:image\//.test(dataURI)) {
console.log("ImageDataURI :: Error :: It seems that it is not an Image Data URI. Couldn't match \"data:image/\""); log.error("image-data-uri", "It seems that it is not an Image Data URI. Couldn't match \"data:image/\"");
return null; return null;
} }
@ -20,9 +29,16 @@ let ImageDataURI = (() => {
}; };
} }
/**
* Endcode an image into data:image/ URI
* @param {(Buffer|string)} data Data to encode
* @param {string} mediaType Media type of data
* @returns {(string|null)} A string representing the base64-encoded
* version of the given Buffer object or null if an error occurred.
*/
function encode(data, mediaType) { function encode(data, mediaType) {
if (!data || !mediaType) { if (!data || !mediaType) {
console.log("ImageDataURI :: Error :: Missing some of the required params: data, mediaType "); log.error("image-data-uri", "Missing some of the required params: data, mediaType");
return null; return null;
} }
@ -33,6 +49,12 @@ let ImageDataURI = (() => {
return dataImgBase64; return dataImgBase64;
} }
/**
* Write data URI to file
* @param {string} dataURI data:image/ URI
* @param {string} [filePath] Path to write file to
* @returns {Promise<string>}
*/
function outputFile(dataURI, filePath) { function outputFile(dataURI, filePath) {
filePath = filePath || "./"; filePath = filePath || "./";
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@ -1,7 +1,8 @@
const path = require("path"); const path = require("path");
const Bree = require("bree"); const Bree = require("bree");
const { SHARE_ENV } = require("worker_threads"); const { SHARE_ENV } = require("worker_threads");
const { log } = require("../src/util");
let bree;
const jobs = [ const jobs = [
{ {
name: "clear-old-data", name: "clear-old-data",
@ -9,8 +10,13 @@ const jobs = [
}, },
]; ];
/**
* Initialize background jobs
* @param {Object} args Arguments to pass to workers
* @returns {Bree}
*/
const initBackgroundJobs = function (args) { const initBackgroundJobs = function (args) {
const bree = new Bree({ bree = new Bree({
root: path.resolve("server", "jobs"), root: path.resolve("server", "jobs"),
jobs, jobs,
worker: { worker: {
@ -18,7 +24,7 @@ const initBackgroundJobs = function (args) {
workerData: args, workerData: args,
}, },
workerMessageHandler: (message) => { workerMessageHandler: (message) => {
console.log("[Background Job]:", message); log.info("jobs", message);
} }
}); });
@ -26,6 +32,14 @@ const initBackgroundJobs = function (args) {
return bree; return bree;
}; };
module.exports = { /** Stop all background jobs if running */
initBackgroundJobs const stopBackgroundJobs = function () {
if (bree) {
bree.stop();
}
};
module.exports = {
initBackgroundJobs,
stopBackgroundJobs
}; };

View File

@ -25,15 +25,20 @@ const DEFAULT_KEEP_PERIOD = 180;
parsedPeriod = DEFAULT_KEEP_PERIOD; parsedPeriod = DEFAULT_KEEP_PERIOD;
} }
log(`Clearing Data older than ${parsedPeriod} days...`); if (parsedPeriod < 1) {
log(`Data deletion has been disabled as period is less than 1. Period is ${parsedPeriod} days.`);
} else {
try { log(`Clearing Data older than ${parsedPeriod} days...`);
await R.exec(
"DELETE FROM heartbeat WHERE time < DATETIME('now', '-' || ? || ' days') ", try {
[parsedPeriod] await R.exec(
); "DELETE FROM heartbeat WHERE time < DATETIME('now', '-' || ? || ' days') ",
} catch (e) { [ parsedPeriod ]
log(`Failed to clear old data: ${e.message}`); );
} catch (e) {
log(`Failed to clear old data: ${e.message}`);
}
} }
exit(); exit();

View File

@ -2,14 +2,24 @@ const { parentPort, workerData } = require("worker_threads");
const Database = require("../database"); const Database = require("../database");
const path = require("path"); const path = require("path");
/**
* Send message to parent process for logging
* since worker_thread does not have access to stdout, this is used
* instead of console.log()
* @param {any} any The message to log
*/
const log = function (any) { const log = function (any) {
if (parentPort) { if (parentPort) {
parentPort.postMessage(any); parentPort.postMessage(any);
} }
}; };
/**
* Exit the worker process
* @param {number} error The status code to exit
*/
const exit = function (error) { const exit = function (error) {
if (error && error != 0) { if (error && error !== 0) {
process.exit(error); process.exit(error);
} else { } else {
if (parentPort) { if (parentPort) {
@ -20,6 +30,7 @@ const exit = function (error) {
} }
}; };
/** Connects to the database */
const connectDb = async function () { const connectDb = async function () {
const dbPath = path.join( const dbPath = path.join(
process.env.DATA_DIR || workerData["data-dir"] || "./data/" process.env.DATA_DIR || workerData["data-dir"] || "./data/"

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

@ -3,12 +3,18 @@ const { R } = require("redbean-node");
class Group extends BeanModel { class Group extends BeanModel {
async toPublicJSON() { /**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @param {boolean} [showTags=false] Should the JSON include monitor tags
* @returns {Object}
*/
async toPublicJSON(showTags = false) {
let monitorBeanList = await this.getMonitorList(); let monitorBeanList = await this.getMonitorList();
let monitorList = []; let monitorList = [];
for (let bean of monitorBeanList) { for (let bean of monitorBeanList) {
monitorList.push(await bean.toPublicJSON()); monitorList.push(await bean.toPublicJSON(showTags));
} }
return { return {
@ -19,9 +25,13 @@ class Group extends BeanModel {
}; };
} }
/**
* Get all monitors
* @returns {Bean[]}
*/
async getMonitorList() { async getMonitorList() {
return R.convertToBeans("monitor", await R.getAll(` 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 WHERE monitor.id = monitor_group.monitor_id
AND group_id = ? AND group_id = ?
ORDER BY monitor_group.weight ORDER BY monitor_group.weight

View File

@ -1,8 +1,3 @@
const dayjs = require("dayjs");
const utc = require("dayjs/plugin/utc");
let timezone = require("dayjs/plugin/timezone");
dayjs.extend(utc);
dayjs.extend(timezone);
const { BeanModel } = require("redbean-node/dist/bean-model"); const { BeanModel } = require("redbean-node/dist/bean-model");
/** /**
@ -10,9 +5,15 @@ const { BeanModel } = require("redbean-node/dist/bean-model");
* 0 = DOWN * 0 = DOWN
* 1 = UP * 1 = UP
* 2 = PENDING * 2 = PENDING
* 3 = MAINTENANCE
*/ */
class Heartbeat extends BeanModel { class Heartbeat extends BeanModel {
/**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @returns {Object}
*/
toPublicJSON() { toPublicJSON() {
return { return {
status: this.status, status: this.status,
@ -22,6 +23,10 @@ class Heartbeat extends BeanModel {
}; };
} }
/**
* Return an object that ready to parse to JSON
* @returns {Object}
*/
toJSON() { toJSON() {
return { return {
monitorID: this.monitor_id, monitorID: this.monitor_id,

View File

@ -2,6 +2,11 @@ const { BeanModel } = require("redbean-node/dist/bean-model");
class Incident extends BeanModel { class Incident extends BeanModel {
/**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @returns {Object}
*/
toPublicJSON() { toPublicJSON() {
return { return {
id: this.id, id: this.id,

240
server/model/maintenance.js Normal file
View File

@ -0,0 +1,240 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
const { parseTimeObject, parseTimeFromTimeObject, utcToLocal, localToUTC, log } = require("../../src/util");
const { timeObjectToUTC, timeObjectToLocal } = require("../util-server");
const { R } = require("redbean-node");
const dayjs = require("dayjs");
class Maintenance extends BeanModel {
/**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @returns {Object}
*/
async toPublicJSON() {
let dateRange = [];
if (this.start_date) {
dateRange.push(utcToLocal(this.start_date));
if (this.end_date) {
dateRange.push(utcToLocal(this.end_date));
}
}
let timeRange = [];
let startTime = timeObjectToLocal(parseTimeObject(this.start_time));
timeRange.push(startTime);
let endTime = timeObjectToLocal(parseTimeObject(this.end_time));
timeRange.push(endTime);
let obj = {
id: this.id,
title: this.title,
description: this.description,
strategy: this.strategy,
intervalDay: this.interval_day,
active: !!this.active,
dateRange: dateRange,
timeRange: timeRange,
weekdays: (this.weekdays) ? JSON.parse(this.weekdays) : [],
daysOfMonth: (this.days_of_month) ? JSON.parse(this.days_of_month) : [],
timeslotList: [],
};
const timeslotList = await this.getTimeslotList();
for (let timeslot of timeslotList) {
obj.timeslotList.push(await timeslot.toPublicJSON());
}
if (!Array.isArray(obj.weekdays)) {
obj.weekdays = [];
}
if (!Array.isArray(obj.daysOfMonth)) {
obj.daysOfMonth = [];
}
// Maintenance Status
if (!obj.active) {
obj.status = "inactive";
} else if (obj.strategy === "manual") {
obj.status = "under-maintenance";
} else if (obj.timeslotList.length > 0) {
let currentTimestamp = dayjs().unix();
for (let timeslot of obj.timeslotList) {
if (dayjs.utc(timeslot.startDate).unix() <= currentTimestamp && dayjs.utc(timeslot.endDate).unix() >= currentTimestamp) {
log.debug("timeslot", "Timeslot ID: " + timeslot.id);
log.debug("timeslot", "currentTimestamp:" + currentTimestamp);
log.debug("timeslot", "timeslot.start_date:" + dayjs.utc(timeslot.startDate).unix());
log.debug("timeslot", "timeslot.end_date:" + dayjs.utc(timeslot.endDate).unix());
obj.status = "under-maintenance";
break;
}
}
if (!obj.status) {
obj.status = "scheduled";
}
} else if (obj.timeslotList.length === 0) {
obj.status = "ended";
} else {
obj.status = "unknown";
}
return obj;
}
/**
* Only get future or current timeslots only
* @returns {Promise<[]>}
*/
async getTimeslotList() {
return R.convertToBeans("maintenance_timeslot", await R.getAll(`
SELECT maintenance_timeslot.*
FROM maintenance_timeslot, maintenance
WHERE maintenance_timeslot.maintenance_id = maintenance.id
AND maintenance.id = ?
AND ${Maintenance.getActiveAndFutureMaintenanceSQLCondition()}
`, [
this.id
]));
}
/**
* Return an object that ready to parse to JSON
* @param {string} timezone If not specified, the timeRange will be in UTC
* @returns {Object}
*/
async toJSON(timezone = null) {
return this.toPublicJSON(timezone);
}
/**
* Get a list of weekdays that the maintenance is active for
* Monday=1, Tuesday=2 etc.
* @returns {number[]} Array of active weekdays
*/
getDayOfWeekList() {
log.debug("timeslot", "List: " + this.weekdays);
return JSON.parse(this.weekdays).sort(function (a, b) {
return a - b;
});
}
/**
* Get a list of days in month that maintenance is active for
* @returns {number[]} Array of active days in month
*/
getDayOfMonthList() {
return JSON.parse(this.days_of_month).sort(function (a, b) {
return a - b;
});
}
/**
* Get the start date and time for maintenance
* @returns {dayjs.Dayjs} Start date and time
*/
getStartDateTime() {
let startOfTheDay = dayjs.utc(this.start_date).format("HH:mm");
log.debug("timeslot", "startOfTheDay: " + startOfTheDay);
// Start Time
let startTimeSecond = dayjs.utc(this.start_time, "HH:mm").diff(dayjs.utc(startOfTheDay, "HH:mm"), "second");
log.debug("timeslot", "startTime: " + startTimeSecond);
// Bake StartDate + StartTime = Start DateTime
return dayjs.utc(this.start_date).add(startTimeSecond, "second");
}
/**
* Get the duraction of maintenance in seconds
* @returns {number} Duration of maintenance
*/
getDuration() {
let duration = dayjs.utc(this.end_time, "HH:mm").diff(dayjs.utc(this.start_time, "HH:mm"), "second");
// Add 24hours if it is across day
if (duration < 0) {
duration += 24 * 3600;
}
return duration;
}
/**
* Convert data from socket to bean
* @param {Bean} bean Bean to fill in
* @param {Object} obj Data to fill bean with
* @returns {Bean} Filled bean
*/
static jsonToBean(bean, obj) {
if (obj.id) {
bean.id = obj.id;
}
// Apply timezone offset to timeRange, as it cannot apply automatically.
if (obj.timeRange[0]) {
timeObjectToUTC(obj.timeRange[0]);
if (obj.timeRange[1]) {
timeObjectToUTC(obj.timeRange[1]);
}
}
bean.title = obj.title;
bean.description = obj.description;
bean.strategy = obj.strategy;
bean.interval_day = obj.intervalDay;
bean.active = obj.active;
if (obj.dateRange[0]) {
bean.start_date = localToUTC(obj.dateRange[0]);
if (obj.dateRange[1]) {
bean.end_date = localToUTC(obj.dateRange[1]);
}
}
bean.start_time = parseTimeFromTimeObject(obj.timeRange[0]);
bean.end_time = parseTimeFromTimeObject(obj.timeRange[1]);
bean.weekdays = JSON.stringify(obj.weekdays);
bean.days_of_month = JSON.stringify(obj.daysOfMonth);
return bean;
}
/**
* SQL conditions for active maintenance
* @returns {string}
*/
static getActiveMaintenanceSQLCondition() {
return `
(
(maintenance_timeslot.start_date <= DATETIME('now')
AND maintenance_timeslot.end_date >= DATETIME('now')
AND maintenance.active = 1)
OR
(maintenance.strategy = 'manual' AND active = 1)
)
`;
}
/**
* SQL conditions for active and future maintenance
* @returns {string}
*/
static getActiveAndFutureMaintenanceSQLCondition() {
return `
(
((maintenance_timeslot.end_date >= DATETIME('now')
AND maintenance.active = 1)
OR
(maintenance.strategy = 'manual' AND active = 1))
)
`;
}
}
module.exports = Maintenance;

View File

@ -0,0 +1,198 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
const { R } = require("redbean-node");
const dayjs = require("dayjs");
const { log, utcToLocal, SQL_DATETIME_FORMAT_WITHOUT_SECOND, localToUTC } = require("../../src/util");
const { UptimeKumaServer } = require("../uptime-kuma-server");
class MaintenanceTimeslot extends BeanModel {
/**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @returns {Object}
*/
async toPublicJSON() {
const serverTimezoneOffset = UptimeKumaServer.getInstance().getTimezoneOffset();
const obj = {
id: this.id,
startDate: this.start_date,
endDate: this.end_date,
startDateServerTimezone: utcToLocal(this.start_date, SQL_DATETIME_FORMAT_WITHOUT_SECOND),
endDateServerTimezone: utcToLocal(this.end_date, SQL_DATETIME_FORMAT_WITHOUT_SECOND),
serverTimezoneOffset,
};
return obj;
}
/**
* Return an object that ready to parse to JSON
* @returns {Object}
*/
async toJSON() {
return await this.toPublicJSON();
}
/**
* @param {Maintenance} maintenance
* @param {dayjs} minDate (For recurring type only) Generate a next timeslot from this date.
* @param {boolean} removeExist Remove existing timeslot before create
* @returns {Promise<MaintenanceTimeslot>}
*/
static async generateTimeslot(maintenance, minDate = null, removeExist = false) {
if (removeExist) {
await R.exec("DELETE FROM maintenance_timeslot WHERE maintenance_id = ? ", [
maintenance.id
]);
}
if (maintenance.strategy === "manual") {
log.debug("maintenance", "No need to generate timeslot for manual type");
} else if (maintenance.strategy === "single") {
let bean = R.dispense("maintenance_timeslot");
bean.maintenance_id = maintenance.id;
bean.start_date = maintenance.start_date;
bean.end_date = maintenance.end_date;
bean.generated_next = true;
return await R.store(bean);
} else if (maintenance.strategy === "recurring-interval") {
// Prevent dead loop, in case interval_day is not set
if (!maintenance.interval_day || maintenance.interval_day <= 0) {
maintenance.interval_day = 1;
}
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
return startDateTime.add(maintenance.interval_day, "day");
}, () => {
return true;
});
} else if (maintenance.strategy === "recurring-weekday") {
let dayOfWeekList = maintenance.getDayOfWeekList();
log.debug("timeslot", dayOfWeekList);
if (dayOfWeekList.length <= 0) {
log.debug("timeslot", "No weekdays selected?");
return null;
}
const isValid = (startDateTime) => {
log.debug("timeslot", "nextDateTime: " + startDateTime);
let day = startDateTime.local().day();
log.debug("timeslot", "nextDateTime.day(): " + day);
return dayOfWeekList.includes(day);
};
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
while (true) {
startDateTime = startDateTime.add(1, "day");
if (isValid(startDateTime)) {
return startDateTime;
}
}
}, isValid);
} else if (maintenance.strategy === "recurring-day-of-month") {
let dayOfMonthList = maintenance.getDayOfMonthList();
if (dayOfMonthList.length <= 0) {
log.debug("timeslot", "No day selected?");
return null;
}
const isValid = (startDateTime) => {
let day = parseInt(startDateTime.local().format("D"));
log.debug("timeslot", "day: " + day);
// Check 1-31
if (dayOfMonthList.includes(day)) {
return startDateTime;
}
// Check "lastDay1","lastDay2"...
let daysInMonth = startDateTime.daysInMonth();
let lastDayList = [];
// Small first, e.g. 28 > 29 > 30 > 31
for (let i = 4; i >= 1; i--) {
if (dayOfMonthList.includes("lastDay" + i)) {
lastDayList.push(daysInMonth - i + 1);
}
}
log.debug("timeslot", lastDayList);
return lastDayList.includes(day);
};
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
while (true) {
startDateTime = startDateTime.add(1, "day");
if (isValid(startDateTime)) {
return startDateTime;
}
}
}, isValid);
} else {
throw new Error("Unknown maintenance strategy");
}
}
/**
* Generate a next timeslot for all recurring types
* @param maintenance
* @param minDate
* @param {function} nextDayCallback The logic how to get the next possible day
* @param {function} isValidCallback Check the day whether is matched the current strategy
* @returns {Promise<null|MaintenanceTimeslot>}
*/
static async handleRecurringType(maintenance, minDate, nextDayCallback, isValidCallback) {
let bean = R.dispense("maintenance_timeslot");
let duration = maintenance.getDuration();
let startDateTime = maintenance.getStartDateTime();
let endDateTime;
// Keep generating from the first possible date, until it is ok
while (true) {
log.debug("timeslot", "startDateTime: " + startDateTime.format());
// Handling out of effective date range
if (startDateTime.diff(dayjs.utc(maintenance.end_date)) > 0) {
log.debug("timeslot", "Out of effective date range");
return null;
}
endDateTime = startDateTime.add(duration, "second");
// If endDateTime is out of effective date range, use the end datetime from effective date range
if (endDateTime.diff(dayjs.utc(maintenance.end_date)) > 0) {
endDateTime = dayjs.utc(maintenance.end_date);
}
// If minDate is set, the endDateTime must be bigger than it.
// And the endDateTime must be bigger current time
// Is valid under current recurring strategy
if (
(!minDate || endDateTime.diff(minDate) > 0) &&
endDateTime.diff(dayjs()) > 0 &&
isValidCallback(startDateTime)
) {
break;
}
startDateTime = nextDayCallback(startDateTime);
}
bean.maintenance_id = maintenance.id;
bean.start_date = localToUTC(startDateTime);
bean.end_date = localToUTC(endDateTime);
bean.generated_next = false;
return await R.store(bean);
}
}
module.exports = MaintenanceTimeslot;

File diff suppressed because it is too large Load Diff

25
server/model/proxy.js Normal file
View File

@ -0,0 +1,25 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
class Proxy extends BeanModel {
/**
* Return an object that ready to parse to JSON
* @returns {Object}
*/
toJSON() {
return {
id: this._id,
userId: this._user_id,
protocol: this._protocol,
host: this._host,
port: this._port,
auth: !!this._auth,
username: this._username,
password: this._password,
active: !!this._active,
default: !!this._default,
createdDate: this._created_date,
};
}
}
module.exports = Proxy;

307
server/model/status_page.js Normal file
View File

@ -0,0 +1,307 @@
const { BeanModel } = require("redbean-node/dist/bean-model");
const { R } = require("redbean-node");
const cheerio = require("cheerio");
const { UptimeKumaServer } = require("../uptime-kuma-server");
const jsesc = require("jsesc");
const Maintenance = require("./maintenance");
class StatusPage extends BeanModel {
/**
* Like this: { "test-uptime.kuma.pet": "default" }
* @type {{}}
*/
static domainMappingList = { };
/**
*
* @param {Response} response
* @param {string} indexHTML
* @param {string} slug
*/
static async handleStatusPageResponse(response, indexHTML, slug) {
let statusPage = await R.findOne("status_page", " slug = ? ", [
slug
]);
if (statusPage) {
response.send(await StatusPage.renderHTML(indexHTML, statusPage));
} else {
response.status(404).send(UptimeKumaServer.getInstance().indexHTML);
}
}
/**
* SSR for status pages
* @param {string} indexHTML
* @param {StatusPage} statusPage
*/
static async renderHTML(indexHTML, statusPage) {
const $ = cheerio.load(indexHTML);
const description155 = statusPage.description?.substring(0, 155) ?? "";
$("title").text(statusPage.title);
$("meta[name=description]").attr("content", description155);
if (statusPage.icon) {
$("link[rel=icon]")
.attr("href", statusPage.icon)
.removeAttr("type");
$("link[rel=apple-touch-icon]").remove();
}
const head = $("head");
// OG Meta Tags
head.append(`<meta property="og:title" content="${statusPage.title}" />`);
head.append(`<meta property="og:description" content="${description155}" />`);
// Preload data
// Add jsesc, fix https://github.com/louislam/uptime-kuma/issues/2186
const escapedJSONObject = jsesc(await StatusPage.getStatusPageData(statusPage), {
"isScriptContext": true
});
const script = $(`
<script id="preload-data" data-json="{}">
window.preloadData = ${escapedJSONObject};
</script>
`);
head.append(script);
// manifest.json
$("link[rel=manifest]").attr("href", `/api/status-page/${statusPage.slug}/manifest.json`);
return $.root().html();
}
/**
* Get all status page data in one call
* @param {StatusPage} statusPage
*/
static async getStatusPageData(statusPage) {
// Incident
let incident = await R.findOne("incident", " pin = 1 AND active = 1 AND status_page_id = ? ", [
statusPage.id,
]);
if (incident) {
incident = incident.toPublicJSON();
}
let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
// Public Group List
const publicGroupList = [];
const showTags = !!statusPage.show_tags;
const list = await R.find("group", " public = 1 AND status_page_id = ? ORDER BY weight ", [
statusPage.id
]);
for (let groupBean of list) {
let monitorGroup = await groupBean.toPublicJSON(showTags);
publicGroupList.push(monitorGroup);
}
// Response
return {
config: await statusPage.toPublicJSON(),
incident,
publicGroupList,
maintenanceList,
};
}
/**
* Loads domain mapping from DB
* Return object like this: { "test-uptime.kuma.pet": "default" }
* @returns {Promise<void>}
*/
static async loadDomainMappingList() {
StatusPage.domainMappingList = await R.getAssoc(`
SELECT domain, slug
FROM status_page, status_page_cname
WHERE status_page.id = status_page_cname.status_page_id
`);
}
/**
* Send status page list to client
* @param {Server} io io Socket server instance
* @param {Socket} socket Socket.io instance
* @returns {Promise<Bean[]>}
*/
static async sendStatusPageList(io, socket) {
let result = {};
let list = await R.findAll("status_page", " ORDER BY title ");
for (let item of list) {
result[item.id] = await item.toJSON();
}
io.to(socket.userID).emit("statusPageList", result);
return list;
}
/**
* Update list of domain names
* @param {string[]} domainNameList
* @returns {Promise<void>}
*/
async updateDomainNameList(domainNameList) {
if (!Array.isArray(domainNameList)) {
throw new Error("Invalid array");
}
let trx = await R.begin();
await trx.exec("DELETE FROM status_page_cname WHERE status_page_id = ?", [
this.id,
]);
try {
for (let domain of domainNameList) {
if (typeof domain !== "string") {
throw new Error("Invalid domain");
}
if (domain.trim() === "") {
continue;
}
// If the domain name is used in another status page, delete it
await trx.exec("DELETE FROM status_page_cname WHERE domain = ?", [
domain,
]);
let mapping = trx.dispense("status_page_cname");
mapping.status_page_id = this.id;
mapping.domain = domain;
await trx.store(mapping);
}
await trx.commit();
} catch (error) {
await trx.rollback();
throw error;
}
}
/**
* Get list of domain names
* @returns {Object[]}
*/
getDomainNameList() {
let domainList = [];
for (let domain in StatusPage.domainMappingList) {
let s = StatusPage.domainMappingList[domain];
if (this.slug === s) {
domainList.push(domain);
}
}
return domainList;
}
/**
* Return an object that ready to parse to JSON
* @returns {Object}
*/
async toJSON() {
return {
id: this.id,
slug: this.slug,
title: this.title,
description: this.description,
icon: this.getIcon(),
theme: this.theme,
published: !!this.published,
showTags: !!this.show_tags,
domainNameList: this.getDomainNameList(),
customCSS: this.custom_css,
footerText: this.footer_text,
showPoweredBy: !!this.show_powered_by,
};
}
/**
* Return an object that ready to parse to JSON for public
* Only show necessary data to public
* @returns {Object}
*/
async toPublicJSON() {
return {
slug: this.slug,
title: this.title,
description: this.description,
icon: this.getIcon(),
theme: this.theme,
published: !!this.published,
showTags: !!this.show_tags,
customCSS: this.custom_css,
footerText: this.footer_text,
showPoweredBy: !!this.show_powered_by,
};
}
/**
* Convert slug to status page ID
* @param {string} slug
*/
static async slugToID(slug) {
return await R.getCell("SELECT id FROM status_page WHERE slug = ? ", [
slug
]);
}
/**
* Get path to the icon for the page
* @returns {string}
*/
getIcon() {
if (!this.icon) {
return "/icon.svg";
} else {
return this.icon;
}
}
/**
* Get list of maintenances
* @param {number} statusPageId ID of status page to get maintenance for
* @returns {Object} Object representing maintenances sanitized for public
*/
static async getMaintenanceList(statusPageId) {
try {
const publicMaintenanceList = [];
let activeCondition = Maintenance.getActiveMaintenanceSQLCondition();
let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(`
SELECT DISTINCT maintenance.*
FROM maintenance
JOIN maintenance_status_page
ON maintenance_status_page.maintenance_id = maintenance.id
AND maintenance_status_page.status_page_id = ?
LEFT JOIN maintenance_timeslot
ON maintenance_timeslot.maintenance_id = maintenance.id
WHERE ${activeCondition}
ORDER BY maintenance.end_date
`, [ statusPageId ]));
for (const bean of maintenanceBeanList) {
publicMaintenanceList.push(await bean.toPublicJSON());
}
return publicMaintenanceList;
} catch (error) {
return [];
}
}
}
module.exports = StatusPage;

View File

@ -1,6 +1,11 @@
const { BeanModel } = require("redbean-node/dist/bean-model"); const { BeanModel } = require("redbean-node/dist/bean-model");
class Tag extends BeanModel { class Tag extends BeanModel {
/**
* Return an object that ready to parse to JSON
* @returns {Object}
*/
toJSON() { toJSON() {
return { return {
id: this._id, id: this._id,

View File

@ -3,19 +3,30 @@ const passwordHash = require("../password-hash");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
class User extends BeanModel { class User extends BeanModel {
/**
* Reset user password
* Fix #1510, as in the context reset-password.js, there is no auto model mapping. Call this static function instead.
* @param {number} userID ID of user to update
* @param {string} newPassword
* @returns {Promise<void>}
*/
static async resetPassword(userID, newPassword) {
await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [
passwordHash.generate(newPassword),
userID
]);
}
/** /**
* Direct execute, no need R.store() * Reset this users password
* @param newPassword * @param {string} newPassword
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async resetPassword(newPassword) { async resetPassword(newPassword) {
await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [ await User.resetPassword(this.id, newPassword);
passwordHash.generate(newPassword),
this.id
]);
this.password = newPassword; this.password = newPassword;
} }
} }
module.exports = User; module.exports = User;

View File

@ -13,27 +13,49 @@ let t = {
let instances = []; let instances = [];
/**
* Does a === b
* @param {any} a
* @returns {function(any): boolean}
*/
let matches = function (a) { let matches = function (a) {
return function (b) { return function (b) {
return a === b; return a === b;
}; };
}; };
/**
* Does a!==b
* @param {any} a
* @returns {function(any): boolean}
*/
let doesntMatch = function (a) { let doesntMatch = function (a) {
return function (b) { return function (b) {
return !matches(a)(b); return !matches(a)(b);
}; };
}; };
/**
* Get log duration
* @param {number} d Time in ms
* @param {string} prefix Prefix for log
* @returns {string} Coloured log string
*/
let logDuration = function (d, prefix) { let logDuration = function (d, prefix) {
let str = d > 1000 ? (d / 1000).toFixed(2) + "sec" : d + "ms"; let str = d > 1000 ? (d / 1000).toFixed(2) + "sec" : d + "ms";
return "\x1b[33m- " + (prefix ? prefix + " " : "") + str + "\x1b[0m"; return "\x1b[33m- " + (prefix ? prefix + " " : "") + str + "\x1b[0m";
}; };
/**
* Get safe headers
* @param {Object} res Express response object
* @returns {Object}
*/
function getSafeHeaders(res) { function getSafeHeaders(res) {
return res.getHeaders ? res.getHeaders() : res._headers; return res.getHeaders ? res.getHeaders() : res._headers;
} }
/** Constructor for ApiCache instance */
function ApiCache() { function ApiCache() {
let memCache = new MemoryCache(); let memCache = new MemoryCache();
@ -68,6 +90,15 @@ function ApiCache() {
instances.push(this); instances.push(this);
this.id = instances.length; this.id = instances.length;
/**
* Logs a message to the console if the `DEBUG` environment variable is set.
* @param {string} a The first argument to log.
* @param {string} b The second argument to log.
* @param {string} c The third argument to log.
* @param {string} d The fourth argument to log, and so on... (optional)
*
* Generated by Trelent
*/
function debug(a, b, c, d) { function debug(a, b, c, d) {
let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) { let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) {
return arg !== undefined; return arg !== undefined;
@ -77,6 +108,13 @@ function ApiCache() {
return (globalOptions.debug || debugEnv) && console.log.apply(null, arr); return (globalOptions.debug || debugEnv) && console.log.apply(null, arr);
} }
/**
* Returns true if the given request and response should be logged.
* @param {Object} request The HTTP request object.
* @param {Object} response The HTTP response object.
* @param {function(Object, Object):boolean} toggle
* @returns {boolean}
*/
function shouldCacheResponse(request, response, toggle) { function shouldCacheResponse(request, response, toggle) {
let opt = globalOptions; let opt = globalOptions;
let codes = opt.statusCodes; let codes = opt.statusCodes;
@ -99,6 +137,11 @@ function ApiCache() {
return true; return true;
} }
/**
* Add key to index array
* @param {string} key Key to add
* @param {Object} req Express request object
*/
function addIndexEntries(key, req) { function addIndexEntries(key, req) {
let groupName = req.apicacheGroup; let groupName = req.apicacheGroup;
@ -111,6 +154,16 @@ function ApiCache() {
index.all.unshift(key); index.all.unshift(key);
} }
/**
* Returns a new object containing only the whitelisted headers.
* @param {Object} headers The original object of header names and
* values.
* @param {string[]} globalOptions.headerWhitelist An array of
* strings representing the whitelisted header names to keep in the
* output object.
*
* Generated by Trelent
*/
function filterBlacklistedHeaders(headers) { function filterBlacklistedHeaders(headers) {
return Object.keys(headers) return Object.keys(headers)
.filter(function (key) { .filter(function (key) {
@ -122,6 +175,14 @@ function ApiCache() {
}, {}); }, {});
} }
/**
* Create a cache object
* @param {Object} headers The response headers to filter.
* @returns {Object} A new object containing only the whitelisted
* response headers.
*
* Generated by Trelent
*/
function createCacheObject(status, headers, data, encoding) { function createCacheObject(status, headers, data, encoding) {
return { return {
status: status, status: status,
@ -132,6 +193,15 @@ function ApiCache() {
}; };
} }
/**
* Sets a cache value for the given key.
* @param {string} key The cache key to set.
* @param {any} value The cache value to set.
* @param {number} duration How long in milliseconds the cached
* response should be valid for (defaults to 1 hour).
*
* Generated by Trelent
*/
function cacheResponse(key, value, duration) { function cacheResponse(key, value, duration) {
let redis = globalOptions.redisClient; let redis = globalOptions.redisClient;
let expireCallback = globalOptions.events.expire; let expireCallback = globalOptions.events.expire;
@ -154,6 +224,13 @@ function ApiCache() {
}, Math.min(duration, 2147483647)); }, Math.min(duration, 2147483647));
} }
/**
* Appends content to the response.
* @param {Object} res Express response object
* @param {(string|Buffer)} content The content to append.
*
* Generated by Trelent
*/
function accumulateContent(res, content) { function accumulateContent(res, content) {
if (content) { if (content) {
if (typeof content == "string") { if (typeof content == "string") {
@ -179,6 +256,17 @@ function ApiCache() {
} }
} }
/**
* Monkeypatches the response object to add cache control headers
* and create a cache object.
* @param {Object} req Express request object
* @param {Object} res Express response object
* @param {function} next Function to call next
* @param {string} key Key to add response as
* @param {number} duration Time to cache response for
* @param {string} strDuration Duration in string form
* @param {function(Object, Object):boolean} toggle
*/
function makeResponseCacheable(req, res, next, key, duration, strDuration, toggle) { function makeResponseCacheable(req, res, next, key, duration, strDuration, toggle) {
// monkeypatch res.end to create cache object // monkeypatch res.end to create cache object
res._apicache = { res._apicache = {
@ -245,6 +333,17 @@ function ApiCache() {
next(); next();
} }
/**
* Send a cached response to client
* @param {Request} request Express request object
* @param {Response} response Express response object
* @param {object} cacheObject Cache object to send
* @param {function(Object, Object):boolean} toggle
* @param {function} next Function to call next
* @param {number} duration Not used
* @returns {boolean|undefined} true if the request should be
* cached, false otherwise. If undefined, defaults to true.
*/
function sendCachedResponse(request, response, cacheObject, toggle, next, duration) { function sendCachedResponse(request, response, cacheObject, toggle, next, duration) {
if (toggle && !toggle(request, response)) { if (toggle && !toggle(request, response)) {
return next(); return next();
@ -285,12 +384,19 @@ function ApiCache() {
return response.end(data, cacheObject.encoding); return response.end(data, cacheObject.encoding);
} }
/** Sync caching options */
function syncOptions() { function syncOptions() {
for (let i in middlewareOptions) { for (let i in middlewareOptions) {
Object.assign(middlewareOptions[i].options, globalOptions, middlewareOptions[i].localOptions); Object.assign(middlewareOptions[i].options, globalOptions, middlewareOptions[i].localOptions);
} }
} }
/**
* Clear key from cache
* @param {string} target Key to clear
* @param {boolean} isAutomatic Is the key being cleared automatically
* @returns {number}
*/
this.clear = function (target, isAutomatic) { this.clear = function (target, isAutomatic) {
let group = index.groups[target]; let group = index.groups[target];
let redis = globalOptions.redisClient; let redis = globalOptions.redisClient;
@ -365,6 +471,14 @@ function ApiCache() {
return this.getIndex(); return this.getIndex();
}; };
/**
* Converts a duration string to an integer number of milliseconds.
* @param {(string|number)} duration The string to convert.
* @param {number} defaultDuration The default duration to return if
* can't parse duration
* @returns {number} The converted value in milliseconds, or the
* defaultDuration if it can't be parsed.
*/
function parseDuration(duration, defaultDuration) { function parseDuration(duration, defaultDuration) {
if (typeof duration === "number") { if (typeof duration === "number") {
return duration; return duration;
@ -387,17 +501,24 @@ function ApiCache() {
return defaultDuration; return defaultDuration;
} }
/**
* Parse duration
* @param {(number|string)} duration
* @returns {number} Duration parsed to a number
*/
this.getDuration = function (duration) { this.getDuration = function (duration) {
return parseDuration(duration, globalOptions.defaultDuration); return parseDuration(duration, globalOptions.defaultDuration);
}; };
/** /**
* Return cache performance statistics (hit rate). Suitable for putting into a route: * Return cache performance statistics (hit rate). Suitable for
* putting into a route:
* <code> * <code>
* app.get('/api/cache/performance', (req, res) => { * app.get('/api/cache/performance', (req, res) => {
* res.json(apicache.getPerformance()) * res.json(apicache.getPerformance())
* }) * })
* </code> * </code>
* @returns {any[]}
*/ */
this.getPerformance = function () { this.getPerformance = function () {
return performanceArray.map(function (p) { return performanceArray.map(function (p) {
@ -405,6 +526,11 @@ function ApiCache() {
}); });
}; };
/**
* Get index of a group
* @param {string} group
* @returns {number}
*/
this.getIndex = function (group) { this.getIndex = function (group) {
if (group) { if (group) {
return index.groups[group]; return index.groups[group];
@ -413,6 +539,14 @@ function ApiCache() {
} }
}; };
/**
* Express middleware
* @param {(string|number)} strDuration Duration to cache responses
* for.
* @param {function(Object, Object):boolean} middlewareToggle
* @param {Object} localOptions Options for APICache
* @returns
*/
this.middleware = function cache(strDuration, middlewareToggle, localOptions) { this.middleware = function cache(strDuration, middlewareToggle, localOptions) {
let duration = instance.getDuration(strDuration); let duration = instance.getDuration(strDuration);
let opt = {}; let opt = {};
@ -436,63 +570,72 @@ function ApiCache() {
options(localOptions); options(localOptions);
/** /**
* A Function for non tracking performance * A Function for non tracking performance
*/ */
function NOOPCachePerformance() { function NOOPCachePerformance() {
this.report = this.hit = this.miss = function () {}; // noop; this.report = this.hit = this.miss = function () {}; // noop;
} }
/** /**
* A function for tracking and reporting hit rate. These statistics are returned by the getPerformance() call above. * A function for tracking and reporting hit rate. These
*/ * statistics are returned by the getPerformance() call above.
*/
function CachePerformance() { function CachePerformance() {
/** /**
* Tracks the hit rate for the last 100 requests. * Tracks the hit rate for the last 100 requests. If there
* If there have been fewer than 100 requests, the hit rate just considers the requests that have happened. * have been fewer than 100 requests, the hit rate just
*/ * considers the requests that have happened.
*/
this.hitsLast100 = new Uint8Array(100 / 4); // each hit is 2 bits this.hitsLast100 = new Uint8Array(100 / 4); // each hit is 2 bits
/** /**
* Tracks the hit rate for the last 1000 requests. * Tracks the hit rate for the last 1000 requests. If there
* If there have been fewer than 1000 requests, the hit rate just considers the requests that have happened. * have been fewer than 1000 requests, the hit rate just
*/ * considers the requests that have happened.
*/
this.hitsLast1000 = new Uint8Array(1000 / 4); // each hit is 2 bits this.hitsLast1000 = new Uint8Array(1000 / 4); // each hit is 2 bits
/** /**
* Tracks the hit rate for the last 10000 requests. * Tracks the hit rate for the last 10000 requests. If there
* If there have been fewer than 10000 requests, the hit rate just considers the requests that have happened. * have been fewer than 10000 requests, the hit rate just
*/ * considers the requests that have happened.
*/
this.hitsLast10000 = new Uint8Array(10000 / 4); // each hit is 2 bits this.hitsLast10000 = new Uint8Array(10000 / 4); // each hit is 2 bits
/** /**
* Tracks the hit rate for the last 100000 requests. * Tracks the hit rate for the last 100000 requests. If
* If there have been fewer than 100000 requests, the hit rate just considers the requests that have happened. * there have been fewer than 100000 requests, the hit rate
*/ * just considers the requests that have happened.
*/
this.hitsLast100000 = new Uint8Array(100000 / 4); // each hit is 2 bits this.hitsLast100000 = new Uint8Array(100000 / 4); // each hit is 2 bits
/** /**
* The number of calls that have passed through the middleware since the server started. * The number of calls that have passed through the
*/ * middleware since the server started.
*/
this.callCount = 0; this.callCount = 0;
/** /**
* The total number of hits since the server started * The total number of hits since the server started
*/ */
this.hitCount = 0; this.hitCount = 0;
/** /**
* The key from the last cache hit. This is useful in identifying which route these statistics apply to. * The key from the last cache hit. This is useful in
*/ * identifying which route these statistics apply to.
*/
this.lastCacheHit = null; this.lastCacheHit = null;
/** /**
* The key from the last cache miss. This is useful in identifying which route these statistics apply to. * The key from the last cache miss. This is useful in
*/ * identifying which route these statistics apply to.
*/
this.lastCacheMiss = null; this.lastCacheMiss = null;
/** /**
* Return performance statistics * Return performance statistics
*/ * @returns {Object}
*/
this.report = function () { this.report = function () {
return { return {
lastCacheHit: this.lastCacheHit, lastCacheHit: this.lastCacheHit,
@ -509,10 +652,13 @@ function ApiCache() {
}; };
/** /**
* Computes a cache hit rate from an array of hits and misses. * Computes a cache hit rate from an array of hits and
* @param {Uint8Array} array An array representing hits and misses. * misses.
* @returns a number between 0 and 1, or null if the array has no hits or misses * @param {Uint8Array} array An array representing hits and
*/ * misses.
* @returns {?number} a number between 0 and 1, or null if
* the array has no hits or misses
*/
this.hitRate = function (array) { this.hitRate = function (array) {
let hits = 0; let hits = 0;
let misses = 0; let misses = 0;
@ -538,16 +684,17 @@ function ApiCache() {
}; };
/** /**
* Record a hit or miss in the given array. It will be recorded at a position determined * Record a hit or miss in the given array. It will be
* by the current value of the callCount variable. * recorded at a position determined by the current value of
* @param {Uint8Array} array An array representing hits and misses. * the callCount variable.
* @param {boolean} hit true for a hit, false for a miss * @param {Uint8Array} array An array representing hits and
* Each element in the array is 8 bits, and encodes 4 hit/miss records. * misses.
* Each hit or miss is encoded as to bits as follows: * @param {boolean} hit true for a hit, false for a miss
* 00 means no hit or miss has been recorded in these bits * Each element in the array is 8 bits, and encodes 4
* 01 encodes a hit * hit/miss records. Each hit or miss is encoded as to bits
* 10 encodes a miss * as follows: 00 means no hit or miss has been recorded in
*/ * these bits 01 encodes a hit 10 encodes a miss
*/
this.recordHitInArray = function (array, hit) { this.recordHitInArray = function (array, hit) {
let arrayIndex = ~~(this.callCount / 4) % array.length; let arrayIndex = ~~(this.callCount / 4) % array.length;
let bitOffset = (this.callCount % 4) * 2; // 2 bits per record, 4 records per uint8 array element let bitOffset = (this.callCount % 4) * 2; // 2 bits per record, 4 records per uint8 array element
@ -557,9 +704,11 @@ function ApiCache() {
}; };
/** /**
* Records the hit or miss in the tracking arrays and increments the call count. * Records the hit or miss in the tracking arrays and
* @param {boolean} hit true records a hit, false records a miss * increments the call count.
*/ * @param {boolean} hit true records a hit, false records a
* miss
*/
this.recordHit = function (hit) { this.recordHit = function (hit) {
this.recordHitInArray(this.hitsLast100, hit); this.recordHitInArray(this.hitsLast100, hit);
this.recordHitInArray(this.hitsLast1000, hit); this.recordHitInArray(this.hitsLast1000, hit);
@ -572,18 +721,18 @@ function ApiCache() {
}; };
/** /**
* Records a hit event, setting lastCacheMiss to the given key * Records a hit event, setting lastCacheMiss to the given key
* @param {string} key The key that had the cache hit * @param {string} key The key that had the cache hit
*/ */
this.hit = function (key) { this.hit = function (key) {
this.recordHit(true); this.recordHit(true);
this.lastCacheHit = key; this.lastCacheHit = key;
}; };
/** /**
* Records a miss event, setting lastCacheMiss to the given key * Records a miss event, setting lastCacheMiss to the given key
* @param {string} key The key that had the cache miss * @param {string} key The key that had the cache miss
*/ */
this.miss = function (key) { this.miss = function (key) {
this.recordHit(false); this.recordHit(false);
this.lastCacheMiss = key; this.lastCacheMiss = key;
@ -594,6 +743,13 @@ function ApiCache() {
performanceArray.push(perf); performanceArray.push(perf);
/**
* Cache a request
* @param {Object} req Express request object
* @param {Object} res Express response object
* @param {function} next Function to call next
* @returns {any}
*/
let cache = function (req, res, next) { let cache = function (req, res, next) {
function bypass() { function bypass() {
debug("bypass detected, skipping cache."); debug("bypass detected, skipping cache.");
@ -701,6 +857,11 @@ function ApiCache() {
return cache; return cache;
}; };
/**
* Process options
* @param {Object} options
* @returns {Object}
*/
this.options = function (options) { this.options = function (options) {
if (options) { if (options) {
Object.assign(globalOptions, options); Object.assign(globalOptions, options);
@ -721,6 +882,7 @@ function ApiCache() {
} }
}; };
/** Reset the index */
this.resetIndex = function () { this.resetIndex = function () {
index = { index = {
all: [], all: [],
@ -728,6 +890,11 @@ function ApiCache() {
}; };
}; };
/**
* Create a new instance of ApiCache
* @param {Object} config Config to pass
* @returns {ApiCache}
*/
this.newInstance = function (config) { this.newInstance = function (config) {
let instance = new ApiCache(); let instance = new ApiCache();
@ -738,6 +905,7 @@ function ApiCache() {
return instance; return instance;
}; };
/** Clone this instance */
this.clone = function () { this.clone = function () {
return this.newInstance(this.options()); return this.newInstance(this.options());
}; };

View File

@ -3,6 +3,15 @@ function MemoryCache() {
this.size = 0; this.size = 0;
} }
/**
*
* @param {string} key Key to store cache as
* @param {any} value Value to store
* @param {number} time Time to store for
* @param {function(any, string)} timeoutCallback Callback to call in
* case of timeout
* @returns {Object}
*/
MemoryCache.prototype.add = function (key, value, time, timeoutCallback) { MemoryCache.prototype.add = function (key, value, time, timeoutCallback) {
let old = this.cache[key]; let old = this.cache[key];
let instance = this; let instance = this;
@ -22,6 +31,11 @@ MemoryCache.prototype.add = function (key, value, time, timeoutCallback) {
return entry; return entry;
}; };
/**
* Delete a cache entry
* @param {string} key Key to delete
* @returns {null}
*/
MemoryCache.prototype.delete = function (key) { MemoryCache.prototype.delete = function (key) {
let entry = this.cache[key]; let entry = this.cache[key];
@ -36,18 +50,32 @@ MemoryCache.prototype.delete = function (key) {
return null; return null;
}; };
/**
* Get value of key
* @param {string} key
* @returns {Object}
*/
MemoryCache.prototype.get = function (key) { MemoryCache.prototype.get = function (key) {
let entry = this.cache[key]; let entry = this.cache[key];
return entry; return entry;
}; };
/**
* Get value of cache entry
* @param {string} key
* @returns {any}
*/
MemoryCache.prototype.getValue = function (key) { MemoryCache.prototype.getValue = function (key) {
let entry = this.get(key); let entry = this.get(key);
return entry && entry.value; return entry && entry.value;
}; };
/**
* Clear cache
* @returns {boolean}
*/
MemoryCache.prototype.clear = function () { MemoryCache.prototype.clear = function () {
Object.keys(this.cache).forEach(function (key) { Object.keys(this.cache).forEach(function (key) {
this.delete(key); this.delete(key);

View File

@ -0,0 +1,20 @@
import { PluginFunc, ConfigType } from 'dayjs'
declare const plugin: PluginFunc
export = plugin
declare module 'dayjs' {
interface Dayjs {
tz(timezone?: string, keepLocalTime?: boolean): Dayjs
offsetName(type?: 'short' | 'long'): string | undefined
}
interface DayjsTimezone {
(date: ConfigType, timezone?: string): Dayjs
(date: ConfigType, format: string, timezone?: string): Dayjs
guess(): string
setDefault(timezone?: string): void
}
const tz: DayjsTimezone
}

View File

@ -0,0 +1,115 @@
/**
* Copy from node_modules/dayjs/plugin/timezone.js
* Try to fix https://github.com/louislam/uptime-kuma/issues/2318
* Source: https://github.com/iamkun/dayjs/tree/dev/src/plugin/utc
* License: MIT
*/
!function (t, e) {
// eslint-disable-next-line no-undef
typeof exports == "object" && typeof module != "undefined" ? module.exports = e() : typeof define == "function" && define.amd ? define(e) : (t = typeof globalThis != "undefined" ? globalThis : t || self).dayjs_plugin_timezone = e();
}(this, (function () {
"use strict";
let t = {
year: 0,
month: 1,
day: 2,
hour: 3,
minute: 4,
second: 5
};
let e = {};
return function (n, i, o) {
let r;
let a = function (t, n, i) {
void 0 === i && (i = {});
let o = new Date(t);
let r = function (t, n) {
void 0 === n && (n = {});
let i = n.timeZoneName || "short";
let o = t + "|" + i;
let r = e[o];
return r || (r = new Intl.DateTimeFormat("en-US", {
hour12: !1,
timeZone: t,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: i
}), e[o] = r), r;
}(n, i);
return r.formatToParts(o);
};
let u = function (e, n) {
let i = a(e, n);
let r = [];
let u = 0;
for (; u < i.length; u += 1) {
let f = i[u];
let s = f.type;
let m = f.value;
let c = t[s];
c >= 0 && (r[c] = parseInt(m, 10));
}
let d = r[3];
let l = d === 24 ? 0 : d;
let v = r[0] + "-" + r[1] + "-" + r[2] + " " + l + ":" + r[4] + ":" + r[5] + ":000";
let h = +e;
return (o.utc(v).valueOf() - (h -= h % 1e3)) / 6e4;
};
let f = i.prototype;
f.tz = function (t, e) {
void 0 === t && (t = r);
let n = this.utcOffset();
let i = this.toDate();
let a = i.toLocaleString("en-US", { timeZone: t }).replace("\u202f", " ");
let u = Math.round((i - new Date(a)) / 1e3 / 60);
let f = o(a).$set("millisecond", this.$ms).utcOffset(15 * -Math.round(i.getTimezoneOffset() / 15) - u, !0);
if (e) {
let s = f.utcOffset();
f = f.add(n - s, "minute");
}
return f.$x.$timezone = t, f;
}, f.offsetName = function (t) {
let e = this.$x.$timezone || o.tz.guess();
let n = a(this.valueOf(), e, { timeZoneName: t }).find((function (t) {
return t.type.toLowerCase() === "timezonename";
}));
return n && n.value;
};
let s = f.startOf;
f.startOf = function (t, e) {
if (!this.$x || !this.$x.$timezone) {
return s.call(this, t, e);
}
let n = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"));
return s.call(n, t, e).tz(this.$x.$timezone, !0);
}, o.tz = function (t, e, n) {
let i = n && e;
let a = n || e || r;
let f = u(+o(), a);
if (typeof t != "string") {
return o(t).tz(a);
}
let s = function (t, e, n) {
let i = t - 60 * e * 1e3;
let o = u(i, n);
if (e === o) {
return [ i, e ];
}
let r = u(i -= 60 * (o - e) * 1e3, n);
return o === r ? [ i, o ] : [ t - 60 * Math.min(o, r) * 1e3, Math.max(o, r) ];
}(o.utc(t, i).valueOf(), f, a);
let m = s[0];
let c = s[1];
let d = o(m).utcOffset(c);
return d.$x.$timezone = a, d;
}, o.tz.guess = function () {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
}, o.tz.setDefault = function (t) {
r = t;
};
};
}));

View File

@ -0,0 +1,67 @@
const NotificationProvider = require("./notification-provider");
const { DOWN, UP } = require("../../src/util");
const axios = require("axios");
class Alerta extends NotificationProvider {
name = "alerta";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
let alertaUrl = `${notification.alertaApiEndpoint}`;
let config = {
headers: {
"Content-Type": "application/json;charset=UTF-8",
"Authorization": "Key " + notification.alertaApiKey,
}
};
let data = {
environment: notification.alertaEnvironment,
severity: "critical",
correlate: [],
service: [ "UptimeKuma" ],
value: "Timeout",
tags: [ "uptimekuma" ],
attributes: {},
origin: "uptimekuma",
type: "exceptionAlert",
};
if (heartbeatJSON == null) {
let postData = Object.assign({
event: "msg",
text: msg,
group: "uptimekuma-msg",
resource: "Message",
}, data);
await axios.post(alertaUrl, postData, config);
} else {
let datadup = Object.assign( {
correlate: [ "service_up", "service_down" ],
event: monitorJSON["type"],
group: "uptimekuma-" + monitorJSON["type"],
resource: monitorJSON["name"],
}, data );
if (heartbeatJSON["status"] === DOWN) {
datadup.severity = notification.alertaAlertState; // critical
datadup.text = "Service " + monitorJSON["type"] + " is down.";
await axios.post(alertaUrl, datadup, config);
} else if (heartbeatJSON["status"] === UP) {
datadup.severity = notification.alertaRecoverState; // cleaned
datadup.text = "Service " + monitorJSON["type"] + " is up.";
await axios.post(alertaUrl, datadup, config);
}
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = Alerta;

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

@ -37,6 +37,12 @@ class AliyunSMS extends NotificationProvider {
} }
} }
/**
* Send the SMS notification
* @param {BeanModel} notification Notification details
* @param {string} msgbody Message template
* @returns {boolean} True if successful else false
*/
async sendSms(notification, msgbody) { async sendSms(notification, msgbody) {
let params = { let params = {
PhoneNumbers: notification.phonenumber, PhoneNumbers: notification.phonenumber,
@ -64,13 +70,18 @@ class AliyunSMS extends NotificationProvider {
}; };
let result = await axios(config); let result = await axios(config);
if (result.data.Message == "OK") { if (result.data.Message === "OK") {
return true; return true;
} }
return false; return false;
} }
/** Aliyun request sign */ /**
* Aliyun request sign
* @param {Object} param Parameters object to sign
* @param {string} AccessKeySecret Secret key to sign parameters with
* @returns {string}
*/
sign(param, AccessKeySecret) { sign(param, AccessKeySecret) {
let param2 = {}; let param2 = {};
let data = []; let data = [];
@ -82,8 +93,23 @@ class AliyunSMS extends NotificationProvider {
param2[key] = param[key]; param2[key] = param[key];
} }
// Escape more characters than encodeURIComponent does.
// For generating Aliyun signature, all characters except A-Za-z0-9~-._ are encoded.
// See https://help.aliyun.com/document_detail/315526.html
// This encoding methods as known as RFC 3986 (https://tools.ietf.org/html/rfc3986)
let moreEscapesTable = function (m) {
return {
"!": "%21",
"*": "%2A",
"'": "%27",
"(": "%28",
")": "%29"
}[m];
};
for (let key in param2) { for (let key in param2) {
data.push(`${encodeURIComponent(key)}=${encodeURIComponent(param2[key])}`); let value = encodeURIComponent(param2[key]).replace(/[!*'()]/g, moreEscapesTable);
data.push(`${encodeURIComponent(key)}=${value}`);
} }
let StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`; let StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`;
@ -93,6 +119,11 @@ class AliyunSMS extends NotificationProvider {
.digest("base64"); .digest("base64");
} }
/**
* Convert status constant to string
* @param {const} status The status constant
* @returns {string}
*/
statusToString(status) { statusToString(status) {
switch (status) { switch (status) {
case DOWN: case DOWN:

View File

@ -1,14 +1,19 @@
const NotificationProvider = require("./notification-provider"); const NotificationProvider = require("./notification-provider");
const child_process = require("child_process"); const childProcess = require("child_process");
class Apprise extends NotificationProvider { class Apprise extends NotificationProvider {
name = "apprise"; name = "apprise";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]) const args = [ "-vv", "-b", msg, notification.appriseURL ];
if (notification.title) {
args.push("-t");
args.push(notification.title);
}
const s = childProcess.spawnSync("apprise", args);
let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found"; const output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found";
if (output) { if (output) {
@ -16,7 +21,7 @@ class Apprise extends NotificationProvider {
return "Sent Successfully"; return "Sent Successfully";
} }
throw new Error(output) throw new Error(output);
} else { } else {
return "No output from apprise"; return "No output from apprise";
} }

View File

@ -12,55 +12,67 @@ const { default: axios } = require("axios");
// bark is an APN bridge that sends notifications to Apple devices. // 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 barkNotificationAvatar = "https://github.com/louislam/uptime-kuma/raw/master/public/icon.png";
const barkNotificationSound = "telegraph";
const successMessage = "Successes!"; const successMessage = "Successes!";
class Bark extends NotificationProvider { class Bark extends NotificationProvider {
name = "Bark"; name = "Bark";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
try { let barkEndpoint = notification.barkEndpoint;
var barkEndpoint = notification.barkEndpoint;
// check if the endpoint has a "/" suffix, if so, delete it first // check if the endpoint has a "/" suffix, if so, delete it first
if (barkEndpoint.endsWith("/")) { if (barkEndpoint.endsWith("/")) {
barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1);
} }
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) { if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) {
let title = "UptimeKuma Monitor Up"; let title = "UptimeKuma Monitor Up";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
} }
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) {
let title = "UptimeKuma Monitor Down"; let title = "UptimeKuma Monitor Down";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
} }
if (msg != null) { if (msg != null) {
let title = "UptimeKuma Message"; let title = "UptimeKuma Message";
return await this.postNotification(title, msg, barkEndpoint); return await this.postNotification(notification, title, msg, barkEndpoint);
}
} catch (error) {
throw error;
} }
} }
// add additional parameter for better on device styles (iOS 15 optimized) /**
appendAdditionalParameters(postUrl) { * Add additional parameter for better on device styles (iOS 15
// grouping all our notifications * optimized)
postUrl += "?group=" + barkNotificationGroup; * @param {string} postUrl URL to append parameters to
* @returns {string}
*/
appendAdditionalParameters(notification, postUrl) {
// set icon to uptime kuma icon, 11kb should be fine // set icon to uptime kuma icon, 11kb should be fine
postUrl += "&icon=" + barkNotificationAvatar; postUrl += "?icon=" + barkNotificationAvatar;
// grouping all our notifications
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 // 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; return postUrl;
} }
// thrown if failed to check result, result code should be in range 2xx /**
* Check if result is successful
* @param {Object} result Axios response object
* @throws {Error} The status code is not in range 2xx
*/
checkResult(result) { checkResult(result) {
if (result.status == null) { if (result.status == null) {
throw new Error("Bark notification failed with invalid response!"); throw new Error("Bark notification failed with invalid response!");
@ -70,12 +82,19 @@ class Bark extends NotificationProvider {
} }
} }
async postNotification(title, subtitle, endpoint) { /**
* Send the message
* @param {string} title Message title
* @param {string} subtitle Message
* @param {string} endpoint Endpoint to send request to
* @returns {string}
*/
async postNotification(notification, title, subtitle, endpoint) {
// url encode title and subtitle // url encode title and subtitle
title = encodeURIComponent(title); title = encodeURIComponent(title);
subtitle = encodeURIComponent(subtitle); subtitle = encodeURIComponent(subtitle);
let postUrl = endpoint + "/" + title + "/" + subtitle; let postUrl = endpoint + "/" + title + "/" + subtitle;
postUrl = this.appendAdditionalParameters(postUrl); postUrl = this.appendAdditionalParameters(notification, postUrl);
let result = await axios.get(postUrl); let result = await axios.get(postUrl);
this.checkResult(result); this.checkResult(result);
if (result.statusText != null) { if (result.statusText != null) {

View File

@ -12,7 +12,7 @@ class ClickSendSMS extends NotificationProvider {
let config = { let config = {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'), "Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString("base64"),
"Accept": "text/json", "Accept": "text/json",
} }
}; };

View File

@ -37,6 +37,12 @@ class DingDing extends NotificationProvider {
} }
} }
/**
* Send message to DingDing
* @param {BeanModel} notification
* @param {Object} params Parameters of message
* @returns {boolean} True if successful else false
*/
async sendToDingDing(notification, params) { async sendToDingDing(notification, params) {
let timestamp = Date.now(); let timestamp = Date.now();
@ -50,13 +56,18 @@ class DingDing extends NotificationProvider {
}; };
let result = await axios(config); let result = await axios(config);
if (result.data.errmsg == "ok") { if (result.data.errmsg === "ok") {
return true; return true;
} }
return false; return false;
} }
/** DingDing sign */ /**
* DingDing sign
* @param {Date} timestamp Timestamp of message
* @param {string} secretKey Secret key to sign data with
* @returns {string}
*/
sign(timestamp, secretKey) { sign(timestamp, secretKey) {
return Crypto return Crypto
.createHmac("sha256", Buffer.from(secretKey, "utf8")) .createHmac("sha256", Buffer.from(secretKey, "utf8"))
@ -64,7 +75,13 @@ class DingDing extends NotificationProvider {
.digest("base64"); .digest("base64");
} }
/**
* Convert status constant to string
* @param {const} status The status constant
* @returns {string}
*/
statusToString(status) { statusToString(status) {
// TODO: Move to notification-provider.js to avoid repetition in classes
switch (status) { switch (status) {
case DOWN: case DOWN:
return "DOWN"; return "DOWN";

View File

@ -17,25 +17,32 @@ class Discord extends NotificationProvider {
let discordtestdata = { let discordtestdata = {
username: discordDisplayName, username: discordDisplayName,
content: msg, content: msg,
} };
await axios.post(notification.discordWebhookUrl, discordtestdata) await axios.post(notification.discordWebhookUrl, discordtestdata);
return okMsg; return okMsg;
} }
let url; let address;
if (monitorJSON["type"] === "port") { switch (monitorJSON["type"]) {
url = monitorJSON["hostname"]; case "ping":
if (monitorJSON["port"]) { address = monitorJSON["hostname"];
url += ":" + monitorJSON["port"]; break;
} case "port":
case "dns":
} else { case "steam":
url = monitorJSON["url"]; address = monitorJSON["hostname"];
if (monitorJSON["port"]) {
address += ":" + monitorJSON["port"];
}
break;
default:
address = monitorJSON["url"];
break;
} }
// If heartbeatJSON is not null, we go into the normal alerting loop. // If heartbeatJSON is not null, we go into the normal alerting loop.
if (heartbeatJSON["status"] == DOWN) { if (heartbeatJSON["status"] === DOWN) {
let discorddowndata = { let discorddowndata = {
username: discordDisplayName, username: discordDisplayName,
embeds: [{ embeds: [{
@ -48,8 +55,8 @@ class Discord extends NotificationProvider {
value: monitorJSON["name"], value: monitorJSON["name"],
}, },
{ {
name: "Service URL", name: monitorJSON["type"] === "push" ? "Service Type" : "Service URL",
value: url, value: monitorJSON["type"] === "push" ? "Heartbeat" : address,
}, },
{ {
name: "Time (UTC)", name: "Time (UTC)",
@ -57,20 +64,20 @@ class Discord extends NotificationProvider {
}, },
{ {
name: "Error", name: "Error",
value: heartbeatJSON["msg"], value: heartbeatJSON["msg"] == null ? "N/A" : heartbeatJSON["msg"],
}, },
], ],
}], }],
} };
if (notification.discordPrefixMessage) { if (notification.discordPrefixMessage) {
discorddowndata.content = notification.discordPrefixMessage; discorddowndata.content = notification.discordPrefixMessage;
} }
await axios.post(notification.discordWebhookUrl, discorddowndata) await axios.post(notification.discordWebhookUrl, discorddowndata);
return okMsg; return okMsg;
} else if (heartbeatJSON["status"] == UP) { } else if (heartbeatJSON["status"] === UP) {
let discordupdata = { let discordupdata = {
username: discordDisplayName, username: discordDisplayName,
embeds: [{ embeds: [{
@ -83,8 +90,8 @@ class Discord extends NotificationProvider {
value: monitorJSON["name"], value: monitorJSON["name"],
}, },
{ {
name: "Service URL", name: monitorJSON["type"] === "push" ? "Service Type" : "Service URL",
value: url.startsWith("http") ? "[Visit Service](" + url + ")" : url, value: monitorJSON["type"] === "push" ? "Heartbeat" : address,
}, },
{ {
name: "Time (UTC)", name: "Time (UTC)",
@ -92,21 +99,21 @@ class Discord extends NotificationProvider {
}, },
{ {
name: "Ping", name: "Ping",
value: heartbeatJSON["ping"] + "ms", value: heartbeatJSON["ping"] == null ? "N/A" : heartbeatJSON["ping"] + " ms",
}, },
], ],
}], }],
} };
if (notification.discordPrefixMessage) { if (notification.discordPrefixMessage) {
discordupdata.content = notification.discordPrefixMessage; discordupdata.content = notification.discordPrefixMessage;
} }
await axios.post(notification.discordWebhookUrl, discordupdata) await axios.post(notification.discordWebhookUrl, discordupdata);
return okMsg; return okMsg;
} }
} catch (error) { } catch (error) {
this.throwGeneralAxiosError(error) this.throwGeneralAxiosError(error);
} }
} }

View File

@ -21,7 +21,7 @@ class Feishu extends NotificationProvider {
return okMsg; return okMsg;
} }
if (heartbeatJSON["status"] == DOWN) { if (heartbeatJSON["status"] === DOWN) {
let downdata = { let downdata = {
msg_type: "post", msg_type: "post",
content: { content: {
@ -48,7 +48,7 @@ class Feishu extends NotificationProvider {
return okMsg; return okMsg;
} }
if (heartbeatJSON["status"] == UP) { if (heartbeatJSON["status"] === UP) {
let updata = { let updata = {
msg_type: "post", msg_type: "post",
content: { content: {

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