mirror of
https://github.com/WGDashboard/WGDashboard.git
synced 2026-08-04 15:03:02 +00:00
Compare commits
1201 Commits
v1.0-beta.5
...
v4.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 481fadc7fc | |||
| 44f2c59e56 | |||
| 83589a912f | |||
| fab9f03e7d | |||
| 928c83b13c | |||
| 72f20bc69b | |||
| 8293d5379d | |||
| 1d29445a8b | |||
| 5c308d757f | |||
| 5bf16004c9 | |||
| 417fa437b7 | |||
| 43f893c921 | |||
| 8ad9af4bc2 | |||
| b3931bdc9d | |||
| 7ac153848b | |||
| 7689ebcac5 | |||
| bf7adf9ca9 | |||
| 51ab8c556a | |||
| 149a8e910d | |||
| 310746b8cd | |||
| 6681303450 | |||
| 3228f37f09 | |||
| 421785bf6a | |||
| 308e8ca8c7 | |||
| cb068ef70e | |||
| acd3ec782f | |||
| 12d1e5b8d0 | |||
| b165cdbd79 | |||
| 66f4507dee | |||
| a724e1cb58 | |||
| f942809de0 | |||
| 8043f77e02 | |||
| 1db9ba90d8 | |||
| 464fa59cb6 | |||
| a8e2cbf55b | |||
| fecd8dab38 | |||
| 13a833e3ed | |||
| 8d4784052a | |||
| d9e9b41861 | |||
| f0c3ef0aa1 | |||
| 3888831679 | |||
| 1a32fad324 | |||
| d842ae9540 | |||
| d0177b7504 | |||
| e3842b25f3 | |||
| a29b59c9cd | |||
| f94eb97aa4 | |||
| 86017b79eb | |||
| bc22fa5fad | |||
| d6b70028ff | |||
| 0f7f9acd58 | |||
| 20633a6d1a | |||
| a23856270d | |||
| 55543e370e | |||
| 8137a46c68 | |||
| aeb9597c71 | |||
| 5067485e94 | |||
| dfd456c7dc | |||
| 0ccb07e683 | |||
| ca67a6897f | |||
| 0390227641 | |||
| 395b0982db | |||
| f096ab4da7 | |||
| d5ec9f7640 | |||
| 5732867407 | |||
| 31842f4c12 | |||
| d5168d2da6 | |||
| cac5ec836b | |||
| ee9569e7d4 | |||
| 95df7de026 | |||
| d3a5bd374d | |||
| 43ac3dddf1 | |||
| 1174328de3 | |||
| dda54fb907 | |||
| 92ea808a5d | |||
| 2bc3a75c94 | |||
| 07ef97ce7c | |||
| 5fe3539331 | |||
| 4bc3bd5f13 | |||
| 4abce854d7 | |||
| 3b5c73992e | |||
| c5abea2944 | |||
| 8e5cf14ebc | |||
| 7c8410ab86 | |||
| 369b4b92cc | |||
| c50bb70383 | |||
| d84b2060f0 | |||
| afcf6024e6 | |||
| 3542bd6668 | |||
| 69b9116dd5 | |||
| a2db4f06b1 | |||
| b60b0fb511 | |||
| 0c1e9a6bb5 | |||
| 2692f92cb9 | |||
| a43c8b4b00 | |||
| 6f15389411 | |||
| f055241802 | |||
| ac77c3a390 | |||
| 5cd99f2edc | |||
| 7c70fbec30 | |||
| ac0dc3196f | |||
| 7f4da826b1 | |||
| cc2af4371f | |||
| 2a79a03d38 | |||
| 47aac7fe33 | |||
| d4055884b1 | |||
| 61658e847a | |||
| bd714223ce | |||
| 060154cb89 | |||
| 99a1bfca9d | |||
| 4379f30628 | |||
| b501244577 | |||
| 6f7b9815ca | |||
| 227bd088f7 | |||
| b1d6ecb07c | |||
| 41772f28bd | |||
| 393dac1c99 | |||
| db9d0be6c7 | |||
| f0774ec273 | |||
| d4a4d28b58 | |||
| 3ec97021bd | |||
| 56cf972373 | |||
| 2f3ae4c1af | |||
| bc3dd04e12 | |||
| 4e8fc1b431 | |||
| cd39aa2968 | |||
| 87ea3fc982 | |||
| f74a511778 | |||
| 202461fe48 | |||
| 2af6687351 | |||
| e603af5f24 | |||
| 84069ee882 | |||
| edbb5cef92 | |||
| a62c54b4ed | |||
| 41df7c04c3 | |||
| 9b783a8322 | |||
| 57db4df618 | |||
| 9d1081bd56 | |||
| cc3773817b | |||
| 8956355e57 | |||
| 645db97c14 | |||
| 07a04dc507 | |||
| a7317af413 | |||
| ba6d6b8851 | |||
| 3726810108 | |||
| 4f92a7edf3 | |||
| 5d84b61f18 | |||
| cd1329ec67 | |||
| 48a58b2b69 | |||
| 9b64aba8bf | |||
| cae8264d98 | |||
| 95d8985336 | |||
| b26ae90807 | |||
| 66d171c432 | |||
| 40463d9831 | |||
| eb7dee013d | |||
| 1a878599b1 | |||
| b9e25abdd9 | |||
| c612022717 | |||
| 31e7f02b8d | |||
| 75747a2979 | |||
| a85a8668a7 | |||
| cca5fd859c | |||
| 2ed49abb1b | |||
| 409e6d49b2 | |||
| 93cfc482b8 | |||
| 85be6d53d0 | |||
| bf6f58eb5e | |||
| cd9d17ab18 | |||
| e0bc6a10d0 | |||
| ccfc1ad166 | |||
| 812060240f | |||
| 715a266ca4 | |||
| fa4b3ece56 | |||
| aac2a002bb | |||
| 8574acaf6e | |||
| ddf4639354 | |||
| 9bd394f351 | |||
| 6899d48aae | |||
| 514e1ca8d0 | |||
| eba5be010a | |||
| f578d5c1c9 | |||
| e58b1d670b | |||
| c2642259b4 | |||
| c47b0c9741 | |||
| f425156cad | |||
| 7d7e31120e | |||
| ccd247d154 | |||
| 53df6849f7 | |||
| c2080bd1b3 | |||
| 9e93f8c2a5 | |||
| 907a142c8d | |||
| d7bc8cd8e4 | |||
| bb3e00a695 | |||
| af5e7974c3 | |||
| 6a88959ec4 | |||
| 7b59149f90 | |||
| 3e01079caf | |||
| d92e62e40b | |||
| b4952dea7b | |||
| 00acb04329 | |||
| 939dd0591e | |||
| febdb2a9e0 | |||
| bcfd9fc1c9 | |||
| e4964da5d4 | |||
| a042298a4a | |||
| 908be168a9 | |||
| d780bb3937 | |||
| 461e7e8913 | |||
| 819e8b73c3 | |||
| 627b7087a1 | |||
| f23cf555e1 | |||
| 000978e4fb | |||
| 74782483bd | |||
| c5f9387b92 | |||
| 57583b6747 | |||
| 434c236210 | |||
| 807bb97b6a | |||
| da53bd44d1 | |||
| 3b01943649 | |||
| 3340f9c6ee | |||
| b21cfe8504 | |||
| 97ab6ec299 | |||
| 7fda58e5c8 | |||
| db6e820d1d | |||
| 8c2e1875ca | |||
| bd95fe9af1 | |||
| a517f89234 | |||
| f994e7bfa8 | |||
| 28716924c9 | |||
| b597f90f5b | |||
| 5912420467 | |||
| 90f35fd680 | |||
| 3e2d6e71b9 | |||
| cbffdd829a | |||
| d77e092948 | |||
| 1f5e10e784 | |||
| 68e3813c6c | |||
| c9d78e3f67 | |||
| b4f3fb3b30 | |||
| bf7fb898f9 | |||
| 6c5e0543b4 | |||
| 578a1db62f | |||
| 4524a55b23 | |||
| f942eaf1b6 | |||
| 6a4d16fae9 | |||
| 53b234252f | |||
| 9287e81ef1 | |||
| 5462326f79 | |||
| b8b3992159 | |||
| 8214000713 | |||
| 94337a33d4 | |||
| 8ddee03338 | |||
| 8e2934533b | |||
| 71ee784003 | |||
| 597528e9b7 | |||
| 45fbbf9218 | |||
| c7a4a01fee | |||
| fa04ad1395 | |||
| abdd85bdd5 | |||
| dba55d57e8 | |||
| 9819c96717 | |||
| 1b0885bffe | |||
| c0a8540ab8 | |||
| f3b95f03a1 | |||
| 5f06f3da52 | |||
| 10a7fb809b | |||
| d3ea1f3da2 | |||
| 74d0471a6f | |||
| a1c1805409 | |||
| b843145bed | |||
| 119920b665 | |||
| 6190e2d290 | |||
| 79de99d146 | |||
| 56a9b3df0a | |||
| 4df6413dba | |||
| fcd0ada639 | |||
| 6b6bd155aa | |||
| 9c91b1bca5 | |||
| 1a5c0e5b24 | |||
| 981b30e4af | |||
| 30c84d8cbf | |||
| 4c538c54a8 | |||
| ad7a8f1d08 | |||
| f02a07dab4 | |||
| c61b0fc1e1 | |||
| fed7dfcb73 | |||
| 0d69c811ab | |||
| 83274add22 | |||
| 7497d1b6d4 | |||
| 239bc144e3 | |||
| 1ece64abe1 | |||
| 915783699b | |||
| 43f6bd41c9 | |||
| 98c017dd56 | |||
| 811ed3251b | |||
| 665b0f1484 | |||
| 9e26d845da | |||
| 6ddf20f5ce | |||
| 27ed0710cc | |||
| cb87c9f345 | |||
| e1e147c8f0 | |||
| b37d889de9 | |||
| b61c9bfc5e | |||
| e963788a81 | |||
| 3ef4798e09 | |||
| 21730102ae | |||
| b1ae05152e | |||
| cc87f01e2f | |||
| 85dfa1b078 | |||
| fdff54e11e | |||
| 0894f38660 | |||
| f643d8ef25 | |||
| e437284980 | |||
| f6e0d330ac | |||
| 890cbf0f36 | |||
| 36cf2ea2e8 | |||
| a8f7bd0280 | |||
| aa6517046d | |||
| 42e4d8c7ba | |||
| 3d1da38cbc | |||
| 5ae8490999 | |||
| 715675b2f1 | |||
| 0d7198a26c | |||
| d8b7ce6d9b | |||
| d032ca31e3 | |||
| 67b49c0585 | |||
| c23242f18e | |||
| c23f7a3ee2 | |||
| 7e3e957649 | |||
| b8f304dfd3 | |||
| e895ac9245 | |||
| 77579a71e8 | |||
| cc7e13cdbf | |||
| 5df3886e42 | |||
| cc179a05d0 | |||
| ec5f4f2778 | |||
| 084c95f0e5 | |||
| 3b78cfe0fd | |||
| 160ce3338d | |||
| d425cfe1aa | |||
| 6ff286f9b4 | |||
| b930461434 | |||
| ee6bb24506 | |||
| b69124c89f | |||
| f089e4a1ce | |||
| 7dedb5c076 | |||
| 3276c9a84c | |||
| 04ef2ea3b6 | |||
| 04a2f27a75 | |||
| d962f59884 | |||
| fd3bd4567a | |||
| 29e7a5ecdb | |||
| 4956b0d89d | |||
| 3bc54a4e16 | |||
| 29ecd602ec | |||
| 1425dec564 | |||
| 2bb1c0c999 | |||
| 97f3daae70 | |||
| c53a7ef6fe | |||
| b97fc16ad9 | |||
| eaac12ddc8 | |||
| 183be5da0e | |||
| ace0953c87 | |||
| 1fd7e7833d | |||
| aa5801d73b | |||
| d1ea8081e4 | |||
| 49467c906d | |||
| 79bd575aca | |||
| e533a0e405 | |||
| 94b597d29a | |||
| 504fefff94 | |||
| ff794a3638 | |||
| efb9a34cb8 | |||
| a93291b38f | |||
| dfc9eab9d3 | |||
| 3c74b0b1ef | |||
| 9b981fcea8 | |||
| 9d3a189d77 | |||
| 01c0175e8f | |||
| d7e5e2f381 | |||
| c27de8b9a5 | |||
| c3a55f8b69 | |||
| 78b65a799e | |||
| 6a30cee611 | |||
| bc19e3a6ff | |||
| 5a8f2fa2be | |||
| 81168c27c6 | |||
| a606626053 | |||
| adeb57864b | |||
| 747f1a6fae | |||
| 3ac9c23573 | |||
| 5ad9c0e77a | |||
| ba5ba2f1d6 | |||
| 4902b5f351 | |||
| 166fcda193 | |||
| 83560bc775 | |||
| 4ffb00c9f5 | |||
| fbac41a774 | |||
| c837ab8693 | |||
| 1cc321ddff | |||
| 7861cffb91 | |||
| 82a472f368 | |||
| cfe59774e7 | |||
| 1098475473 | |||
| 4546e795ef | |||
| bb0aba586b | |||
| 204b995e6c | |||
| 321b7b4cee | |||
| 413377fbb9 | |||
| e2e821881c | |||
| 51712ed2a8 | |||
| 27de7ddbf8 | |||
| bb700f3a3d | |||
| 563268558b | |||
| 56744cec7b | |||
| 87696a2e6c | |||
| 79f1c20f8a | |||
| 4e5638df36 | |||
| 71349f35e4 | |||
| 2cb06bb4bb | |||
| 5e1769b81f | |||
| e344f28265 | |||
| 2297d6b85b | |||
| baaecdbd8c | |||
| 31d8af642d | |||
| 27c67ec202 | |||
| 4833a29e57 | |||
| 4a2f3e0372 | |||
| f3eeff4ec8 | |||
| 221e03ecfa | |||
| 392a9c6f53 | |||
| 145d12b2c8 | |||
| 0c5033ff79 | |||
| 5f46f54dfd | |||
| d4819b13eb | |||
| 9dd9be3b8c | |||
| dd38809866 | |||
| c414725f12 | |||
| d3c8a350a4 | |||
| e04b748b91 | |||
| 1eee8c4725 | |||
| 2b7a4b170c | |||
| 7c0bf4f137 | |||
| 54bae43d2e | |||
| 25be1155a6 | |||
| 4905d61a1a | |||
| ff0147bebb | |||
| 7fe4889b6e | |||
| 3c9b1b1833 | |||
| 2a46c873b8 | |||
| 6ed09324ad | |||
| d1f9c10790 | |||
| 5d041b2fd3 | |||
| 5cea0fa87b | |||
| 6f140eef29 | |||
| e5850adfd7 | |||
| 6921833ce2 | |||
| 57b9accd97 | |||
| de94f5b233 | |||
| b5519a73fb | |||
| c5d8c2c355 | |||
| c5b02a426c | |||
| 4cae910b68 | |||
| b664fccce2 | |||
| 21672f99d1 | |||
| c269e46892 | |||
| 8534e8cf5b | |||
| 94bf1c2484 | |||
| b3b30470fc | |||
| 41d91e75fc | |||
| a97a91b844 | |||
| f1c577ab76 | |||
| 17a9fe5024 | |||
| d74a76dee3 | |||
| c01201b88e | |||
| 833bdf878a | |||
| 891990b2f1 | |||
| e9ab7029c9 | |||
| 6f681dba09 | |||
| b3edff947d | |||
| ce6d80d601 | |||
| a80a2866de | |||
| 02c2221970 | |||
| d35bd6e75b | |||
| f3a2f98864 | |||
| a3a312e3db | |||
| f5cb5c4516 | |||
| d458a28337 | |||
| a102a780f8 | |||
| 4dbbc32108 | |||
| b6aedb43ee | |||
| ec50dcbbd9 | |||
| bcc983f11f | |||
| 809651054e | |||
| 2e965ceb9e | |||
| e35f942964 | |||
| 40e6fce281 | |||
| 2139865876 | |||
| c3cda05d98 | |||
| 548f3db33d | |||
| a76e9ed98b | |||
| c0ef41a9bb | |||
| f6e5d9675a | |||
| ef028659d8 | |||
| 40f39e918d | |||
| 2ec3ee2734 | |||
| bc29b89a16 | |||
| e21853286e | |||
| c012b8c4a5 | |||
| 48f6c28556 | |||
| 0c1502f801 | |||
| fec20ed381 | |||
| 252c147dcf | |||
| 453d474104 | |||
| 84cf4a9b66 | |||
| fb016bebde | |||
| 8f6a738481 | |||
| b07f958577 | |||
| 8da0fde52a | |||
| 39be16cb63 | |||
| 59d0c0def4 | |||
| 79c03db9a0 | |||
| 0c77823020 | |||
| deed7e0022 | |||
| 99db8c7335 | |||
| 9fe2aa9ed5 | |||
| 4c80dc256b | |||
| cafe9e9c11 | |||
| 27ff4e63b6 | |||
| 8020714e07 | |||
| dbd825ba4b | |||
| fee6cf29eb | |||
| 56287d8e7a | |||
| 45504eaf95 | |||
| b8a9b1150a | |||
| 8bd0e43f58 | |||
| 2c83e9e83c | |||
| 53c9ca10a7 | |||
| 75fbdac42e | |||
| 09d54546ca | |||
| b62fece3d0 | |||
| 284a2b7f64 | |||
| 9c873ccbbd | |||
| 5f72f90031 | |||
| 93cf3c69b8 | |||
| 88f856cbc7 | |||
| 2d5796d161 | |||
| 1d20dc9fcb | |||
| 49502235b5 | |||
| 6e9d71fcf8 | |||
| 27c7e33773 | |||
| 3012619049 | |||
| d6801966c4 | |||
| 518e29118c | |||
| acf4f3fbf0 | |||
| 8378030c70 | |||
| dc7140d486 | |||
| e3771a1c53 | |||
| 2e9ac00a42 | |||
| 4b8b3acd39 | |||
| 8703798ca0 | |||
| 47ac438844 | |||
| bd3aa28523 | |||
| 68d0ae4002 | |||
| 6991039640 | |||
| 00611ef9dc | |||
| 3c50e4768a | |||
| 63dc9834be | |||
| f042e42633 | |||
| 39b80a2e7e | |||
| fb6e948358 | |||
| 181b0845bf | |||
| b2a82dcfe5 | |||
| ed1c05dec9 | |||
| cd73aef0c9 | |||
| ed522ec024 | |||
| 16998d1e16 | |||
| 11421d2d32 | |||
| 1af708aaea | |||
| fbb82fa759 | |||
| a9f977c3b4 | |||
| 5669e22548 | |||
| da4bb9b83d | |||
| c2cbaf0937 | |||
| d81dce536c | |||
| 8e1e2c5b85 | |||
| 959d5e6822 | |||
| 036a0b4cb3 | |||
| c038f14374 | |||
| 343cf91643 | |||
| 4fe70a4c46 | |||
| 59f7200512 | |||
| 0335e709c2 | |||
| a7bb5ac21b | |||
| 99655cab33 | |||
| 348e574154 | |||
| f35dee8643 | |||
| 168412c2e7 | |||
| b9832542fb | |||
| 316545b253 | |||
| 348a57a0d8 | |||
| a3f5654816 | |||
| 8207afe806 | |||
| e15b8f8092 | |||
| e6c99028d6 | |||
| 2e691d7c26 | |||
| 6c87812780 | |||
| 798a3632cf | |||
| aa1d0aabd2 | |||
| f348e691fa | |||
| 0dfda83e45 | |||
| 56044fa3f7 | |||
| 4c69fd4f60 | |||
| 92e3f7a6a3 | |||
| 76d0618d6e | |||
| 80c3a99eb1 | |||
| 91e3a3237b | |||
| 8c8c5a5826 | |||
| b9370955d6 | |||
| 2761e728f7 | |||
| f418bf4f63 | |||
| 3d046e4369 | |||
| b6eb6f2d70 | |||
| 45ce3e26c1 | |||
| ae91cedf76 | |||
| b2a6b484b5 | |||
| 95c4fa56cc | |||
| e8c56afa8e | |||
| ddc3b1f6c2 | |||
| d33d886574 | |||
| 0487980d2f | |||
| e68257d6c9 | |||
| ea0bbab680 | |||
| 5d4a8136c5 | |||
| c98d851cd2 | |||
| 42fa89db7a | |||
| 1a70acc6f2 | |||
| ee0a287112 | |||
| cf16a66c63 | |||
| 4544b17c94 | |||
| 8119c9da51 | |||
| baf4d75c01 | |||
| ac9eff0fcc | |||
| dc57bd92ff | |||
| 3c56a2c868 | |||
| 2d2ab10a24 | |||
| ac906c9994 | |||
| 480406d579 | |||
| 47efb644b7 | |||
| fd0e519e41 | |||
| 0c8bb990d0 | |||
| bd7139827b | |||
| 4f648aff52 | |||
| 3feb45dc01 | |||
| 0489dc7c33 | |||
| a30843cff9 | |||
| 3a34a0eb40 | |||
| e3f82e136a | |||
| 8a7df4ba9f | |||
| e86d1a4c7a | |||
| 5b9d0b60a1 | |||
| 7eff2f0c49 | |||
| 97236bb01d | |||
| 9c6aa12f48 | |||
| 96ccb03eea | |||
| 55f55820c5 | |||
| 955839d513 | |||
| a650e628e5 | |||
| 54142b73fb | |||
| 55e0d2695d | |||
| 2f90ab15dc | |||
| fd3fc66bfc | |||
| a352a94d8a | |||
| 410b81f46f | |||
| aa3711c5cc | |||
| d6b1f97a04 | |||
| b4e8e57a22 | |||
| 9644e6195c | |||
| 764e0c7607 | |||
| 97d640dd40 | |||
| d2915b5b05 | |||
| f274f6fd18 | |||
| f507ac2569 | |||
| 208cbd6d89 | |||
| cd2aa2902a | |||
| fa2d7fa3da | |||
| 7463767781 | |||
| 958bc864c9 | |||
| 4484668750 | |||
| d5dea4b87f | |||
| 0fdef6a0a2 | |||
| bd71b6bad8 | |||
| 9b7887b279 | |||
| 3960e43872 | |||
| 201c8f9ec9 | |||
| 8c8374a08c | |||
| 467595afc9 | |||
| acb54f098c | |||
| 5755d13460 | |||
| 2c3500315d | |||
| 47ea60c0cd | |||
| 18b18c1396 | |||
| ff227de5fa | |||
| 6799692811 | |||
| c6173f7f6f | |||
| d0e4dabc44 | |||
| f815dae300 | |||
| b3bd6bb39e | |||
| 71df6409c2 | |||
| e4f9a1e0cf | |||
| ca6a05e393 | |||
| c0d26164dc | |||
| 76fe2a1ba9 | |||
| 8cbdb54402 | |||
| 764ef80a62 | |||
| 0c37d93c01 | |||
| c57a5128e5 | |||
| 6cf4eba20a | |||
| 6825d728c2 | |||
| 6d3091b2a2 | |||
| 61473877a4 | |||
| 52989c8f5c | |||
| b64ba2ef16 | |||
| 461ae99dd8 | |||
| 8681df6f02 | |||
| ba081ee442 | |||
| cf90d05115 | |||
| 658c6554af | |||
| 94d9d608f7 | |||
| 015b50be5f | |||
| 85970f8c96 | |||
| 1740ab0bbe | |||
| 9d2b5593a2 | |||
| 881d62d69d | |||
| 935129f0a5 | |||
| 1a9bdc5e6d | |||
| 1f565bca10 | |||
| da089197a3 | |||
| 2df8f41d6c | |||
| 4e4f0d4c97 | |||
| eaad22c0a1 | |||
| 63e8553a09 | |||
| b65828416f | |||
| 48dc8033f5 | |||
| 2d838b69fd | |||
| 6c529a6908 | |||
| 9baefec541 | |||
| 327d66bb80 | |||
| 760a4dfcb9 | |||
| ceb8cdd337 | |||
| 570c754eec | |||
| 8ed75d1d21 | |||
| 54710b8221 | |||
| ff794033e1 | |||
| f0f486da9e | |||
| aedcfd1d24 | |||
| 44e738acf5 | |||
| 701b45c286 | |||
| 72fe687d82 | |||
| 632cd66b57 | |||
| 20530c000e | |||
| 8824786fb4 | |||
| bdeb4a4efe | |||
| cf455fc19b | |||
| 1bcddadb7a | |||
| 6dc28f11e0 | |||
| 8ad601fcc0 | |||
| f400844a3d | |||
| 560096878f | |||
| 0938f5ab71 | |||
| 06193d27c0 | |||
| eb18857ecc | |||
| 9a280e99ad | |||
| c7ca20b45a | |||
| 60e64a3646 | |||
| d60f89976e | |||
| 41e05ddf9c | |||
| 5a34f16dcf | |||
| 769ca4e26d | |||
| b6e62b08e4 | |||
| effe5b32fd | |||
| 9e38137e76 | |||
| 57c2e89f00 | |||
| 914a0bf514 | |||
| 210f5eabc9 | |||
| 5f5c91a8ff | |||
| 05c7121c8a | |||
| 551a8e9588 | |||
| 75fbdb653a | |||
| bdfe75cff3 | |||
| bcd845fd59 | |||
| f1e71ecb78 | |||
| 0aa4c8af6f | |||
| 8fe5507ff8 | |||
| a950b80d5a | |||
| ed3bb6429b | |||
| 1e88491ca1 | |||
| 4aed647865 | |||
| 74ab7aaa3d | |||
| dcf2055851 | |||
| 6b6ad05e3a | |||
| 734a4b5e00 | |||
| da70fac0b6 | |||
| 5f4a364095 | |||
| 95a8867527 | |||
| 7cb1301e80 | |||
| e6e070d89e | |||
| ba2bcaba07 | |||
| 3d6ecba4f5 | |||
| 864f82ba11 | |||
| f671c992e1 | |||
| 86220694ce | |||
| 77f31177c8 | |||
| 33ff91aea8 | |||
| a4151800f1 | |||
| 932f24c966 | |||
| 0c0bce9755 | |||
| f07508073f | |||
| 2c9cade70a | |||
| e06cc1bd2d | |||
| 36e33a4c10 | |||
| 7f668c1653 | |||
| b464fa98df | |||
| 23491f1e8c | |||
| 2b90a2eed2 | |||
| 13b9d15d8f | |||
| a053504bb8 | |||
| d7d7a84bd5 | |||
| 990463fbea | |||
| dcdd4aec85 | |||
| 0d9a8ba6f7 | |||
| 179da2ac05 | |||
| 4848739b6e | |||
| 46da285831 | |||
| 71a6a36a54 | |||
| c8ca9ef7ab | |||
| 5af2fff9ca | |||
| edbaf3ac82 | |||
| 337c9bc01e | |||
| cd84674ae0 | |||
| a196dce1fa | |||
| f60ea43f29 | |||
| 76f547a726 | |||
| dffe5e0819 | |||
| b9633bbcd6 | |||
| 46efe2b8dd | |||
| fb9ef0c547 | |||
| d52cd2b17c | |||
| cefa80f317 | |||
| cc1dd682e8 | |||
| bdd984a887 | |||
| 2d3dffe5fc | |||
| 65f31a0b38 | |||
| 4a1a6c5933 | |||
| 7e1fd99c37 | |||
| 8fe8209580 | |||
| 264a050360 | |||
| 3623104e3b | |||
| 191ff1abec | |||
| 3bb86493cc | |||
| d1d3151e1e | |||
| f9dc9ebdb3 | |||
| 3b478bcc2d | |||
| 77bb78c381 | |||
| cafa97f502 | |||
| 0d858493d5 | |||
| 99fb07c6b3 | |||
| eaad971c0a | |||
| 377abd87fd | |||
| af71176296 | |||
| 69737177ef | |||
| efae1222c1 | |||
| 3caea1a903 | |||
| a43478d627 | |||
| ed2c3f43c7 | |||
| 84c9846f7b | |||
| fcfd816cec | |||
| 2e3977e59c | |||
| 3c68430336 | |||
| 43afb86fa8 | |||
| 194ccbdbb4 | |||
| 7139e230cf | |||
| 120d3b9f54 | |||
| 712460a040 | |||
| be5594f1c9 | |||
| 0a885117db | |||
| 5b73654544 | |||
| 1485b78b7b | |||
| bfec57172a | |||
| 9f8559c12d | |||
| 83dde12ca9 | |||
| d17888db4e | |||
| 096529af96 | |||
| 8a56b22635 | |||
| dcdd353981 | |||
| 258564208b | |||
| e2e8222005 | |||
| 75f2826805 | |||
| 730af4f2ee | |||
| e5737ebd9d | |||
| 7f24904164 | |||
| 9ff7198602 | |||
| 6d56967a0f | |||
| 584118805a | |||
| 68b3f01082 | |||
| 77a82cb84b | |||
| 844b19495d | |||
| b8b721f2bd | |||
| 4f93d48ac6 | |||
| 02d1bf5a2c | |||
| fb3606c2b7 | |||
| a5bc2cd48f | |||
| 72151ac6a3 | |||
| e2c8b3bf02 | |||
| 06dd641274 | |||
| 7d9bf01d27 | |||
| b9553e0a05 | |||
| 993dcaf235 | |||
| 8d7c39bac4 | |||
| 80933ab571 | |||
| b5b30c8119 | |||
| bca06129d9 | |||
| a136b86d81 | |||
| 8d555d8ae7 | |||
| c22e61add2 | |||
| 2c83f1ce57 | |||
| f2750de153 | |||
| e0934f11d6 | |||
| 422924026a | |||
| 332e22e534 | |||
| c7bf30e18e | |||
| 5ade5176c0 | |||
| f9e4fafe9f | |||
| 201f2ef1f0 | |||
| 32af4fdcca | |||
| d254b4cc39 | |||
| d0ad4e05bf | |||
| c75854cb7b | |||
| 8cc71913b3 | |||
| 99abe6bcd2 | |||
| f5ad7a49ce | |||
| e42ecf3c99 | |||
| b58bf9dc17 | |||
| 745c8aaf3e | |||
| 0ca73bf80b | |||
| fd76cabd01 | |||
| fcf9300a49 | |||
| 649b66ba1a | |||
| b5d73a0861 | |||
| 1453996ccb | |||
| 5bf9b97d70 | |||
| 5c1e46f5a6 | |||
| c2665cbae8 | |||
| 3934248a6b | |||
| 7ae3bb5601 | |||
| 9890d4f3bc | |||
| 5b47fc16d9 | |||
| 344770a0a4 | |||
| fc11cacd24 | |||
| 737ebdd0c6 | |||
| d06dddfa24 | |||
| 710d631ffe | |||
| 7d9a845ca0 | |||
| cc6e5ffb97 | |||
| 8d29cb7488 | |||
| 5c588ea01a | |||
| dade9935da | |||
| 34cd3aaaca | |||
| 78d3f338fb | |||
| d801c5911e | |||
| 003743c074 | |||
| 4cef39d3b1 | |||
| 83f0df32d7 | |||
| 24f269191c | |||
| 94a0d5a0a4 | |||
| c0fbf4dd0c | |||
| 37b6161075 | |||
| c9b792c370 | |||
| 2103d547a1 | |||
| 3918e220d2 | |||
| c3eaaed43b | |||
| e0bf648076 | |||
| bb298164e4 | |||
| 898694b9be | |||
| f0f9ac92e6 | |||
| ea0229a8ab | |||
| 66fc7cd91d | |||
| c11d4f01b1 | |||
| a8f498f292 | |||
| 6854e2275f | |||
| 6662e79ac5 | |||
| 9e77430634 | |||
| b8e070824a | |||
| 304d4293f3 | |||
| a03e7f5b53 | |||
| ea57c8cad4 | |||
| 280802cf74 | |||
| fbce01d846 | |||
| 591b60c336 | |||
| 78ef870d91 | |||
| bc19d82aed | |||
| 79b41e1056 | |||
| 805f03d231 | |||
| 62acc1081f | |||
| 257a2c2d9f | |||
| ed9b05cdf9 | |||
| 2cc6fbd643 | |||
| bdfc260dd2 | |||
| 7ad65956c9 | |||
| b3dc60b7ca | |||
| bed08109fa | |||
| 06cedec090 | |||
| 1d2c468d03 | |||
| e84616f5f5 | |||
| caa9a90476 | |||
| 62be683dd8 | |||
| ffa63b3f82 | |||
| c5a7788394 | |||
| 99c42ff2c1 | |||
| fd2b7bb917 | |||
| 922a494df0 | |||
| c478ec0095 | |||
| 3abbe17910 | |||
| 349076599f | |||
| 92d299507f | |||
| 6f2d61e918 | |||
| ed13babf6a | |||
| 80db82eb93 | |||
| 8d20334d6e | |||
| 03a95ad018 | |||
| aa59cc8af0 | |||
| 80d63c2c89 | |||
| 03a4acd72b | |||
| 53118cf660 | |||
| 16b1baf81e | |||
| 960e0d0965 | |||
| 8f41222e43 | |||
| e7bc447166 | |||
| 1736359615 | |||
| 58784b1e22 | |||
| 07f2bfd279 | |||
| 6d62db2890 | |||
| a1b23c4aab | |||
| e272a096da | |||
| b8ca24c5bf | |||
| a05d09f0de | |||
| 1807a79c4f | |||
| 77f6826af9 | |||
| 7e39eedf35 | |||
| 0b4b48ceae | |||
| dad931e898 | |||
| 2e387730cb | |||
| c9b6775793 | |||
| a6eaf30c2b | |||
| 6f91d199d8 | |||
| 7ea486307a | |||
| 37d254c827 | |||
| b4014eb317 | |||
| c7824fa184 | |||
| 13c5bd45f9 | |||
| 465d102bd0 | |||
| 93007cd56c | |||
| 8367576dc8 | |||
| dbc06145b3 | |||
| 4efcf0e7c8 | |||
| 0a4bbc1106 | |||
| b08c1f6699 | |||
| 6828b905ef | |||
| f72b405f6d | |||
| 27ae99864c | |||
| 82ba15ba5a | |||
| af01db7bc9 | |||
| 6ec0a65d0c | |||
| c32ccfc9ed | |||
| ef818388c8 | |||
| f5aa45a3e1 | |||
| b7a047a743 | |||
| 05ec985453 | |||
| 88ed9c3e79 | |||
| 3fb03c8dfe | |||
| ff304027cd | |||
| 3140d46c94 | |||
| 9d476af384 | |||
| 0d380672f3 | |||
| e2fb8dca5b | |||
| eaba4c90c5 | |||
| b4ca7373f3 | |||
| 905c068ed5 | |||
| 02886dd420 | |||
| 5bf7754d6c | |||
| 7a0a3055c4 | |||
| bf73efb3b4 | |||
| b4da212158 | |||
| 4a04d42600 | |||
| 42bbfbe538 | |||
| 31ec2430c4 | |||
| f0b56c9f1d | |||
| 6f9f01c991 | |||
| b822ccb19d | |||
| dcb11671f3 | |||
| 282599d36f | |||
| f11acdc68f | |||
| 971e127cfd | |||
| 9b2c59d529 | |||
| 14dc049a66 | |||
| d3d0e7c615 | |||
| 89423ccb8b | |||
| 746f31f70c | |||
| 3aa9eab2bd | |||
| 1bcc8fed5e | |||
| 1213a030e3 | |||
| 3b2344b477 | |||
| c53b0fe2d4 | |||
| 0a92269456 | |||
| 1cb8906893 | |||
| f76579fe5e | |||
| db05ff5e98 | |||
| a05d6979ec | |||
| be40d17172 | |||
| 9e11339979 | |||
| a56129afe0 | |||
| 8933ea999c | |||
| ae3b8f6494 | |||
| 33487ee03f | |||
| 58ecae1162 | |||
| 8777da10e4 | |||
| 4ea971c1b9 | |||
| 0fa4759c3a | |||
| fe7b9730d3 | |||
| 040f6a8393 | |||
| b17575b197 | |||
| dee4f757e7 | |||
| 5ae08d02ab | |||
| b83aec4965 | |||
| 68c4837780 | |||
| 46fe5e99fe | |||
| 9ffb537cfb | |||
| cc7e6f852d | |||
| f83e99c62c | |||
| bc8b8e7982 | |||
| 3b761ca2a8 | |||
| edc21f9830 | |||
| d025ec4dff | |||
| ab334a393f | |||
| 2a9044086f | |||
| c3038ec60c | |||
| 0fa827ba00 | |||
| 26002fc372 | |||
| 59acba8c08 | |||
| 4c5ee45fdb | |||
| 6062120d0d | |||
| cd3ffb2126 | |||
| a8c11cc445 | |||
| fcb89aac6b | |||
| 3704d8f6e7 | |||
| 8c75d172c5 | |||
| 5687302081 | |||
| 9020b16a9a | |||
| d5462df4da | |||
| 9021ca31af | |||
| 83cb8b7f03 | |||
| baf2658eb8 | |||
| 3f19b05d28 | |||
| 5e6be1f830 | |||
| 14d1a3038f | |||
| 6a15e2e587 | |||
| 0679805728 | |||
| 62a03419a5 | |||
| 81f6b0767e | |||
| c7ca5c749b | |||
| 1daac09b7c | |||
| 4d3dd68ac0 | |||
| de9e4a6270 | |||
| bf8f347245 | |||
| a70d09ac7a | |||
| 919b344da4 | |||
| 44f013a678 | |||
| 742191111b | |||
| 8dc0031475 | |||
| 19fb90a300 | |||
| 0c3960d8d9 | |||
| 7e770b9b5d | |||
| b95f391f02 | |||
| 4ed861ffce | |||
| 2c0b3be900 | |||
| 145e163670 | |||
| d5497843eb | |||
| 3799f6fe49 | |||
| 07678300da | |||
| 881c8f30ef | |||
| 5d02fbbdea | |||
| 4c969f5524 | |||
| f361e178f1 | |||
| edc77be8ef | |||
| 55ba5801af | |||
| 6d9c35f7cc | |||
| 320b82dc18 | |||
| d22d695312 | |||
| ba5eeeba07 | |||
| 0b5b2b6243 |
@@ -0,0 +1,4 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: [donaldzou]
|
||||||
|
patreon: DonaldDonnyZou
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe The Problem**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**Expected Error / Traceback**
|
||||||
|
```
|
||||||
|
Please provide the error traceback here
|
||||||
|
```
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Please provide how you run the dashboard
|
||||||
|
|
||||||
|
**OS Information:**
|
||||||
|
- OS: [e.g. Ubuntu 18.02]
|
||||||
|
- Python Version: [e.g v3.7]
|
||||||
|
|
||||||
|
**Sample of your `.conf` file**
|
||||||
|
```
|
||||||
|
Please provide a sample of your configuration file that you are having problem with. You can replace your public key and private key to ABCD...
|
||||||
|
```
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ main ]
|
||||||
|
schedule:
|
||||||
|
- cron: '30 5 * * 4'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'javascript', 'python' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
name: Docker Scan and Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *" # Daily at midnight UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
trigger-build:
|
||||||
|
description: 'Trigger a manual build and push'
|
||||||
|
default: 'true'
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOCKER_IMAGE: donaldzou/wgdashboard
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker_build_analyze:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build and export (multi-arch)
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.DOCKER_IMAGE }}:latest
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||||
|
|
||||||
|
- name: Docker Scout
|
||||||
|
id: docker-scout
|
||||||
|
uses: docker/scout-action@v1
|
||||||
|
with:
|
||||||
|
command: cves
|
||||||
|
image: ${{ env.DOCKER_IMAGE }}:latest
|
||||||
|
only-severities: critical,high,medium,low,unspecified
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
name: Qodana
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: # Specify your branches here
|
||||||
|
- main # The 'main' branch
|
||||||
|
- v4.2-dev
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
qodana:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
|
||||||
|
fetch-depth: 0 # a full history is required for pull request analysis
|
||||||
|
- name: 'Qodana Scan'
|
||||||
|
uses: JetBrains/qodana-action@v2024.3
|
||||||
|
with:
|
||||||
|
pr-mode: false
|
||||||
|
env:
|
||||||
|
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN_2090978292 }}
|
||||||
|
QODANA_ENDPOINT: 'https://qodana.cloud'
|
||||||
+51
-1
@@ -1,2 +1,52 @@
|
|||||||
src/.vscode/sftp.json
|
.vscode
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
src/db
|
||||||
|
__pycache__
|
||||||
|
src/test.py
|
||||||
|
*.db
|
||||||
|
src/wg-dashboard.ini
|
||||||
|
src/static/pic.xd
|
||||||
|
*.conf
|
||||||
|
private_key.txt
|
||||||
|
public_key.txt
|
||||||
|
venv/**
|
||||||
|
log/**
|
||||||
|
release/*
|
||||||
|
src/db/wgdashboard.db
|
||||||
|
.jshintrc
|
||||||
|
node_modules/**
|
||||||
|
*/proxy.js
|
||||||
|
src/static/app/proxy.js
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
.vite/*
|
||||||
|
|
||||||
|
|||||||
Vendored
-9
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "My Server",
|
|
||||||
"host": "38.106.21.18",
|
|
||||||
"protocol": "sftp",
|
|
||||||
"port": 22,
|
|
||||||
"username": "root",
|
|
||||||
"remotePath": "/root/wireguard-dashboard",
|
|
||||||
"uploadOnSave": true
|
|
||||||
}
|
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
FROM golang:1.23 AS compiler
|
||||||
|
WORKDIR /go
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
git make bash build-essential \
|
||||||
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-tools.git && \
|
||||||
|
git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-go.git
|
||||||
|
RUN cd /go/amneziawg-tools/src && make
|
||||||
|
|
||||||
|
RUN cd /go/amneziawg-go && \
|
||||||
|
go get -u ./... && \
|
||||||
|
go mod tidy && \
|
||||||
|
make && \
|
||||||
|
chmod +x /go/amneziawg-go/amneziawg-go /go/amneziawg-tools/src/wg /go/amneziawg-tools/src/wg-quick/linux.bash
|
||||||
|
RUN echo "DONE AmneziaWG"
|
||||||
|
|
||||||
|
### INTERMEDIATE STAGE
|
||||||
|
FROM scratch AS bins
|
||||||
|
COPY --from=compiler /go/amneziawg-go/amneziawg-go /amneziawg-go
|
||||||
|
COPY --from=compiler /go/amneziawg-tools/src/wg /awg
|
||||||
|
COPY --from=compiler /go/amneziawg-tools/src/wg-quick/linux.bash /awg-quick
|
||||||
|
|
||||||
|
# FINAL STAGE
|
||||||
|
FROM alpine:latest
|
||||||
|
LABEL maintainer="dselen@nerthus.nl"
|
||||||
|
|
||||||
|
COPY --from=bins /amneziawg-go /usr/bin/amneziawg-go
|
||||||
|
COPY --from=bins /awg /usr/bin/awg
|
||||||
|
COPY --from=bins /awg-quick /usr/bin/awg-quick
|
||||||
|
|
||||||
|
# Declaring environment variables, change Peernet to an address you like, standard is a 24 bit subnet.
|
||||||
|
ARG wg_net="10.0.0.1"
|
||||||
|
ARG wg_port="51820"
|
||||||
|
|
||||||
|
# Following ENV variables are changable on container runtime because /entrypoint.sh handles that. See compose.yaml for more info.
|
||||||
|
ENV TZ="Europe/Amsterdam"
|
||||||
|
ENV global_dns="1.1.1.1"
|
||||||
|
ENV isolate="none"
|
||||||
|
ENV public_ip=""
|
||||||
|
ENV wgd_port="10086"
|
||||||
|
|
||||||
|
# Doing package management operations, such as upgrading
|
||||||
|
RUN apk update \
|
||||||
|
&& apk add --no-cache bash git tzdata \
|
||||||
|
iptables ip6tables openrc curl wireguard-tools \
|
||||||
|
sudo py3-psutil py3-bcrypt \
|
||||||
|
&& apk upgrade
|
||||||
|
|
||||||
|
# Using WGDASH -- like wg_net functionally as a ARG command. But it is needed in entrypoint.sh so it needs to be exported as environment variable.
|
||||||
|
ENV WGDASH=/opt/wgdashboard
|
||||||
|
|
||||||
|
# Removing the Linux Image package to preserve space on the image, for this reason also deleting apt lists, to be able to install packages: run apt update.
|
||||||
|
|
||||||
|
# Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example.
|
||||||
|
RUN mkdir /data \
|
||||||
|
&& mkdir /configs \
|
||||||
|
&& mkdir -p ${WGDASH}/src \
|
||||||
|
&& mkdir -p /etc/amnezia/amneziawg
|
||||||
|
COPY ./src ${WGDASH}/src
|
||||||
|
|
||||||
|
# Generate basic WireGuard interface. Echoing the WireGuard interface config for readability, adjust if you want it for efficiency.
|
||||||
|
# Also setting the pipefail option, verbose: https://github.com/hadolint/hadolint/wiki/DL4006.
|
||||||
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
RUN out_adapt=$(ip -o -4 route show to default | awk '{print $NF}') \
|
||||||
|
&& echo -e "[Interface]\n\
|
||||||
|
Address = ${wg_net}/24\n\
|
||||||
|
PrivateKey =\n\
|
||||||
|
PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE\n\
|
||||||
|
PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP\n\
|
||||||
|
PreDown = iptables -t nat -D POSTROUTING -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE\n\
|
||||||
|
PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP\n\
|
||||||
|
ListenPort = ${wg_port}\n\
|
||||||
|
SaveConfig = true\n\
|
||||||
|
DNS = ${global_dns}" > /configs/wg0.conf.template \
|
||||||
|
&& chmod 600 /configs/wg0.conf.template
|
||||||
|
|
||||||
|
# Defining a way for Docker to check the health of the container. In this case: checking the gunicorn process.
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1
|
||||||
|
|
||||||
|
# Copy the basic entrypoint.sh script.
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
# Exposing the default WireGuard Dashboard port for web access.
|
||||||
|
EXPOSE 10086
|
||||||
|
WORKDIR $WGDASH
|
||||||
|
|
||||||
|
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||||
@@ -1,19 +1,77 @@
|
|||||||
# Wireguard Dashboard
|
> [!TIP]
|
||||||
## Intro
|
> 🎉 I'm excited to announce that WGDashboard is officially listed on DigitalOcean's Marketplace! For more information, please visit [Host WGDashboard & WireGuard with DigitalOcean](https://donaldzou.dev/WGDashboard-Documentation/host-wgdashboard-wireguard-with-digitalocean.html) for more information!
|
||||||
Monitoring Wireguard is not convinient, need to login into server and type wg show. That's why this platform is being created, to view all configurations in a more straight forward way.
|
|
||||||
## Installation
|
|
||||||
**Requirement:**
|
|
||||||
- Wireguard
|
|
||||||
- Configuration files under **/etc/wireguard**
|
|
||||||
- Python 3.7
|
|
||||||
- Flask
|
|
||||||
|
|
||||||
**Install:**
|
> [!NOTE]
|
||||||
1. `git clone https://github.com/donaldzou/Wireguard-Dashboard.git`
|
> **Help Wanted 🎉**: Localizing WGDashboard to other languages! If you're willing to help, please visit https://github.com/donaldzou/WGDashboard/issues/397. Many thanks!
|
||||||
2. `cd Wireguard-Dashboard`
|
|
||||||
3. `python3 dashboard.py`
|
|
||||||
4. Access your server! e.g (http://your_server_ip:10086)
|
|
||||||
|
|
||||||
## Example
|

|
||||||

|
|
||||||

|
|
||||||
|
<p align="center">
|
||||||
|
<img alt="WGDashboard" src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Logos/Logo-2-Rounded-512x512.png" width="128">
|
||||||
|
</p>
|
||||||
|
<h1 align="center">WGDashboard</h1>
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://forthebadge.com/images/badges/made-with-python.svg">
|
||||||
|
<img src="https://forthebadge.com/images/badges/made-with-javascript.svg">
|
||||||
|
<img src="https://forthebadge.com/images/badges/license-mit.svg">
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/donaldzou/wireguard-dashboard/releases/latest"><img src="https://img.shields.io/github/v/release/donaldzou/wireguard-dashboard"></a>
|
||||||
|
<a href="https://wakatime.com/badge/github/donaldzou/WGDashboard"><img src="https://wakatime.com/badge/github/donaldzou/WGDashboard.svg" alt="wakatime"></a>
|
||||||
|
<a href="https://hitscounter.dev"><img src="https://hitscounter.dev/api/hit?url=https%3A%2F%2Fgithub.com%2Fdonaldzou%2FWGDashboard&label=Visitor&icon=github&color=%230a58ca"></a>
|
||||||
|
<img src="https://img.shields.io/docker/pulls/donaldzou/wgdashboard?logo=docker&label=Docker%20Image%20Pulls&labelColor=ffffff">
|
||||||
|
</p>
|
||||||
|
<p align="center"><b>This project is supported by</b></p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://m.do.co/c/a84cb9aac585">
|
||||||
|
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p align="center">Monitoring WireGuard is not convenient, in most case, you'll need to login to your server and type <code>wg show</code>. That's why this project is being created, to view and manage all WireGuard configurations in a easy way.</p>
|
||||||
|
<p align="center">With all these awesome features, while keeping it <b>easy to install and use</b></p>
|
||||||
|
|
||||||
|
<p align="center"><b><i>This project is not affiliate to the official WireGuard Project</i></b></p>
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Join our Discord Server for quick help, or you wanna chat about this project!
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a align="center" href="https://discord.gg/72TwzjeuWm"><img src="https://img.shields.io/discord/1276818723637956628?labelColor=ffffff&style=for-the-badge&logo=discord&label=Discord"></a>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
Alternatively, you can also reach out at our Matrix.org Chatroom :)
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://app.element.io/#/room/#wgd:matrix.org">Matrix.org Chatroom</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
# [Official Documentation](https://donaldzou.dev/WGDashboard-Documentations)
|
||||||
|
|
||||||
|
- [💡 Features](https://donaldzou.github.io/WGDashboard-Documentation/features.html)
|
||||||
|
- [📝 Requirements](https://donaldzou.github.io/WGDashboard-Documentation/requirements.html)
|
||||||
|
- [🛠 Install](https://donaldzou.github.io/WGDashboard-Documentation/install.html)
|
||||||
|
- [🪜 Usage](https://donaldzou.github.io/WGDashboard-Documentation/usage.html)
|
||||||
|
- [📖 API Documentation](https://donaldzou.github.io/WGDashboard-Documentation/api-documentation.html)
|
||||||
|
- [And much more...](https://donaldzou.github.io/WGDashboard-Documentation/)
|
||||||
|
|
||||||
|
# Screenshots
|
||||||
|
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/sign-in.png" alt=""/>
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/cross-server.png" alt=""/>
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/index.png" alt=""/>
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/new-configuration.png" alt="" />
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/settings.png" alt="" />
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/light-dark.png" alt="" />
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/configuration.png" alt=""/>
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/add-peers.png" alt="" />
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/ping.png" alt=""/>
|
||||||
|
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/traceroute.png" alt=""/>
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 5.1.x | :white_check_mark: |
|
||||||
|
| 5.0.x | :x: |
|
||||||
|
| 4.0.x | :white_check_mark: |
|
||||||
|
| < 4.0 | :x: |
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
# WGDashboard Docker Explanation:
|
||||||
|
Author: DaanSelen<br>
|
||||||
|
|
||||||
|
This document delves into how the WGDashboard Docker container has been built.<br>
|
||||||
|
Of course there are two stages, one before run-time and one at/after run-time.<br>
|
||||||
|
The `Dockerfile` describes how the container image is made, and the `entrypoint.sh` is executed after running the container. <br>
|
||||||
|
In this example, WireGuard is integrated into the container itself, so it should be a run-and-go/out-of-the-box.<br>
|
||||||
|
For more details on the source-code specific to this Docker image, refer to the source files, they have lots of comments.
|
||||||
|
|
||||||
|
I have tried to embed some new features such as `isolate` and interface startup on container-start (through `enable`). I hope you enjoy!
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/donaldzou/WGDashboard/main/src/static/img/logo.png" alt="WG-Dashboard Logo" title="WG-Dashboard Logo" width="150" height="150" />
|
||||||
|
|
||||||
|
## Getting the container running:
|
||||||
|
|
||||||
|
To get the container running you either pull the image from the repository, `donaldzou/wgdashboard:latest`.<br>
|
||||||
|
From there either use the environment variables describe below as parameters or use the Docker Compose file: `compose.yaml`.<br>
|
||||||
|
Be careful, the default generated WireGuard configuration file uses port 51820/udp. So use this port if you want to use it out of the box.<br>
|
||||||
|
Otherwise edit the configuration file in `/etc/wireguard/wg0.conf`.
|
||||||
|
|
||||||
|
An example of a simple command to get the container running is show below:<br>
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -d \
|
||||||
|
--name wgdashboard \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-e enable=wg0 \
|
||||||
|
-e isolate=wg0 \
|
||||||
|
-p 10086:10086/tcp \
|
||||||
|
-p 51820:51820/udp \
|
||||||
|
--cap-add NET_ADMIN \
|
||||||
|
donaldzou/wgdashboard:latest
|
||||||
|
```
|
||||||
|
<br>
|
||||||
|
If you want to use Compose instead of a raw Docker command, refer to the example in the `compose.yaml` or the one pasted below:
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
wgdashboard:
|
||||||
|
image: donaldzou/wgdashboard:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: wgdashboard
|
||||||
|
environment:
|
||||||
|
#- tz=
|
||||||
|
#- global_dns=
|
||||||
|
#- enable=
|
||||||
|
#- isolate=
|
||||||
|
#- public_ip=
|
||||||
|
ports:
|
||||||
|
- 10086:10086/tcp
|
||||||
|
- 51820:51820/udp
|
||||||
|
volumes:
|
||||||
|
- conf:/etc/wireguard
|
||||||
|
- data:/data
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
conf:
|
||||||
|
data:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to customize the yaml, make sure the core stays the same, but for example volume PATHs (ON THE HOST) can be freely changed.<br>
|
||||||
|
This setup is just generic and will use the Docker volumes.
|
||||||
|
|
||||||
|
## Updating the container:
|
||||||
|
|
||||||
|
Updating is right now in Alpha stage. I have got it to work, testing methods.
|
||||||
|
|
||||||
|
## Working with the container and environment variables:
|
||||||
|
|
||||||
|
Once the container is running, the installation process is essentially the same as running it on bare-metal.<br>
|
||||||
|
So go to the assign TCP port in this case HTTP, like the default 10086 one in the example and log into the WEB-GUI.<br>
|
||||||
|
|
||||||
|
| Environment variable | Accepted arguments | Default value | Example value | Verbose |
|
||||||
|
| -------------- | ------- | ------- | ------- | ------- |
|
||||||
|
| tz | Europe/Amsterdam or any confirming timezone notation. | `Europe/Amsterdam` | `America/New_York` | Sets the timezone of the Docker container. This is to timesync the container to any other processes which would need it. |
|
||||||
|
| global_dns | Any IPv4 address, such as my personal recommendation: 9.9.9.9 (QUAD9). | `1.1.1.1` | `8.8.8.8` or any IP-Address that resolves DNS-names, and of course is reachable | Set the default DNS given to clients once they connect to the WireGuard tunnel, and for new peers, set to Cloudflare DNS for reliability.
|
||||||
|
| enable | Anything, preferably an existing WireGuard interface name. | `none` | `wg0,wg2,wg13` | Enables or disables the starting of the WireGuard interface on container 'boot-up'.
|
||||||
|
| isolate | Anything, preferably an existing WireGuard interface name. | `none` | `wg1,wg0` | The Wireguard interface itself IS able to reach the peers (Done through the `iptables` package).
|
||||||
|
| public_ip | Any IPv4 (public recommended) address, such as the one returned by default | Default uses the return of `curl ifconfig.me` | `89.20.83.118` | To reach your VPN from outside your own network, you need WG-Dashboard to know what your public IP-address is, otherwise it will generate faulty config files for clients. This happends because it is inside a Docker/Kubernetes container. In or outside of NAT is not relevant as long as the given IP-address is reachable from the internet or the target network.
|
||||||
|
|
||||||
|
## Be careful with:
|
||||||
|
|
||||||
|
When you are going to work with multiple WireGuard interfaces, you need to also open them up to the Docker host. This done by either adding the port mappings like: `51821:51821/udp` in the Docker Compose file, or to open a range like: `51820-51830:51820-51830/udp`<br>
|
||||||
|
The latter opens up UDP ports from 51820 to 51830, so all ports in between as well! Be careful, it is good security practise to open only needed ports!
|
||||||
|
|
||||||
|
## Building the image yourself:
|
||||||
|
|
||||||
|
To build the image yourself, you need to do a couple things:<br>
|
||||||
|
1. Clone the Github repository containing the source code of WGDashboard including the docker directory. For example do: `git clone https://github.com/donaldzou/WGDashboard.git`
|
||||||
|
1. Navigate into the cloned repository.
|
||||||
|
1. (Make sure you have Docker correctly installed, if not: [Click here](https://docs.docker.com/engine/install/)) and run: `docker build . -t <Image name>:<Image tag>` as an example: `docker build . -t dselen/wgdashboard:latest`.<br>
|
||||||
|
|
||||||
|
This will make Docker compile the image from the resources in the directory you mention, in this case the source/root one. Let it compile, it takes only a couple seconds with a minute at most.
|
||||||
|
|
||||||
|
1. If all went well, see your image with `docker images`. Example below:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dselen@dev-mach:~/development/WGDashboard/docker$ docker images
|
||||||
|
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||||
|
dselen/wgdashboard latest c96fd96ee3b3 42 minutes ago 314MB
|
||||||
|
```
|
||||||
|
|
||||||
|
## Closing remarks:
|
||||||
|
|
||||||
|
For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
services:
|
||||||
|
wireguard-dashboard:
|
||||||
|
image: donaldzou/wgdashboard:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: wgdashboard
|
||||||
|
#environment:
|
||||||
|
#- tz= # <--- Set container timezone, default: Europe/Amsterdam.
|
||||||
|
#- global_dns= # <--- Set global DNS address, default: 1.1.1.1.
|
||||||
|
#- isolate= # <--- Set the interfaces that will disallow peer communication, default: 'none'.
|
||||||
|
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
|
||||||
|
#- wgd_port= # <--- Set the port WGDashboard will use for its web-server.
|
||||||
|
ports:
|
||||||
|
- 10086:10086/tcp
|
||||||
|
- 51820:51820/udp
|
||||||
|
volumes:
|
||||||
|
- conf:/etc/wireguard
|
||||||
|
- data:/data
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
conf:
|
||||||
|
data:
|
||||||
+160
@@ -0,0 +1,160 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Path to the configuration file (exists because of previous function).
|
||||||
|
config_file="/data/wg-dashboard.ini"
|
||||||
|
|
||||||
|
trap 'stop_service' SIGTERM
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
echo "[WGDashboard] Stopping WGDashboard..."
|
||||||
|
bash ./wgd.sh stop
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "------------------------- START ----------------------------"
|
||||||
|
echo "Starting the WireGuard Dashboard Docker container."
|
||||||
|
|
||||||
|
ensure_installation() {
|
||||||
|
# When using a custom directory to store the files, this part moves over and makes sure the installation continues.
|
||||||
|
echo "Quick-installing..."
|
||||||
|
|
||||||
|
chmod +x "${WGDASH}"/src/wgd.sh
|
||||||
|
cd "${WGDASH}"/src || exit
|
||||||
|
|
||||||
|
echo "Removing clear command from wgd.sh for better Docker logging."
|
||||||
|
sed -i '/clear/d' ./wgd.sh
|
||||||
|
|
||||||
|
if [ ! -d "/data/db" ]; then
|
||||||
|
echo "Creating database dir"
|
||||||
|
mkdir /data/db
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "${WGDASH}/src/db" ]; then
|
||||||
|
ln -s /data/db "${WGDASH}/src/db"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${config_file}" ]; then
|
||||||
|
echo "Creating wg-dashboard.ini file"
|
||||||
|
touch "${config_file}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${WGDASH}/src/wg-dashboard.ini" ]; then
|
||||||
|
ln -s "${config_file}" "${WGDASH}/src/wg-dashboard.ini"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python3 -m venv "${WGDASH}"/src/venv
|
||||||
|
. "${WGDASH}/src/venv/bin/activate"
|
||||||
|
|
||||||
|
echo "Moving PIP dependency from ephemerality to runtime environment: psutil"
|
||||||
|
mv /usr/lib/python3.12/site-packages/psutil* "${WGDASH}"/src/venv/lib/python3.12/site-packages
|
||||||
|
|
||||||
|
echo "Moving PIP dependency from ephemerality to runtime environment: bcrypt"
|
||||||
|
mv /usr/lib/python3.12/site-packages/bcrypt* "${WGDASH}"/src/venv/lib/python3.12/site-packages
|
||||||
|
|
||||||
|
./wgd.sh install
|
||||||
|
|
||||||
|
echo "Looks like the installation succeeded. Moving on."
|
||||||
|
|
||||||
|
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage.
|
||||||
|
# This is done so WGDashboard it works out of the box
|
||||||
|
|
||||||
|
if [ ! -f "/etc/wireguard/wg0.conf" ]; then
|
||||||
|
echo "Standard wg0 Configuration file not found, grabbing template."
|
||||||
|
cp -a "/configs/wg0.conf.template" "/etc/wireguard/wg0.conf"
|
||||||
|
|
||||||
|
echo "Setting a secure private key." # SORRY 4 BE4 - Daan
|
||||||
|
|
||||||
|
local privateKey
|
||||||
|
privateKey=$(wg genkey)
|
||||||
|
sed -i "s|^PrivateKey *=.*$|PrivateKey = ${privateKey}|g" /etc/wireguard/wg0.conf
|
||||||
|
|
||||||
|
echo "Done setting template."
|
||||||
|
else
|
||||||
|
echo "Existing wg0 configuration file found, using that."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_envvars() {
|
||||||
|
printf "\n------------- SETTING ENVIRONMENT VARIABLES ----------------\n"
|
||||||
|
|
||||||
|
# Check if the file is empty
|
||||||
|
if [ ! -s "${config_file}" ]; then
|
||||||
|
echo "Config file is empty. Creating [Peers] section."
|
||||||
|
|
||||||
|
# Create [Peers] section with initial values
|
||||||
|
{
|
||||||
|
echo "[Peers]"
|
||||||
|
echo "peer_global_dns = ${global_dns}"
|
||||||
|
echo "remote_endpoint = ${public_ip}"
|
||||||
|
echo -e "\n[Server]"
|
||||||
|
echo "app_port = ${wgd_port}"
|
||||||
|
} > "${config_file}"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Config file is not empty, using pre-existing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Verifying current variables..."
|
||||||
|
|
||||||
|
# Check and update the DNS if it has changed
|
||||||
|
current_dns=$(grep "peer_global_dns = " "${config_file}" | awk '{print $NF}')
|
||||||
|
if [ "${global_dns}" == "$current_dns" ]; then
|
||||||
|
echo "DNS is set correctly, moving on."
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Changing default DNS..."
|
||||||
|
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" "${config_file}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_public_ip=$(grep "remote_endpoint = " "${config_file}" | awk '{print $NF}')
|
||||||
|
if [ "${public_ip}" == "" ]; then
|
||||||
|
default_ip=$(curl -s ifconfig.me)
|
||||||
|
|
||||||
|
echo "Trying to fetch the Public-IP using ifconfig.me: ${default_ip}"
|
||||||
|
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${default_ip}/" "${config_file}"
|
||||||
|
elif [ "${current_public_ip}" != "${public_ip}" ]; then
|
||||||
|
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${public_ip}/" "${config_file}"
|
||||||
|
else
|
||||||
|
echo "Public-IP is correct, moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_wgd_port=$(grep "app_port = " "${config_file}" | awk '{print $NF}')
|
||||||
|
if [ "${current_wgd_port}" == "${wgd_port}" ]; then
|
||||||
|
echo "Current WGD port is set correctly, moving on."
|
||||||
|
else
|
||||||
|
echo "Changing default WGD port..."
|
||||||
|
sed -i "s/^app_port = .*/app_port = ${wgd_port}/" "${config_file}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# === CORE SERVICES ===
|
||||||
|
start_core() {
|
||||||
|
printf "\n---------------------- STARTING CORE -----------------------\n"
|
||||||
|
|
||||||
|
echo "Activating Python venv and executing the WireGuard Dashboard service."
|
||||||
|
bash ./wgd.sh start
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_blocking() {
|
||||||
|
sleep 1s
|
||||||
|
echo -e "\nEnsuring container continuation."
|
||||||
|
|
||||||
|
# Find and tail the latest error and access logs if they exist
|
||||||
|
local logdir="${WGDASH}/src/log"
|
||||||
|
|
||||||
|
latestErrLog=$(find "$logdir" -name "error_*.log" -type f -print | sort -r | head -n 1)
|
||||||
|
|
||||||
|
# Only tail the logs if they are found
|
||||||
|
if [ -n "$latestErrLog" ]; then
|
||||||
|
tail -f "$latestErrLog" &
|
||||||
|
wait $!
|
||||||
|
else
|
||||||
|
echo "No log files found to tail. Something went wrong, exiting..."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute functions for the WireGuard Dashboard services, then set the environment variables
|
||||||
|
ensure_installation
|
||||||
|
set_envvars
|
||||||
|
start_core
|
||||||
|
ensure_blocking
|
||||||
Generated
+1369
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"marked": "^15.0.7",
|
||||||
|
"openai": "^4.89.0",
|
||||||
|
"pinia-plugin-persistedstate": "^4.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
version: "1.0"
|
||||||
|
linter: jetbrains/qodana-python:2024.3
|
||||||
|
profile:
|
||||||
|
name: qodana.recommended
|
||||||
|
include:
|
||||||
|
- name: CheckDependencyLicenses
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import re, ipaddress
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def RegexMatch(regex, text) -> bool:
|
||||||
|
"""
|
||||||
|
Regex Match
|
||||||
|
@param regex: Regex patter
|
||||||
|
@param text: Text to match
|
||||||
|
@return: Boolean indicate if the text match the regex pattern
|
||||||
|
"""
|
||||||
|
pattern = re.compile(regex)
|
||||||
|
return pattern.search(text) is not None
|
||||||
|
|
||||||
|
def GetRemoteEndpoint() -> str:
|
||||||
|
"""
|
||||||
|
Using socket to determine default interface IP address. Thanks, @NOXICS
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
import socket
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||||
|
s.connect(("1.1.1.1", 80)) # Connecting to a public IP
|
||||||
|
wgd_remote_endpoint = s.getsockname()[0]
|
||||||
|
return str(wgd_remote_endpoint)
|
||||||
|
|
||||||
|
|
||||||
|
def StringToBoolean(value: str):
|
||||||
|
"""
|
||||||
|
Convert string boolean to boolean
|
||||||
|
@param value: Boolean value in string came from Configuration file
|
||||||
|
@return: Boolean value
|
||||||
|
"""
|
||||||
|
return (value.strip().replace(" ", "").lower() in
|
||||||
|
("yes", "true", "t", "1", 1))
|
||||||
|
|
||||||
|
def ValidateIPAddressesWithRange(ips: str) -> bool:
|
||||||
|
s = ips.replace(" ", "").split(",")
|
||||||
|
for ip in s:
|
||||||
|
try:
|
||||||
|
ipaddress.ip_network(ip)
|
||||||
|
except ValueError as e:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def ValidateIPAddresses(ips) -> bool:
|
||||||
|
s = ips.replace(" ", "").split(",")
|
||||||
|
for ip in s:
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError as e:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def ValidateDNSAddress(addresses) -> tuple[bool, str]:
|
||||||
|
s = addresses.replace(" ", "").split(",")
|
||||||
|
for address in s:
|
||||||
|
if not ValidateIPAddresses(address) and not RegexMatch(
|
||||||
|
r"(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]", address):
|
||||||
|
return False, f"{address} does not appear to be an valid DNS address"
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
def GenerateWireguardPublicKey(privateKey: str) -> tuple[bool, str] | tuple[bool, None]:
|
||||||
|
try:
|
||||||
|
publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
return True, publicKey.decode().strip('\n')
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
def GenerateWireguardPrivateKey() -> tuple[bool, str] | tuple[bool, None]:
|
||||||
|
try:
|
||||||
|
publicKey = subprocess.check_output(f"wg genkey", shell=True,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
return True, publicKey.decode().strip('\n')
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return False, None
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
authenticator = standalone
|
||||||
|
noninteractive = true
|
||||||
|
agree-tos = true
|
||||||
|
rsa-key-size = 2048
|
||||||
+3167
-166
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
|||||||
|
import os.path
|
||||||
|
import dashboard, configparser
|
||||||
|
from datetime import datetime
|
||||||
|
global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger
|
||||||
|
app_host, app_port = dashboard.gunicornConfig()
|
||||||
|
date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
|
||||||
|
|
||||||
|
def post_worker_init(worker):
|
||||||
|
dashboard.startThreads()
|
||||||
|
|
||||||
|
worker_class = 'gthread'
|
||||||
|
workers = 1
|
||||||
|
threads = 1
|
||||||
|
bind = f"{app_host}:{app_port}"
|
||||||
|
daemon = True
|
||||||
|
pidfile = './gunicorn.pid'
|
||||||
|
wsgi_app = "dashboard:app"
|
||||||
|
accesslog = f"./log/access_{date}.log"
|
||||||
|
log_level = "debug"
|
||||||
|
capture_output = True
|
||||||
|
errorlog = f"./log/error_{date}.log"
|
||||||
|
pythonpath = "., ./modules"
|
||||||
|
|
||||||
|
print(f"[Gunicorn] WGDashboard w/ Gunicorn will be running on {bind}", flush=True)
|
||||||
|
print(f"[Gunicorn] Access log file is at {accesslog}", flush=True)
|
||||||
|
print(f"[Gunicorn] Error log file is at {errorlog}", flush=True)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"""
|
||||||
|
Dashboard Logger Class
|
||||||
|
"""
|
||||||
|
import sqlite3, os, uuid
|
||||||
|
|
||||||
|
class DashboardLogger:
|
||||||
|
def __init__(self, CONFIGURATION_PATH):
|
||||||
|
self.loggerdb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard_log.db'),
|
||||||
|
isolation_level=None,
|
||||||
|
check_same_thread=False)
|
||||||
|
self.loggerdb.row_factory = sqlite3.Row
|
||||||
|
self.__createLogDatabase()
|
||||||
|
self.log(Message="WGDashboard started")
|
||||||
|
def __createLogDatabase(self):
|
||||||
|
with self.loggerdb:
|
||||||
|
loggerdbCursor = self.loggerdb.cursor()
|
||||||
|
existingTable = loggerdbCursor.execute("SELECT name from sqlite_master where type='table'").fetchall()
|
||||||
|
existingTable = [t['name'] for t in existingTable]
|
||||||
|
if "DashboardLog" not in existingTable:
|
||||||
|
loggerdbCursor.execute(
|
||||||
|
"CREATE TABLE DashboardLog (LogID VARCHAR NOT NULL, LogDate DATETIME DEFAULT (strftime('%Y-%m-%d %H:%M:%S','now', 'localtime')), URL VARCHAR, IP VARCHAR, Status VARCHAR, Message VARCHAR, PRIMARY KEY (LogID))")
|
||||||
|
if self.loggerdb.in_transaction:
|
||||||
|
self.loggerdb.commit()
|
||||||
|
|
||||||
|
def log(self, URL: str = "", IP: str = "", Status: str = "true", Message: str = "") -> bool:
|
||||||
|
try:
|
||||||
|
loggerdbCursor = self.loggerdb.cursor()
|
||||||
|
loggerdbCursor.execute(
|
||||||
|
"INSERT INTO DashboardLog (LogID, URL, IP, Status, Message) VALUES (?, ?, ?, ?, ?);", (str(uuid.uuid4()), URL, IP, Status, Message,))
|
||||||
|
loggerdbCursor.close()
|
||||||
|
self.loggerdb.commit()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[WGDashboard] Access Log Error: {str(e)}")
|
||||||
|
return False
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import os.path
|
||||||
|
import smtplib
|
||||||
|
from email import encoders
|
||||||
|
from email.header import Header
|
||||||
|
from email.mime.base import MIMEBase
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.utils import formataddr
|
||||||
|
|
||||||
|
class EmailSender:
|
||||||
|
def __init__(self, DashboardConfig):
|
||||||
|
self.smtp = None
|
||||||
|
self.DashboardConfig = DashboardConfig
|
||||||
|
if not os.path.exists('../attachments'):
|
||||||
|
os.mkdir('../attachments')
|
||||||
|
|
||||||
|
def Server(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "server")[1]
|
||||||
|
|
||||||
|
def Port(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "port")[1]
|
||||||
|
|
||||||
|
def Encryption(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "encryption")[1]
|
||||||
|
|
||||||
|
def Username(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "username")[1]
|
||||||
|
|
||||||
|
def Password(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "email_password")[1]
|
||||||
|
|
||||||
|
def SendFrom(self):
|
||||||
|
return self.DashboardConfig.GetConfig("Email", "send_from")[1]
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
print(self.Server())
|
||||||
|
return len(self.Server()) > 0 and len(self.Port()) > 0 and len(self.Encryption()) > 0 and len(self.Username()) > 0 and len(self.Password()) > 0
|
||||||
|
|
||||||
|
def send(self, receiver, subject, body, includeAttachment = False, attachmentName = ""):
|
||||||
|
if self.ready():
|
||||||
|
try:
|
||||||
|
self.smtp = smtplib.SMTP(self.Server(), port=int(self.Port()))
|
||||||
|
self.smtp.ehlo()
|
||||||
|
if self.Encryption() == "STARTTLS":
|
||||||
|
self.smtp.starttls()
|
||||||
|
self.smtp.login(self.Username(), self.Password())
|
||||||
|
message = MIMEMultipart()
|
||||||
|
message['Subject'] = subject
|
||||||
|
message['From'] = formataddr((Header(self.SendFrom()).encode(), self.Username()))
|
||||||
|
message["To"] = receiver
|
||||||
|
message.attach(MIMEText(body, "plain"))
|
||||||
|
|
||||||
|
if includeAttachment and len(attachmentName) > 0:
|
||||||
|
attachmentPath = os.path.join('./attachments', attachmentName)
|
||||||
|
if os.path.exists(attachmentPath):
|
||||||
|
attachment = MIMEBase("application", "octet-stream")
|
||||||
|
with open(os.path.join('./attachments', attachmentName), 'rb') as f:
|
||||||
|
attachment.set_payload(f.read())
|
||||||
|
encoders.encode_base64(attachment)
|
||||||
|
attachment.add_header("Content-Disposition", f"attachment; filename= {attachmentName}",)
|
||||||
|
message.attach(attachment)
|
||||||
|
else:
|
||||||
|
self.smtp.close()
|
||||||
|
return False, "Attachment does not exist"
|
||||||
|
self.smtp.sendmail(self.Username(), receiver, message.as_string())
|
||||||
|
self.smtp.close()
|
||||||
|
return True, None
|
||||||
|
except Exception as e:
|
||||||
|
return False, f"Send failed | Reason: {e}"
|
||||||
|
return False, "SMTP not configured"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
"""
|
||||||
|
Log Class
|
||||||
|
"""
|
||||||
|
class Log:
|
||||||
|
def __init__(self, LogID: str, JobID: str, LogDate: str, Status: str, Message: str):
|
||||||
|
self.LogID = LogID
|
||||||
|
self.JobID = JobID
|
||||||
|
self.LogDate = LogDate
|
||||||
|
self.Status = Status
|
||||||
|
self.Message = Message
|
||||||
|
|
||||||
|
def toJson(self):
|
||||||
|
return {
|
||||||
|
"LogID": self.LogID,
|
||||||
|
"JobID": self.JobID,
|
||||||
|
"LogDate": self.LogDate,
|
||||||
|
"Status": self.Status,
|
||||||
|
"Message": self.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
def __dict__(self):
|
||||||
|
return self.toJson()
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
"""
|
||||||
|
Peer Job
|
||||||
|
"""
|
||||||
|
from datetime import datetime
|
||||||
|
class PeerJob:
|
||||||
|
def __init__(self, JobID: str, Configuration: str, Peer: str,
|
||||||
|
Field: str, Operator: str, Value: str, CreationDate: datetime, ExpireDate: datetime, Action: str):
|
||||||
|
self.Action = Action
|
||||||
|
self.ExpireDate = ExpireDate
|
||||||
|
self.CreationDate = CreationDate
|
||||||
|
self.Value = Value
|
||||||
|
self.Operator = Operator
|
||||||
|
self.Field = Field
|
||||||
|
self.Configuration = Configuration
|
||||||
|
self.Peer = Peer
|
||||||
|
self.JobID = JobID
|
||||||
|
|
||||||
|
def toJson(self):
|
||||||
|
return {
|
||||||
|
"JobID": self.JobID,
|
||||||
|
"Configuration": self.Configuration,
|
||||||
|
"Peer": self.Peer,
|
||||||
|
"Field": self.Field,
|
||||||
|
"Operator": self.Operator,
|
||||||
|
"Value": self.Value,
|
||||||
|
"CreationDate": self.CreationDate,
|
||||||
|
"ExpireDate": self.ExpireDate,
|
||||||
|
"Action": self.Action
|
||||||
|
}
|
||||||
|
|
||||||
|
def __dict__(self):
|
||||||
|
return self.toJson()
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
"""
|
||||||
|
Peer Job Logger
|
||||||
|
"""
|
||||||
|
import sqlite3, os, uuid
|
||||||
|
from .Log import Log
|
||||||
|
|
||||||
|
class PeerJobLogger:
|
||||||
|
def __init__(self, CONFIGURATION_PATH, AllPeerJobs):
|
||||||
|
self.loggerdb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard_log.db'),
|
||||||
|
check_same_thread=False)
|
||||||
|
self.loggerdb.row_factory = sqlite3.Row
|
||||||
|
self.logs: list[Log] = []
|
||||||
|
self.__createLogDatabase()
|
||||||
|
self.AllPeerJobs = AllPeerJobs
|
||||||
|
def __createLogDatabase(self):
|
||||||
|
with self.loggerdb:
|
||||||
|
loggerdbCursor = self.loggerdb.cursor()
|
||||||
|
|
||||||
|
existingTable = loggerdbCursor.execute("SELECT name from sqlite_master where type='table'").fetchall()
|
||||||
|
existingTable = [t['name'] for t in existingTable]
|
||||||
|
|
||||||
|
if "JobLog" not in existingTable:
|
||||||
|
loggerdbCursor.execute("CREATE TABLE JobLog (LogID VARCHAR NOT NULL, JobID NOT NULL, LogDate DATETIME DEFAULT (strftime('%Y-%m-%d %H:%M:%S','now', 'localtime')), Status VARCHAR NOT NULL, Message VARCHAR, PRIMARY KEY (LogID))")
|
||||||
|
if self.loggerdb.in_transaction:
|
||||||
|
self.loggerdb.commit()
|
||||||
|
def log(self, JobID: str, Status: bool = True, Message: str = "") -> bool:
|
||||||
|
try:
|
||||||
|
with self.loggerdb:
|
||||||
|
loggerdbCursor = self.loggerdb.cursor()
|
||||||
|
loggerdbCursor.execute(f"INSERT INTO JobLog (LogID, JobID, Status, Message) VALUES (?, ?, ?, ?)",
|
||||||
|
(str(uuid.uuid4()), JobID, Status, Message,))
|
||||||
|
if self.loggerdb.in_transaction:
|
||||||
|
self.loggerdb.commit()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[WGDashboard] Peer Job Log Error: {str(e)}")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getLogs(self, all: bool = False, configName = None) -> list[Log]:
|
||||||
|
logs: list[Log] = []
|
||||||
|
try:
|
||||||
|
allJobs = self.AllPeerJobs.getAllJobs(configName)
|
||||||
|
allJobsID = ", ".join([f"'{x.JobID}'" for x in allJobs])
|
||||||
|
with self.loggerdb:
|
||||||
|
loggerdbCursor = self.loggerdb.cursor()
|
||||||
|
table = loggerdbCursor.execute(f"SELECT * FROM JobLog WHERE JobID IN ({allJobsID}) ORDER BY LogDate DESC").fetchall()
|
||||||
|
self.logs.clear()
|
||||||
|
for l in table:
|
||||||
|
logs.append(
|
||||||
|
Log(l["LogID"], l["JobID"], l["LogDate"], l["Status"], l["Message"]))
|
||||||
|
except Exception as e:
|
||||||
|
return logs
|
||||||
|
return logs
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import psutil
|
||||||
|
class SystemStatus:
|
||||||
|
def __init__(self):
|
||||||
|
self.CPU = CPU()
|
||||||
|
self.MemoryVirtual = Memory('virtual')
|
||||||
|
self.MemorySwap = Memory('swap')
|
||||||
|
self.Disks = Disks()
|
||||||
|
self.NetworkInterfaces = NetworkInterfaces()
|
||||||
|
self.Processes = Processes()
|
||||||
|
def toJson(self):
|
||||||
|
return {
|
||||||
|
"CPU": self.CPU,
|
||||||
|
"Memory": {
|
||||||
|
"VirtualMemory": self.MemoryVirtual,
|
||||||
|
"SwapMemory": self.MemorySwap
|
||||||
|
},
|
||||||
|
"Disks": self.Disks,
|
||||||
|
"NetworkInterfaces": self.NetworkInterfaces,
|
||||||
|
"Processes": self.Processes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CPU:
|
||||||
|
def __init__(self):
|
||||||
|
self.cpu_percent: float = 0
|
||||||
|
self.cpu_percent_per_cpu: list[float] = []
|
||||||
|
def getData(self):
|
||||||
|
try:
|
||||||
|
self.cpu_percent_per_cpu = psutil.cpu_percent(interval=0.5, percpu=True)
|
||||||
|
self.cpu_percent = psutil.cpu_percent(interval=0.5)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
class Memory:
|
||||||
|
def __init__(self, memoryType: str):
|
||||||
|
self.__memoryType__ = memoryType
|
||||||
|
self.total = 0
|
||||||
|
self.available = 0
|
||||||
|
self.percent = 0
|
||||||
|
def getData(self):
|
||||||
|
try:
|
||||||
|
if self.__memoryType__ == "virtual":
|
||||||
|
memory = psutil.virtual_memory()
|
||||||
|
else:
|
||||||
|
memory = psutil.swap_memory()
|
||||||
|
self.total = memory.total
|
||||||
|
self.available = memory.available
|
||||||
|
self.percent = memory.percent
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
class Disks:
|
||||||
|
def __init__(self):
|
||||||
|
self.disks : list[Disk] = []
|
||||||
|
def getData(self):
|
||||||
|
try:
|
||||||
|
self.disks = list(map(lambda x : Disk(x.mountpoint), psutil.disk_partitions()))
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return self.disks
|
||||||
|
|
||||||
|
class Disk:
|
||||||
|
def __init__(self, mountPoint: str):
|
||||||
|
self.total = 0
|
||||||
|
self.used = 0
|
||||||
|
self.free = 0
|
||||||
|
self.percent = 0
|
||||||
|
self.mountPoint = mountPoint
|
||||||
|
def getData(self):
|
||||||
|
try:
|
||||||
|
disk = psutil.disk_usage(self.mountPoint)
|
||||||
|
self.total = disk.total
|
||||||
|
self.free = disk.free
|
||||||
|
self.used = disk.used
|
||||||
|
self.percent = disk.percent
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
class NetworkInterfaces:
|
||||||
|
def __init__(self):
|
||||||
|
self.interfaces = {}
|
||||||
|
def getData(self):
|
||||||
|
try:
|
||||||
|
network = psutil.net_io_counters(pernic=True, nowrap=True)
|
||||||
|
for i in network.keys():
|
||||||
|
self.interfaces[i] = network[i]._asdict()
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return self.interfaces
|
||||||
|
|
||||||
|
class Process:
|
||||||
|
def __init__(self, name, command, pid, percent):
|
||||||
|
self.name = name
|
||||||
|
self.command = command
|
||||||
|
self.pid = pid
|
||||||
|
self.percent = percent
|
||||||
|
def toJson(self):
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
class Processes:
|
||||||
|
def __init__(self):
|
||||||
|
self.CPU_Top_10_Processes: list[Process] = []
|
||||||
|
self.Memory_Top_10_Processes: list[Process] = []
|
||||||
|
def getData(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
processes = list(psutil.process_iter())
|
||||||
|
self.CPU_Top_10_Processes = sorted(
|
||||||
|
list(map(lambda x : Process(x.name(), " ".join(x.cmdline()), x.pid, x.cpu_percent()), processes)),
|
||||||
|
key=lambda x : x.percent, reverse=True)[:20]
|
||||||
|
self.Memory_Top_10_Processes = sorted(
|
||||||
|
list(map(lambda x : Process(x.name(), " ".join(x.cmdline()), x.pid, x.memory_percent()), processes)),
|
||||||
|
key=lambda x : x.percent, reverse=True)[:20]
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
break
|
||||||
|
def toJson(self):
|
||||||
|
self.getData()
|
||||||
|
return {
|
||||||
|
"cpu_top_10": self.CPU_Top_10_Processes,
|
||||||
|
"memory_top_10": self.Memory_Top_10_Processes
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
bcrypt
|
||||||
|
ifcfg
|
||||||
|
psutil
|
||||||
|
pyotp
|
||||||
|
Flask
|
||||||
|
flask-cors
|
||||||
|
icmplib
|
||||||
|
gunicorn
|
||||||
|
requests
|
||||||
|
tcconfig
|
||||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,30 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
.vite/*
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "Running vite build..."
|
||||||
|
if vite build; then
|
||||||
|
echo "Vite build successful."
|
||||||
|
else
|
||||||
|
echo "Vite build failed. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Checking for changes to commit..."
|
||||||
|
if git diff-index --quiet HEAD --; then
|
||||||
|
|
||||||
|
if git commit -a; then
|
||||||
|
echo "Git commit successful."
|
||||||
|
else
|
||||||
|
echo "Git commit failed. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No changes to commit. Skipping commit."
|
||||||
|
fi
|
||||||
|
echo "Pushing changes to remote..."
|
||||||
|
if git push; then
|
||||||
|
echo "Git push successful."
|
||||||
|
else
|
||||||
|
echo "Git push failed. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
import{_ as r,c as i,d as o,w as e,k as l,a as t,j as _,i as a,l as d,S as u}from"./index-CUmHRwBw.js";const m={name:"configuration"},p={class:"mt-md-5 mt-3 text-body"};function f(k,x,h,w,$,v){const n=l("RouterView");return t(),i("div",p,[o(n,null,{default:e(({Component:s,route:c})=>[o(_,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(d(s),{key:c.path}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",f]]);export{B as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.fade-enter-active[data-v-6451623a]{transition-delay:var(--d75b06ae)!important}.progress-bar[data-v-c7f6d1a1]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.filter a[data-v-ea61b607]{text-decoration:none}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.agentMessage[data-v-8635cf47]{white-space:break-spaces;max-width:80%;display:flex;flex-direction:column;word-wrap:break-word}.text-bg-secondary[data-v-8635cf47]{background-color:RGBA(var(--bs-secondary-rgb),.7)!important}.text-bg-primary[data-v-8635cf47]{background-color:RGBA(var(--bs-primary-rgb),.7)!important}.agentContainer[data-v-694cfad1]{--agentHeight: 100vh;position:absolute;z-index:9999;top:0;left:100%;width:450px;box-shadow:0 10px 30px #0000004d;backdrop-filter:blur(8px);background:linear-gradient(var(--degree),#009dff52 var(--distance2),#ff4a0052 100%)}.agentContainer.enabled[data-v-694cfad1]{height:calc(var(--agentHeight) - 1rem)}@media screen and (max-width: 768px){.agentContainer[data-v-694cfad1]{--agentHeight: 100vh !important;top:0;left:0;max-height:calc(var(--agentHeight) - 58px - 1rem);width:calc(100% - 1rem)}}.agentChatroomBody[data-v-694cfad1]{flex:1 1 auto;overflow-y:auto;max-height:calc(var(--agentHeight) - 70px - 244px)}@media screen and (max-width: 768px){.navbar-container[data-v-58e71749]{position:absolute!important;z-index:1000;animation-duration:.4s;animation-fill-mode:both;display:none;animation-timing-function:cubic-bezier(.82,.58,.17,.9)}.navbar-container.active[data-v-58e71749]{animation-direction:normal;display:block!important;animation-name:zoomInFade-58e71749}}.navbar-container[data-v-58e71749]{height:100vh;position:relative}@supports (height: 100dvh){@media screen and (max-width: 768px){.navbar-container[data-v-58e71749]{height:calc(100dvh - 58px)}}}@keyframes zoomInFade-58e71749{0%{opacity:0;transform:translateY(60px);filter:blur(3px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}.slideIn-enter-active[data-v-58e71749],.slideIn-leave-active[data-v-58e71749]{transition:all .3s cubic-bezier(.82,.58,.17,1)}.slideIn-enter-from[data-v-58e71749],.slideIn-leave-to[data-v-58e71749]{transform:translateY(30px);filter:blur(3px);opacity:0}main[data-v-0c6a5068]{height:100vh}@supports (height: 100dvh){@media screen and (max-width: 768px){main[data-v-0c6a5068]{height:calc(100dvh - 58px)}}}
|
||||||
+18
File diff suppressed because one or more lines are too long
+56
File diff suppressed because one or more lines are too long
+44
File diff suppressed because one or more lines are too long
+15
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
function f(e){return e.includes(":")?6:e.includes(".")?4:0}function b(e){const i=f(e);if(!i)throw new Error(`Invalid IP address: ${e}`);let n=0n,o=0n;const r=Object.create(null);if(i===4)for(const s of e.split(".").map(BigInt).reverse())n+=s*2n**o,o+=8n;else{if(e.includes(".")&&(r.ipv4mapped=!0,e=e.split(":").map(t=>{if(t.includes(".")){const[c,l,d,a]=t.split(".").map($=>Number($).toString(16).padStart(2,"0"));return`${c}${l}:${d}${a}`}else return t}).join(":")),e.includes("%")){let t;[,e,t]=/(.+)%(.+)/.exec(e)||[],r.scopeid=t}const s=e.split(":"),u=s.indexOf("");if(u!==-1)for(;s.length<8;)s.splice(u,0,"");for(const t of s.map(c=>BigInt(parseInt(c||"0",16))).reverse())n+=t*2n**o,o+=16n}return r.number=n,r.version=i,r}const p={4:32,6:128},I=e=>e.includes("/")?f(e):0;function m(e){const i=I(e),n=Object.create(null);if(i)n.cidr=e,n.version=i;else{const a=f(e);if(a)n.cidr=`${e}/${p[a]}`,n.version=a;else throw new Error(`Network is not a CIDR or IP: ${e}`)}const[o,r]=n.cidr.split("/");if(!/^[0-9]+$/.test(r))throw new Error(`Network is not a CIDR or IP: ${e}`);n.prefix=r,n.single=r===String(p[n.version]);const{number:s,version:u}=b(o),t=p[u],c=s.toString(2).padStart(t,"0"),l=Number(t-r),d=c.substring(0,t-l);return n.start=BigInt(`0b${d}${"0".repeat(l)}`),n.end=BigInt(`0b${d}${"1".repeat(l)}`),n}export{m as p};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_ as e,G as t,a as o,c as a,t as c}from"./index-CUmHRwBw.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return o(),a("span",null,c(this.getLocaleText),1)}const u=e(s,[["render",n]]);export{u as L};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{L as l}from"./localeText-DvaqSAco.js";import{d as c}from"./dayjs.min-C3XPfvH9.js";import{_ as h,a as o,c as a,b as e,d as i,w as u,f as p,t as n,j as g,n as f,k as _}from"./index-CUmHRwBw.js";const x={name:"message",methods:{dayjs:c,hide(){this.ct(),this.message.show=!1},show(){this.timeout=setTimeout(()=>{this.message.show=!1},5e3)},ct(){clearTimeout(this.timeout)}},components:{LocaleText:l},props:{message:Object},mounted(){this.show()},data(){return{dismiss:!1,timeout:null}}},v=["id"],b={key:0,class:"d-flex"},w={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},y={class:"ms-auto"},k={key:1},T={class:"card-body d-flex align-items-center gap-3"};function M(j,s,C,L,t,m){const d=_("LocaleText");return o(),a("div",{onMouseenter:s[1]||(s[1]=r=>{t.dismiss=!0,this.ct()}),onMouseleave:s[2]||(s[2]=r=>{t.dismiss=!1,this.show()}),class:"card shadow rounded-3 position-relative message ms-auto",id:this.message.id},[e("div",{class:f([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[i(g,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(o(),a("div",k,[e("small",{onClick:s[0]||(s[0]=r=>m.hide()),class:"d-block mx-auto w-100 text-center",style:{cursor:"pointer"}},[s[3]||(s[3]=e("i",{class:"bi bi-x-lg me-2"},null,-1)),i(d,{t:"Dismiss"})])])):(o(),a("div",b,[e("small",w,[i(d,{t:"FROM "}),p(" "+n(this.message.from),1)]),e("small",y,n(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,n(this.message.content),1)])],40,v)}const z=h(x,[["render",M],["__scopeId","data-v-94c76b54"]]);export{z as M};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.message[data-v-94c76b54]{width:100%}@media screen and (min-width: 576px){.message[data-v-94c76b54]{width:400px}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.protocolBtnGroup a[data-v-b4bbbc2b]{transition:all .2s ease-in-out}
|
||||||
File diff suppressed because one or more lines are too long
+10
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.list-move[data-v-ed72944d],.list-enter-active[data-v-ed72944d],.list-leave-active[data-v-ed72944d]{transition:all .3s ease}.list-enter-from[data-v-ed72944d],.list-leave-to[data-v-ed72944d]{opacity:0;transform:translateY(10px)}.list-leave-active[data-v-ed72944d]{position:absolute}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.slide-up-enter-active[data-v-b0ea2d46],.slide-up-leave-active[data-v-b0ea2d46]{transition:all .2s cubic-bezier(.42,0,.22,1)}.slide-up-enter-from[data-v-b0ea2d46],.slide-up-leave-to[data-v-b0ea2d46]{opacity:0;transform:scale(.9)}@keyframes spin-b0ea2d46{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#check[data-v-b0ea2d46]{animation:cubic-bezier(.42,0,.22,1.3) .7s spin-b0ea2d46}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_ as v,D as g,r as o,o as h,J as x,g as y,a as i,c as n,b as s,d as c,n as w,e as C,w as k,j as F}from"./index-CUmHRwBw.js";import{L as T}from"./localeText-DvaqSAco.js";import"./browser-CjSdxGTc.js";const M={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},S={class:"container d-flex h-100 w-100"},D={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},P={class:"card rounded-3 shadow w-100"},j={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},B={class:"mb-0"},G={class:"card-body p-4 d-flex flex-column gap-3"},L={style:{height:"300px"},class:"d-flex"},N=["value"],V={key:0,class:"spinner-border m-auto",role:"status"},I={class:"d-flex"},W=["disabled"],$={key:0,class:"d-block"},q={key:1,class:"d-block",id:"check"},z={__name:"peerConfigurationFile",props:{selectedPeer:Object},emits:["close"],setup(u,{emit:p}){const m=p,f=u,r=g(),t=o(!1),l=o(""),a=o(!0);o({error:!1,message:void 0}),h(()=>{const d=x();y("/api/downloadPeer/"+d.params.id,{id:f.selectedPeer.id},e=>{e.status?(l.value=e.data.file,a.value=!1):this.dashboardStore.newMessage("Server",e.message,"danger")})});const b=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(l.value).then(()=>{t.value=!0,setTimeout(()=>{t.value=!1},3e3)}).catch(()=>{r.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(t.value=!0,setTimeout(()=>{t.value=!1},3e3)):r.newMessage("WGDashboard","Failed to copy","danger"))};return(d,e)=>(i(),n("div",M,[s("div",S,[s("div",D,[s("div",P,[s("div",j,[s("h4",B,[c(T,{t:"Peer Configuration File"})]),s("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=_=>m("close"))})]),s("div",G,[s("div",L,[s("textarea",{style:{height:"300px"},class:w(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,N),a.value?(i(),n("div",V,e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)]))):C("",!0)]),s("div",I,[s("button",{onClick:e[1]||(e[1]=_=>b()),disabled:t.value||a.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[c(F,{name:"slide-up",mode:"out-in"},{default:k(()=>[t.value?(i(),n("span",q,e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)]))):(i(),n("span",$,e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])))]),_:1})],8,W)])])])])])]))}},R=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{R as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{S as p,a as b}from"./schedulePeerJob-Rx5QXWIx.js";import{_ as h,W as u,z as m,k as i,a as o,c as a,b as e,d as r,w as _,F as v,h as f,i as J,e as x,T as g}from"./index-CUmHRwBw.js";import{L as w}from"./localeText-DvaqSAco.js";import"./vue-datepicker-CUbRHf9G.js";import"./dayjs.min-C3XPfvH9.js";const P={name:"peerJobs",setup(){return{store:u()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:p,ScheduleDropdown:b},data(){return{}},methods:{deleteJob(d){this.selectedPeer.jobs=this.selectedPeer.jobs.filter(t=>t.JobID!==d.JobID)},addJob(){this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({JobID:m().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},k={class:"mb-0 fw-normal"},j={class:"card-body px-4 pb-4 pt-2 position-relative"},T={class:"d-flex align-items-center mb-3"},N={class:"card shadow-sm",key:"none",style:{height:"153px"}},I={class:"card-body text-muted text-center d-flex"},L={class:"m-auto"};function O(d,t,B,F,V,A){const n=i("LocaleText"),l=i("SchedulePeerJob");return o(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",k,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=s=>this.$emit("close"))})]),e("div",j,[e("div",T,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow",onClick:t[1]||(t[1]=s=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(g,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:_(()=>[(o(!0),a(v,null,f(this.selectedPeer.jobs,(s,E)=>(o(),J(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(s),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:s.JobID,pjob:s},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(o(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):x("",!0)]),_:1})])])])])])}const q=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{q as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.schedulePeerJobTransition-move[data-v-5bbdd42b],.schedulePeerJobTransition-enter-active[data-v-5bbdd42b],.schedulePeerJobTransition-leave-active[data-v-5bbdd42b]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.schedulePeerJobTransition-enter-from[data-v-5bbdd42b],.schedulePeerJobTransition-leave-to[data-v-5bbdd42b]{opacity:0;transform:scale(.9)}.schedulePeerJobTransition-leave-active[data-v-5bbdd42b]{position:absolute;width:100%}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{S as _}from"./schedulePeerJob-Rx5QXWIx.js";import{_ as g,W as v,k as c,a as t,c as r,b as e,d as l,F as p,h as b,t as m,e as f,i as y}from"./index-CUmHRwBw.js";import{L as x}from"./localeText-DvaqSAco.js";import"./vue-datepicker-CUbRHf9G.js";import"./dayjs.min-C3XPfvH9.js";const J={name:"peerJobsAllModal",setup(){return{store:v()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},k={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},w={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},C={class:"card-body px-4 pb-4 pt-2"},P={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},j={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",k,[e("div",w,[e("div",$,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",C,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",P,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",j,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),y(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const U=g(J,[["render",W]]);export{U as default};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
import{b as r}from"./browser-CjSdxGTc.js";import{L as i}from"./localeText-DvaqSAco.js";import{_ as c,D as l,g as p,k as _,a,c as n,b as e,d as m,n as h,e as u}from"./index-CUmHRwBw.js";const f={name:"peerQRCode",components:{LocaleText:i},props:{selectedPeer:Object},setup(){return{dashboardStore:l()}},data(){return{loading:!0}},mounted(){p("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},t=>{this.loading=!1,t.status?r.toCanvas(document.querySelector("#qrcode"),t.data.file,s=>{s&&console.error(s)}):this.dashboardStore.newMessage("Server",t.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},g={class:"container d-flex h-100 w-100"},v={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},x={class:"card rounded-3 shadow"},C={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},w={class:"mb-0"},y={class:"card-body p-4"},S={style:{width:"292px",height:"292px"},class:"d-flex"},k={key:0,class:"spinner-border m-auto",role:"status"};function L(t,s,$,q,o,B){const d=_("LocaleText");return a(),n("div",b,[e("div",g,[e("div",v,[e("div",x,[e("div",C,[e("h4",w,[m(d,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:s[0]||(s[0]=N=>this.$emit("close"))})]),e("div",y,[e("div",S,[e("canvas",{id:"qrcode",class:h(["rounded-3 shadow animate__animated animate__fadeIn animate__faster",{"d-none":o.loading}])},null,2),o.loading?(a(),n("div",k,s[1]||(s[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)]))):u("",!0)])])])])])])}const T=c(f,[["render",L]]);export{T as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.searchPeersContainer[data-v-b741afe7]{width:100%}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_ as u,q as m,G as p,r as b,W as f,a2 as h,o as g,a as v,i as y,w as _,b as e,m as x,y as w,d as S,j as B}from"./index-CUmHRwBw.js";import{L as T}from"./localeText-DvaqSAco.js";const C={class:"fixed-bottom w-100 bottom-0 z-2",style:{"z-index":"1"}},P={class:"container-fluid"},k={class:"row g-0"},L={class:"col-md-9 col-lg-10 d-flex justify-content-center py-2"},V={class:"rounded-3 p-2 border shadow searchPeersContainer bg-body-tertiary"},j={class:"d-flex gap-1 align-items-center px-2"},z=["placeholder"],D={__name:"peerSearchBar",emits:["close"],setup(G,{emit:n}){const l=m(()=>p("Search Peers..."));let t;const o=b(""),r=f(),i=()=>{t?(clearTimeout(t),t=setTimeout(()=>{r.searchString=o.value},300)):t=setTimeout(()=>{r.searchString=o.value},300)},d=n,c=h("searchBar");return g(()=>{c.value.focus()}),(M,s)=>(v(),y(B,{name:"slideUp",appear:"",type:"animation",style:{"animation-delay":"1s"}},{default:_(()=>[e("div",C,[e("div",P,[e("div",k,[s[5]||(s[5]=e("div",{class:"col-md-3 col-lg-2"},null,-1)),e("div",L,[e("div",V,[e("div",j,[s[4]||(s[4]=e("h6",{class:"mb-0 me-2"},[e("label",{for:"searchPeers"},[e("i",{class:"bi bi-search"})])],-1)),x(e("input",{ref:"searchBar",class:"flex-grow-1 form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:s[0]||(s[0]=a=>i()),"onUpdate:modelValue":s[1]||(s[1]=a=>o.value=a)},null,40,z),[[w,o.value]]),e("button",{onClick:s[2]||(s[2]=a=>d("close")),style:{"white-space":"nowrap"},class:"btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3 d-flex align-items-center"},[e("span",null,[s[3]||(s[3]=e("i",{class:"bi bi-x-circle-fill me-2"},null,-1)),S(T,{t:"Done"})])])])])])])])])]),_:1}))}},W=u(D,[["__scopeId","data-v-b741afe7"]]);export{W as default};
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.toggleShowKey[data-v-2166fcf9]{position:absolute;top:35px;right:12px}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.card[data-v-8cfb4d4d]{border-color:var(--bs-border-color)!important}textarea[data-v-6e705c87]:focus,input[data-v-6e705c87]:focus{box-shadow:none;border-color:var(--bs-border-color)!important}textarea[data-v-6e705c87]{padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}
|
||||||
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.pingPlaceholder[data-v-a08ce97e]{width:100%;height:79.98px}.ping-move[data-v-a08ce97e],.ping-enter-active[data-v-a08ce97e],.ping-leave-active[data-v-a08ce97e]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.ping-leave-active[data-v-a08ce97e]{position:absolute;width:100%}.ping-enter-from[data-v-a08ce97e],.ping-leave-to[data-v-a08ce97e]{opacity:0;filter:blur(3px)}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{L as r}from"./localeText-DvaqSAco.js";import{a as t,c as n,f as i,i as s,e as a}from"./index-CUmHRwBw.js";const d={key:0,class:"badge wireguardBg rounded-3 shadow"},c={key:1,class:"badge amneziawgBg rounded-3 shadow"},u={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(e){return(m,o)=>e.protocol==="wg"?(t(),n("span",d,[o[0]||(o[0]=i(" WireGuard ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):e.protocol==="awg"?(t(),n("span",c,[o[1]||(o[1]=i(" AmneziaWG ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):a("",!0)}};export{u as _};
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.dropdownIcon[data-v-ccf48ac7]{transition:all .2s ease-in-out}.dropdownIcon.active[data-v-ccf48ac7]{transform:rotate(180deg)}.steps{&[data-v-324df2b1]{transition:all .3s ease-in-out;opacity:.3}&.active[data-v-324df2b1]{opacity:1}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.btn.disabled[data-v-6a5aba2a]{opacity:1;background-color:#0d6efd17;border-color:transparent}[data-v-8f3f1b93]{font-size:.875rem}input[data-v-8f3f1b93]{padding:.1rem .4rem}input[data-v-8f3f1b93]:disabled{border-color:transparent;background-color:#0d6efd17;color:#0d6efd}.dp__main[data-v-8f3f1b93]{width:auto;flex-grow:1;--dp-input-padding: 2.5px 30px 2.5px 12px;--dp-border-radius: .5rem}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.card[data-v-177407c1]{height:100%}.dashboardModal[data-v-177407c1]{height:calc(100% - 1rem)!important}@media screen and (min-height: 700px){.card[data-v-177407c1]{height:700px}}.peerBtn[data-v-177407c1]{border:var(--bs-border-width) solid var(--bs-border-color)}.peerBtn.active[data-v-177407c1]{border:var(--bs-border-width) solid var(--bs-body-color)}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
@media screen and (max-width: 992px){.apiKey-card-body{&[data-v-a76253c8]{flex-direction:column!important;align-items:start!important}div.ms-auto[data-v-a76253c8]{margin-left:0!important}div[data-v-a76253c8]{width:100%;align-items:start!important}small[data-v-a76253c8]{margin-right:auto}}}.apiKey-move[data-v-100ee9f9],.apiKey-enter-active[data-v-100ee9f9],.apiKey-leave-active[data-v-100ee9f9]{transition:all .5s ease}.apiKey-enter-from[data-v-100ee9f9],.apiKey-leave-to[data-v-100ee9f9]{opacity:0;transform:translateY(30px) scale(.9)}.apiKey-leave-active[data-v-100ee9f9]{position:absolute;width:100%}.dropdown-menu[data-v-4e34593e]{width:100%}.list-group{&[data-v-4aa2aed9]:first-child{border-top-left-radius:var(--bs-border-radius-lg);border-top-right-radius:var(--bs-border-radius-lg)}&[data-v-4aa2aed9]:last-child{border-bottom-left-radius:var(--bs-border-radius-lg);border-bottom-right-radius:var(--bs-border-radius-lg)}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_ as u,D as m,A as p,c as r,b as e,d as o,f as c,t as h,e as f,m as l,y as d,a as i,k as w}from"./index-CUmHRwBw.js";import{L as g}from"./localeText-DvaqSAco.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:m()}},data(){return{setup:{username:"",newPassword:"",repeatNewPassword:"",enable_totp:!0},loading:!1,errorMessage:"",done:!1}},computed:{goodToSubmit(){return this.setup.username&&this.setup.newPassword.length>=8&&this.setup.repeatNewPassword.length>=8&&this.setup.newPassword===this.setup.repeatNewPassword}},methods:{submit(){this.loading=!0,p("/api/Welcome_Finish",this.setup,n=>{n.status?(this.done=!0,this.$router.push("/2FASetup")):(document.querySelectorAll("#createAccount input").forEach(s=>s.classList.add("is-invalid")),this.errorMessage=n.message,document.querySelector(".login-container-fluid").scrollTo({top:0,left:0,behavior:"smooth"})),this.loading=!1})}}},_=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},v={class:"dashboardLogo display-4"},y={class:"mb-5"},P={key:0,class:"alert alert-danger"},N={class:"d-flex flex-column gap-3"},k={id:"createAccount",class:"d-flex flex-column gap-2"},S={class:"form-group text-body"},T={for:"username",class:"mb-1 text-muted"},C={class:"form-group text-body"},L={for:"password",class:"mb-1 text-muted"},V={class:"form-group text-body"},A={for:"confirmPassword",class:"mb-1 text-muted"},$=["disabled"],q={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=w("LocaleText");return i(),r("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[e("div",x,[e("span",v,[o(t,{t:"Nice to meet you!"})]),e("p",y,[o(t,{t:"Please fill in the following fields to finish setup"}),s[4]||(s[4]=c(" 😊"))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):f("",!0),e("div",N,[e("form",k,[e("div",S,[e("label",T,[e("small",null,[o(t,{t:"Enter an username you like"})])]),l(e("input",{type:"text",autocomplete:"username","onUpdate:modelValue":s[0]||(s[0]=a=>this.setup.username=a),class:"form-control",id:"username",name:"username",required:""},null,512),[[d,this.setup.username]])]),e("div",C,[e("label",L,[e("small",null,[o(t,{t:"Enter a password"}),e("code",null,[o(t,{t:"(At least 8 characters and make sure is strong enough!)"})])])]),l(e("input",{type:"password",autocomplete:"new-password","onUpdate:modelValue":s[1]||(s[1]=a=>this.setup.newPassword=a),class:"form-control",id:"password",name:"password",required:""},null,512),[[d,this.setup.newPassword]])]),e("div",V,[e("label",A,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",q,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,$)])])])],8,_)}const j=u(b,[["render",B]]);export{j as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.animate__fadeInUp[data-v-1b44aacd]{animation-timing-function:cubic-bezier(.42,0,.22,1)}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_,r,D as p,g as u,c as m,b as t,d as c,J as h,a as f,k as b}from"./index-CUmHRwBw.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-DvaqSAco.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=h(),e=r(!1),i=p(),n=r(""),s=r(void 0),l=r(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(s.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(s.value=d.data,l.value=new Blob([s.value.file],{type:"text/plain"})):s.value=void 0,e.value=!0}),{store:i,theme:n,peerConfiguration:s,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),i=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=i,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},w=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},I={class:"m-auto"},L={key:1,class:"d-flex align-items-center flex-column gap-3"},k={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},B={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},D={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},R=["download","href"];function q(o,e,i,n,s,l){const a=b("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",x,[this.peerConfiguration?(f(),m("div",L,[t("div",k,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),c(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",B,null,512),t("p",D,[c(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),c(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)]),8,R)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",I,[c(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,w)}const N=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{N as default};
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.dot.inactive[data-v-ed7817c7]{background-color:#dc3545;box-shadow:0 0 0 .2rem #dc354545}.spin[data-v-ed7817c7]{animation:spin-ed7817c7 1s infinite cubic-bezier(.82,.58,.17,.9)}@keyframes spin-ed7817c7{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media screen and (max-width: 768px){.remoteServerContainer[data-v-ed7817c7]{flex-direction:column}.remoteServerContainer .button-group button[data-v-ed7817c7]{width:100%}}@media screen and (max-width: 768px){.login-box[data-v-80e20da4]{width:100%!important}.login-box div[data-v-80e20da4]{width:auto!important}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.square[data-v-70102637]{height:var(--e901480c);transition:background-color .5s cubic-bezier(.42,0,.22,1)}.floatingLabel[data-v-70102637]{top:40px}.square[data-v-a382214a]{height:var(--38705f32);transition:background-color .5s cubic-bezier(.42,0,.22,1)}.floatingLabel[data-v-a382214a]{top:var(--38705f32)}
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
import{_ as i,p as m,r as p,q as b,a as o,c as t,d as g,w as v,n as x,b as r,t as n,e as f,j as C,s as w}from"./index-CUmHRwBw.js";const y={class:"text-muted me-2"},_={class:"fw-bold"},k={__name:"cpuCore",props:{core_number:Number,percentage:Number,align:Boolean,square:Boolean},setup(e){m(c=>({e901480c:u.value}));const l=e,a=p(!1),u=b(()=>l.square?"40px":"25px");return(c,s)=>(o(),t("div",{class:"flex-grow-1 square rounded-3 border position-relative p-2",onMouseenter:s[0]||(s[0]=d=>a.value=!0),onMouseleave:s[1]||(s[1]=d=>a.value=!1),style:w({"background-color":`rgb(13 110 253 / ${e.percentage*10}%)`})},[g(C,{name:"zoomReversed"},{default:v(()=>[a.value?(o(),t("div",{key:0,style:{"white-space":"nowrap"},class:x(["floatingLabel z-3 border position-absolute d-block p-1 px-2 bg-body text-body rounded-3 border shadow d-flex",[e.align?"end-0":"start-0"]])},[r("small",y," Core #"+n(e.core_number+1),1),r("small",_,n(e.percentage)+"% ",1)],2)):f("",!0)]),_:1})],36))}},B=i(k,[["__scopeId","data-v-70102637"]]);export{B as C};
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
.title[data-v-ffe5ad8f]{height:18px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.process-move[data-v-977dc46d],.process-enter-active[data-v-977dc46d],.process-leave-active[data-v-977dc46d]{transition:all .5s cubic-bezier(.42,0,.22,1)}.process-enter-from[data-v-977dc46d],.process-leave-to[data-v-977dc46d]{opacity:0;transform:scale(.9)}.process-leave-active[data-v-977dc46d]{position:absolute;width:100%}.progress-bar[data-v-977dc46d]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.fadeIn[data-v-977dc46d]{opacity:0;animation:fadeIn-977dc46d .5s forwards cubic-bezier(.42,0,.22,1)}@keyframes fadeIn-977dc46d{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
import{_ as h,D as m,g as p,A as f,c as b,b as t,d as i,t as _,m as v,y as g,i as d,w as r,k as c,a as n}from"./index-CUmHRwBw.js";import{b as x}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-DvaqSAco.js";const T={name:"totp",components:{LocaleText:y},async setup(){const s=m();let e="";return await p("/api/Welcome_GetTotpLink",{},a=>{a.status&&(e=a.data)}),{l:e,store:s}},mounted(){this.l&&x.toCanvas(document.getElementById("qrcode"),this.l,function(s){})},data(){return{totp:"",totpInvalidMessage:"",verified:!1}},methods:{validateTotp(){}},watch:{totp(s){const e=document.querySelector("#totp");e.classList.remove("is-invalid","is-valid"),s.length===6&&(console.log(s),/[0-9]{6}/.test(s)?f("/api/Welcome_VerifyTotpLink",{totp:s},a=>{a.status?(this.verified=!0,e.classList.add("is-valid"),this.$emit("verified")):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP does not match.")}):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP can only contain numbers"))}}},k=["data-bs-theme"],w={class:"m-auto text-body",style:{width:"500px"}},L={class:"d-flex flex-column"},M={class:"dashboardLogo display-4"},C={class:"mb-2"},P={class:"text-muted"},I={class:"p-3 bg-body-secondary rounded-3 border mb-3"},O={class:"text-muted mb-0"},B=["href"],$={style:{"line-break":"anywhere"}},A={for:"totp",class:"mb-2"},D={class:"text-muted"},S={class:"form-group mb-2"},q=["disabled"],E={class:"invalid-feedback"},F={class:"valid-feedback"},R={class:"d-flex gap-3 mt-5 flex-column"};function G(s,e,a,N,W,Q){const o=c("LocaleText"),l=c("RouterLink");return n(),b("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[t("div",w,[t("div",L,[t("div",null,[t("h1",M,[i(o,{t:"Multi-Factor Authentication (MFA)"})]),t("p",C,[t("small",P,[i(o,{t:"1. Please scan the following QR Code to generate TOTP with your choice of authenticator"})])]),e[1]||(e[1]=t("canvas",{id:"qrcode",class:"rounded-3 mb-2"},null,-1)),t("div",I,[t("p",O,[t("small",null,[i(o,{t:"Or you can click the link below:"})])]),t("a",{href:this.l},[t("code",$,_(this.l),1)],8,B)]),t("label",A,[t("small",D,[i(o,{t:"2. Enter the TOTP generated by your authenticator to verify"})])]),t("div",S,[v(t("input",{class:"form-control text-center totp",id:"totp",maxlength:"6",type:"text",inputmode:"numeric",autocomplete:"one-time-code","onUpdate:modelValue":e[0]||(e[0]=u=>this.totp=u),disabled:this.verified},null,8,q),[[g,this.totp]]),t("div",E,[i(o,{t:this.totpInvalidMessage},null,8,["t"])]),t("div",F,[i(o,{t:"TOTP verified!"})])])]),e[4]||(e[4]=t("hr",null,null,-1)),t("div",R,[this.verified?(n(),d(l,{key:1,to:"/",class:"btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3"},{default:r(()=>[i(o,{t:"Complete"}),e[3]||(e[3]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1})):(n(),d(l,{key:0,to:"/",class:"btn bg-secondary-subtle text-secondary-emphasis rounded-3 flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex"},{default:r(()=>[i(o,{t:"I don't need MFA"}),e[2]||(e[2]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1}))])])])],8,k)}const z=h(T,[["render",G]]);export{z as default};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.pingPlaceholder[data-v-3e75b4d4]{width:100%;height:40px}.ping-move[data-v-3e75b4d4],.ping-enter-active[data-v-3e75b4d4],.ping-leave-active[data-v-3e75b4d4]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.ping-leave-active[data-v-3e75b4d4]{position:absolute;width:100%}.ping-enter-from[data-v-3e75b4d4],.ping-leave-to[data-v-3e75b4d4]{opacity:0;filter:blur(3px)}.ping-leave-active[data-v-3e75b4d4]{position:absolute}table th[data-v-3e75b4d4],table td[data-v-3e75b4d4]{padding:.5rem}.table[data-v-3e75b4d4]>:not(caption)>*>*{background-color:transparent!important}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{_ as h,W as g,g as b,c as o,b as t,d as n,m as y,y as f,C as x,w as r,j as c,a as l,f as v,F as u,h as m,n as k,s as T,t as i,k as _}from"./index-CUmHRwBw.js";import{O as A}from"./osmap-C861OkPV.js";import{L as w}from"./localeText-DvaqSAco.js";const R={name:"traceroute",components:{LocaleText:w,OSMap:A},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:g()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,b("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},M={class:"mt-md-5 mt-3 text-body"},S={class:"container-md"},$={class:"mb-3 text-body"},C={class:"d-flex gap-2 mb-3 flex-column"},L={class:"flex-grow-1"},P={class:"mb-1 text-muted",for:"ipAddress"},O=["disabled"],V=["disabled"],B={key:0,class:"d-block"},I={key:1,class:"d-block"},N={class:"position-relative"},z={key:"pingPlaceholder"},D={key:1},E={key:"table",class:"w-100 mt-2"},F={class:"table table-sm rounded-3 w-100"},G={scope:"col"},H={scope:"col"},K={scope:"col"},W={scope:"col"},j={scope:"col"},U={scope:"col"},q={key:0},J={key:1};function Q(d,s,X,Y,Z,tt){const a=_("LocaleText"),p=_("OSMap");return l(),o("div",M,[t("div",S,[t("h3",$,[n(a,{t:"Traceroute"})]),t("div",C,[t("div",L,[t("label",P,[t("small",null,[n(a,{t:"Enter IP Address / Hostname"})])]),y(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control rounded-3","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=x(e=>this.execute(),["enter"])),type:"text"},null,40,O),[[f,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 position-relative flex-grow-1",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(c,{name:"slide"},{default:r(()=>[this.tracing?(l(),o("span",I,s[4]||(s[4]=[t("span",{class:"spinner-border spinner-border-sm","aria-hidden":"true"},null,-1),t("span",{class:"visually-hidden",role:"status"},"Loading...",-1)]))):(l(),o("span",B,s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),v("Trace! ")])))]),_:1})],8,V)]),t("div",N,[n(c,{name:"ping"},{default:r(()=>[this.tracerouteResult?(l(),o("div",D,[n(p,{d:this.tracerouteResult,type:"traceroute"},null,8,["d"]),t("div",E,[t("table",F,[t("thead",null,[t("tr",null,[t("th",G,[n(a,{t:"Hop"})]),t("th",H,[n(a,{t:"IP Address"})]),t("th",K,[n(a,{t:"Average RTT (ms)"})]),t("th",W,[n(a,{t:"Min RTT (ms)"})]),t("th",j,[n(a,{t:"Max RTT (ms)"})]),t("th",U,[n(a,{t:"Geolocation"})])])]),t("tbody",null,[(l(!0),o(u,null,m(this.tracerouteResult,(e,et)=>(l(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,[t("samp",null,i(e.ip),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.avg_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.min_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.max_rtt),1)])]),t("td",null,[e.geo.city&&e.geo.country?(l(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):(l(),o("span",J," - "))])]))),256))])])])])):(l(),o("div",z,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(l(),o(u,null,m(5,e=>t("div",{class:k(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:T({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const lt=h(R,[["render",Q],["__scopeId","data-v-3e75b4d4"]]);export{lt as default};
|
||||||
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user