Compare commits

...

402 Commits
v4.0 ... main

Author SHA1 Message Date
dselen
421785bf6a
Merge pull request #675 from mahdiMGF2/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Docker Scan and Build / docker_build_analyze (push) Has been cancelled
Qodana / qodana (push) Has been cancelled
added Farsi language
2025-04-17 23:01:50 +02:00
Mahdi
308e8ca8c7 The Persian language was organized based on the alphabet. 2025-04-13 15:14:01 +03:30
Mahdi
12d1e5b8d0 added Farsi language 2025-04-11 09:04:02 +03:30
dselen
b165cdbd79
Merge pull request #672 from Jumala9163/jumala9163/locale/japanese
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Qodana / qodana (push) Has been cancelled
Add Japanese Language
2025-04-07 16:05:17 +02:00
Donald Zou
a724e1cb58
Update README.md 2025-04-07 17:41:12 +08:00
Donald Zou
f942809de0
Update README.md
Added DO as sponsor!
2025-04-07 15:14:07 +08:00
Donald Zou
8043f77e02
Update README.md 2025-04-06 05:32:15 +08:00
Jumala9163
1db9ba90d8
fix typo 2025-04-06 00:23:30 +09:00
Jumala9163
464fa59cb6
Add Japanese(ja-jp) Language 2025-04-06 00:12:00 +09:00
Donald Zou
a8e2cbf55b
Update README.md 2025-04-05 22:38:20 +08:00
Donald Zou
fecd8dab38
Update README.md 2025-04-05 20:45:37 +08:00
Donald Zou
13a833e3ed
Update README.md 2025-04-04 16:53:17 +08:00
Donald Zou
3888831679
Merge pull request #663 from donaldzou/DaanSelen-patch-3
Update docker-related.yaml
2025-03-26 17:11:02 +08:00
dselen
1a32fad324
Update docker-related.yaml
Added nigthly trigger.
2025-03-26 09:42:11 +01:00
Donald Zou
d842ae9540
Update docker-related.yaml 2025-03-25 15:36:53 +08:00
Donald Zou
d0177b7504
Update docker-related.yaml 2025-03-25 15:17:41 +08:00
Donald Zou
e3842b25f3
Update docker-related.yaml 2025-03-25 15:11:06 +08:00
Donald Zou
a29b59c9cd
Update docker-related.yaml 2025-03-24 17:36:05 +08:00
Donald Zou
f94eb97aa4
Update docker-related.yaml 2025-03-24 12:52:28 +08:00
Donald Zou
86017b79eb
Update docker-related.yaml 2025-03-24 12:50:26 +08:00
Donald Zou
bc22fa5fad
Update docker-related.yaml 2025-03-24 12:42:03 +08:00
Donald Zou
d6b70028ff
Merge pull request #662 from donaldzou/donaldzou-patch-1
Update docker-related.yaml
2025-03-24 05:11:36 +08:00
Donald Zou
0f7f9acd58
Update docker-related.yaml 2025-03-24 05:11:22 +08:00
Donald Zou
20633a6d1a
Update docker-related.yaml 2025-03-24 05:00:45 +08:00
Donald Zou
a23856270d
Merge pull request #661 from donaldzou/DaanSelen-patch-2
Update docker-related.yaml
2025-03-24 04:27:53 +08:00
dselen
55543e370e
Update docker-related.yaml
Workflow fix fix
2025-03-23 21:20:40 +01:00
Donald Zou
8137a46c68
Merge pull request #660 from DaanSelen/workflow-fix
Workflow fix.
2025-03-24 04:16:34 +08:00
Daan
aeb9597c71 Workflow fix. 2025-03-23 20:41:48 +01:00
Donald Zou
0390227641
Update qodana_code_quality.yml
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Qodana / qodana (push) Has been cancelled
2025-03-12 00:36:07 +08:00
Donald Zou
395b0982db
Merge pull request #650 from donaldzou/qodana-automation-897468090
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Qodana / qodana (push) Waiting to run
Add qodana CI checks
2025-03-11 18:00:52 +08:00
Qodana Application
f096ab4da7 Add github workflow file 2025-03-11 10:00:39 +00:00
Qodana Application
d5ec9f7640 Add qodana.yaml file 2025-03-11 10:00:39 +00:00
dselen
95df7de026
Merge pull request #639 from karorogunso/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Add Thai language
2025-02-27 11:51:53 +01:00
Karorogunso
d3a5bd374d
Merge pull request #1 from karorogunso/thai
Add Thai to main brach
2025-02-27 16:44:42 +07:00
Karorogunso
43ac3dddf1
Merge branch 'donaldzou:main' into thai 2025-02-27 16:25:57 +07:00
Karorogunso
1174328de3
Update active_languages.json 2025-02-27 16:24:28 +07:00
dselen
2bc3a75c94
Merge pull request #621 from wdk-kr/korean
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Add Korean Language
2025-02-18 13:04:56 +01:00
완두콩
07ef97ce7c Update active_languages.json 2025-02-18 20:13:52 +09:00
완두콩
5fe3539331 Update ko.json 2025-02-18 15:52:50 +09:00
완두콩
4bc3bd5f13 Update ko.json 2025-02-18 15:51:24 +09:00
완두콩
4abce854d7 Update active_languages.json 2025-02-18 15:36:01 +09:00
완두콩
3b5c73992e Fix incorrect translations 2025-02-18 15:25:10 +09:00
완두콩
c5abea2944 Add Korean Language 2025-02-18 15:11:08 +09:00
dselen
060154cb89
Merge pull request #595 from sobhydo/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Adding Arabic Translation
2025-02-06 14:13:23 +01:00
dselen
99a1bfca9d
Update active_languages.json
removed leading newline
2025-02-06 14:10:10 +01:00
dselen
4379f30628
Update active_languages.json
removed trailing enter.
2025-02-06 14:09:47 +01:00
Ahmed Sobhy
b501244577 Alphabetical order for active languages 2025-02-06 16:53:43 +04:00
Ahmed Sobhy
f0774ec273 Adding Arabic Translation 2025-01-27 23:41:06 +04:00
karorogunso
d4a4d28b58 Add Thai Language 2025-01-27 21:39:06 +07:00
Donald Zou
a62c54b4ed
Merge pull request #576 from petrsimunek/patch-1
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Update cs.json
2025-01-19 21:07:40 +08:00
Donald Zou
41df7c04c3
Merge pull request #585 from donaldzou/fix-#581
Ready for update
2025-01-19 21:03:38 +08:00
Donald Zou
9b783a8322 Ready for update 2025-01-19 21:03:08 +08:00
Donald Zou
57db4df618
Merge pull request #584 from donaldzou/fix-#581
Fixed Job Logger Bug, Restrict Peers with Configuration include special characters
2025-01-19 20:57:04 +08:00
Donald Zou
9d1081bd56 Update dashboard.py
- Fixed #581 issue.
2025-01-19 20:54:19 +08:00
Donald Zou
07a04dc507 Update dashboard.py 2025-01-19 13:20:04 +08:00
Donald Zou
cd1329ec67
Update README.md
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-01-13 01:41:25 +08:00
petrsimunek
48a58b2b69
Update cs.json
Added translation for dashboard IP and port settings
2025-01-11 16:23:29 +01:00
Donald Zou
9b64aba8bf
Merge pull request #575 from mahdiMGF2/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Fixed some syntax error in Peer Jobs
2025-01-09 17:21:22 +08:00
Donald Zou
cae8264d98
Update dashboard.py 2025-01-09 17:13:32 +08:00
Mahdi
95d8985336 Bug fixed
Bug Fixed deletePeerScheduleJob endpoint
2025-01-09 11:38:45 +03:30
Donald Zou
b26ae90807
Merge pull request #574 from donaldzou/v4.1.3-dev
v4.1.3 Ready
2025-01-09 14:02:19 +08:00
Donald Zou
66d171c432 v4.1.3 Ready 2025-01-09 13:42:21 +08:00
dselen
1a878599b1
Merge pull request #549 from alexperreault/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
French translation
2025-01-03 08:39:41 +01:00
alexp
c612022717 alphabetical order 2025-01-02 20:23:52 -05:00
Donald Zou
75747a2979
Merge pull request #568 from donaldzou/fix-backup-folder-not-created
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Create WGDashboard_Backup when configuration initialized
2025-01-02 11:36:11 +08:00
Donald Zou
a85a8668a7 Update dashboard.py 2025-01-01 10:36:44 +08:00
Donald Zou
2ed49abb1b Update dashboard.py
Minor issue
2024-12-31 10:44:27 +08:00
Donald Zou
409e6d49b2 Update dashboard.py
- Fixed `WGDashboard_Backup` not being created and caused crash
2024-12-31 10:33:28 +08:00
Donald Zou
85be6d53d0
Merge pull request #566 from donaldzou/fix-edit-configuration
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Edited configuration not updating to dashboard
2024-12-30 20:33:10 +08:00
Donald Zou
bf6f58eb5e Remove with sqldb in SQL Select 2024-12-30 20:31:24 +08:00
Donald Zou
e0bc6a10d0 Edited configuration not updating to dashboard 2024-12-29 16:37:19 +08:00
Donald Zou
715a266ca4
Merge pull request #563 from donaldzou/fix-#562
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Fix #562, and mysterious Jobs disappear issue
2024-12-28 23:53:35 +08:00
Donald Zou
fa4b3ece56 Log the error instead of remove the job 2024-12-28 21:01:21 +08:00
Donald Zou
aac2a002bb
Delete .github/workflows/main.yml
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-12-28 01:34:33 +08:00
Donald Zou
8574acaf6e
Create main.yml 2024-12-28 01:27:25 +08:00
Donald Zou
ddf4639354
Update README.md 2024-12-28 01:26:47 +08:00
Donald Zou
9bd394f351 Update dashboard.py 2024-12-27 03:09:27 +08:00
Donald Zou
e58b1d670b
Update README.md
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-12-15 21:37:45 +08:00
alexp
af5e7974c3 Added the french language 2024-12-07 21:29:59 -05:00
Donald Zou
4524a55b23
Merge pull request #527 from donaldzou/fix-#516
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Security Patch
2024-11-25 20:41:51 +08:00
Donald Zou
f942eaf1b6 Ready for release 2024-11-25 18:23:48 +08:00
Donald Zou
9287e81ef1 Build 2024-11-25 01:53:29 +08:00
Donald Zou
5462326f79 Updated dashboard.py and DashboardConfigurationStore.js
- Added `session.clear()` to clean the session specific to each login session
- Clear all cookie with the `signout` request and also clear again (just in case) in the frontend code.
2024-11-25 01:46:27 +08:00
Donald Zou
fa04ad1395
Merge pull request #518 from donaldzou/v4.1.1-dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Ready for new update
2024-11-23 15:57:28 +08:00
Donald Zou
abdd85bdd5 Ready for new update 2024-11-23 15:37:00 +08:00
Donald Zou
dba55d57e8
Merge pull request #488 from donaldzou/language-template
Added template and script to check local files
2024-11-23 15:18:14 +08:00
Donald Zou
9819c96717 Update verify_locale_files.py 2024-11-23 15:09:35 +08:00
Donald Zou
1b0885bffe Update verify_locale_files.py 2024-11-23 14:55:07 +08:00
Donald Zou
c0a8540ab8 Update tr-tr.json 2024-11-23 14:38:15 +08:00
Donald Zou
f3b95f03a1 Update active_languages.json 2024-11-23 13:46:27 +08:00
Donald Zou
5f06f3da52 Update sv-se.json 2024-11-23 13:46:20 +08:00
Donald Zou
10a7fb809b Update pl.json 2024-11-23 13:37:27 +08:00
Donald Zou
d3ea1f3da2 Update nl-nl.json
Fixed translation
2024-11-23 13:36:58 +08:00
Donald Zou
74d0471a6f Update verify_locale_files.py 2024-11-23 13:23:50 +08:00
Donald Zou
a1c1805409 Updated it-it.json 2024-11-23 13:23:47 +08:00
Donald Zou
b843145bed Update de-de.json
Fixed de-de translations
2024-11-23 13:15:03 +08:00
Donald Zou
119920b665 Update ru.json
Fixed translations
2024-11-22 19:36:11 +08:00
Donald Zou
6190e2d290 Fixed cs.json 2024-11-22 01:46:52 +08:00
Donald Zou
79de99d146 Finalized verify script 2024-11-22 01:41:11 +08:00
Donald Zou
56a9b3df0a
Merge pull request #514 from MickLesk/patch-1
Update de-de.json
2024-11-22 01:32:56 +08:00
Donald Zou
4df6413dba
Merge pull request #513 from oskarax/main
Added Swedish translations and updated active languages file.
2024-11-22 01:30:28 +08:00
Donald Zou
fcd0ada639
Merge branch 'language-template' into main 2024-11-22 01:30:17 +08:00
Donald Zou
6b6bd155aa
Merge pull request #512 from donaldzou/main
Merging main into language template branch
2024-11-22 01:28:23 +08:00
CanbiZ
9c91b1bca5
Update de-de.json 2024-11-18 23:05:05 +01:00
Oskar Ax
1a5c0e5b24 Added Swedish translations and updated active languages file. 2024-11-18 21:08:06 +01:00
Donald Zou
981b30e4af Update check script 2024-11-17 17:20:41 +08:00
Donald Zou
30c84d8cbf
Merge pull request #502 from AdimoUK/main
Merge spanish translation
2024-11-16 19:17:46 +08:00
Donald Zou
4c538c54a8
Merge pull request #501 from AdimoUK/polish-language
Merge Polish translation
2024-11-16 19:12:01 +08:00
dselen
ad7a8f1d08
Merge pull request #496 from DaanSelen/v4.1-add-qemu
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Previous PR was merged too fast 🥇
2024-11-15 12:11:18 +01:00
Daan
f02a07dab4 Name change 2024-11-15 12:08:51 +01:00
dselen
c61b0fc1e1
Merge pull request #494 from donaldzou/fix-preshared-key
Fixed #377
2024-11-15 12:06:14 +01:00
Daan
fed7dfcb73 Added arm/v6
Specified the QEMU setup. From WireGate
2024-11-15 12:05:08 +01:00
Donald Zou
0d69c811ab
Merge pull request #495 from DaanSelen/v4.1-add-qemu
Added QEMU virtualization for cross-compilation
2024-11-15 18:59:48 +08:00
Daan
83274add22 Added QEMU virtualization for cross-compilation @NOXCIS 2024-11-15 11:35:45 +01:00
Donald Zou
7497d1b6d4 Fixed #377
Fixed Preshared Key is not added when adding peers
2024-11-15 13:45:14 +08:00
Donald Zou
239bc144e3 Fixed both Chinese translation 2024-11-15 12:00:31 +08:00
Donald Zou
1ece64abe1
Merge pull request #492 from DaanSelen/language-template
Proposed changes
2024-11-15 11:52:13 +08:00
Daan
915783699b Proposed changes 2024-11-14 21:36:27 +01:00
Donald Zou
43f6bd41c9 Update verify_locale_files.py 2024-11-15 02:15:40 +08:00
Adam
98c017dd56 Fix to a translation 2024-11-14 00:09:59 +00:00
Donald Zou
811ed3251b
Merge pull request #464 from jpizquierdo/v4.1-dev
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-14 02:06:25 +08:00
Donald Zou
665b0f1484 Added template and script to check local files 2024-11-14 02:02:26 +08:00
Donald Zou
9e26d845da
Update active_languages.json
Oops.. missed a comma
2024-11-14 00:59:17 +08:00
Donald Zou
6ddf20f5ce
Update active_languages.json
Sorting the list based on `lang_id`
2024-11-14 00:53:26 +08:00
dselen
27ed0710cc
Merge pull request #487 from donaldzou/donaldzou-patch-1
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Update README.md Discord link
2024-11-13 15:08:24 +01:00
Donald Zou
cb87c9f345
Update README.md Discord link 2024-11-13 21:12:45 +08:00
Donald Zou
21730102ae
Merge pull request #474 from donaldzou/DaanSelen-lang-1
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-11 19:12:12 +08:00
Donald Zou
b1ae05152e
Merge pull request #471 from kaanklky/languages-tr-tr 2024-11-11 19:05:53 +08:00
Adam
cc87f01e2f Addition of Polish Language 2024-11-10 22:07:20 +00:00
dselen
85dfa1b078
Update nl-nl.json 2024-11-10 13:53:47 +01:00
Donald Zou
fdff54e11e
Merge pull request #469 from DaanSelen/main
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-10 09:02:06 +08:00
Kaan Kölköy
0894f38660 Update active languages list 2024-11-09 22:40:04 +01:00
Kaan Kölköy
f643d8ef25 Add Turkish localization 2024-11-09 22:39:51 +01:00
dselen
e437284980
Squash Docker progress: (#1)
* Version 4.1 Docker image tested.

    Fixed kinks in Docker image.
    Updated Dutch language
    Removed remaining "enable" parameter from Docker-related files
    Made the symlink system more reliable
    Improved updatability.

    Added multiplatform docker build (arm,arm64 and amd64)
    More verbose logging from the Docker image.
2024-11-09 00:18:01 +01:00
Donald Zou
f6e0d330ac update
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2024-11-09 02:17:21 +08:00
Donald Zou
890cbf0f36
Merge pull request #468 from donaldzou/issue-discord-link
Fix Discord Link Under Help
2024-11-09 00:49:46 +08:00
Donald Zou
36cf2ea2e8
Merge branch 'main' into issue-discord-link 2024-11-09 00:49:26 +08:00
Donald Zou
a8f7bd0280 Build 2024-11-09 00:48:16 +08:00
Donald Zou
aa6517046d
Merge pull request #467 from donaldzou/issue-#462
Fix #462
2024-11-09 00:44:45 +08:00
Donald Zou
42e4d8c7ba build 2024-11-09 00:40:42 +08:00
Joel Pérez Izquierdo
3d1da38cbc add es-es locale file 2024-11-08 17:29:58 +01:00
Joel Pérez Izquierdo
5ae8490999 add spanish language 2024-11-08 17:28:57 +01:00
Donald Zou
715675b2f1
Merge pull request #458 from donaldzou/donaldzou-patch-1
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Update README.md
2024-11-08 16:17:28 +08:00
Donald Zou
0d7198a26c
Update README.md 2024-11-08 16:17:15 +08:00
Donald Zou
d8b7ce6d9b Update README.md 2024-11-08 16:16:44 +08:00
Donald Zou
d032ca31e3 Update README.md 2024-11-08 16:15:56 +08:00
Donald Zou
67b49c0585
Merge pull request #457 from donaldzou/v4.1-dev
Final update
2024-11-08 16:14:14 +08:00
Donald Zou
c23242f18e Final update 2024-11-08 16:13:47 +08:00
Donald Zou
c23f7a3ee2
Merge pull request #440 from donaldzou/v4.1-dev
V4.1 dev
2024-11-08 16:13:22 +08:00
Donald Zou
7e3e957649 Update ru.json 2024-11-08 00:50:57 +08:00
Donald Zou
b8f304dfd3 Prepare for release 2024-11-08 00:31:19 +08:00
Donald Zou
e895ac9245
Merge branch 'main' into v4.1-dev 2024-11-08 00:29:01 +08:00
Donald Zou
77579a71e8 Match docker 2024-11-07 23:54:48 +08:00
Donald Zou
cc7e13cdbf
Merge pull request #455 from DaanSelen/v4.1-dev
Added Dutch language.
2024-11-07 23:53:48 +08:00
Donald Zou
5df3886e42
Merge branch 'v4.1-dev' into v4.1-dev 2024-11-07 23:50:54 +08:00
Donald Zou
cc179a05d0 Update 2024-11-07 23:47:08 +08:00
Donald Zou
ec5f4f2778 Fixed some CSS issue on mobile 2024-11-07 23:43:14 +08:00
Donald Zou
084c95f0e5 Just fixed #455 2024-11-07 18:33:39 +08:00
Daan
3b78cfe0fd Renamed files and changed Dutch file. 2024-11-07 11:26:37 +01:00
Daan
160ce3338d Changed some file-names 2024-11-07 11:25:05 +01:00
Donald Zou
d425cfe1aa Refactor 2024-11-07 14:56:02 +08:00
Donald Zou
6ff286f9b4 Refactor 2024-11-07 14:54:42 +08:00
Donald Zou
b930461434 Refactored some files 2024-11-07 14:53:31 +08:00
Donald Zou
ee6bb24506 build test 2024-11-07 10:37:11 +08:00
Donald Zou
b69124c89f test 2024-11-07 00:15:28 +08:00
Donald Zou
f089e4a1ce update 2024-11-07 00:09:40 +08:00
Donald Zou
7dedb5c076 Test adding hash to vite build 2024-11-07 00:03:40 +08:00
Donald Zou
3276c9a84c Update 2024-11-06 23:25:20 +08:00
Donald Zou
04ef2ea3b6 Merge branch 'v4.1-dev' of https://github.com/donaldzou/WGDashboard into v4.1-dev 2024-11-06 23:22:01 +08:00
Donald Zou
04a2f27a75 Update 2024-11-06 23:21:53 +08:00
Donald Zou
d962f59884
Merge pull request #452 from jursed/v4.1-dev
Czech translation
2024-11-06 21:40:18 +08:00
Donald Zou
fd3bd4567a
Update active_languages.json
Removed the `,` at the end :)
2024-11-06 21:12:55 +08:00
Donald Zou
29e7a5ecdb Fixed bulk add 2024-11-06 20:58:53 +08:00
Donald Zou
4956b0d89d Rename configuration done 2024-11-06 18:36:55 +08:00
Donald Zou
3bc54a4e16 Update wgd.sh 2024-11-05 19:46:09 +08:00
Donald Zou
29ecd602ec Added help modal 2024-11-05 19:43:47 +08:00
zire
1425dec564 Czech translation
First attempt at Czech translation. Note that some words don't have
a good and short translation, e.g. "peers", "pre-shared key" or
"persistent keepalives". In these cases, some approximate/familiar
"Czech-English" amalgamation is used.
2024-11-03 22:05:13 +01:00
Donald Zou
2bb1c0c999 Optimized build 2024-11-03 21:06:51 +08:00
Donald Zou
97f3daae70 Optimized vite build 2024-11-03 20:45:59 +08:00
Donald Zou
c53a7ef6fe Update 2024-11-03 19:09:15 +08:00
Donald Zou
b97fc16ad9 Adjusted router to dynamic import 2024-11-03 18:35:21 +08:00
Donald Zou
eaac12ddc8 Update both Chinese languague 2024-11-03 17:36:03 +08:00
Donald Zou
183be5da0e
Update README.md
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
testing webhooks
2024-11-03 15:58:34 +08:00
Donald Zou
ace0953c87
Update README.md 2024-11-03 15:26:33 +08:00
Donald Zou
1fd7e7833d
Update README.md 2024-11-03 15:20:41 +08:00
Donald Zou
aa5801d73b
Update README.md 2024-11-03 14:41:21 +08:00
Donald Zou
d1ea8081e4 Finished zh-CN 2024-11-02 18:50:15 +08:00
Donald Zou
49467c906d zh-CN Update 2024-11-02 14:26:47 +06:00
Donald Zou
79bd575aca
Merge pull request #448 from donaldzou/DaanSelen-patch-1
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Hotfix.
2024-11-02 16:20:35 +08:00
Donald Zou
e533a0e405
Merge pull request #445 from knd775/patch-1
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
feat: Support Rocky Linux
2024-11-01 23:24:47 +08:00
Donald Zou
94b597d29a Adjusted some UI 2024-11-01 22:30:25 +08:00
dselen
504fefff94
Update docker-build.yaml 2024-11-01 09:19:47 +01:00
dselen
ff794a3638
Update docker-analyze.yaml
I switched them around 😭
2024-11-01 09:15:46 +01:00
Donald Zou
efb9a34cb8
Merge pull request #447 from DaanSelen/workflow-change
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
2024-11-01 16:11:26 +08:00
Daan
a93291b38f Changed the workflow from every night to: on every commit in the main branch. 2024-10-31 20:16:45 +01:00
Donald Zou
dfc9eab9d3 Fixed some issue on autostart 2024-10-31 23:28:30 +08:00
Donald Zou
3c74b0b1ef Update 2024-10-31 22:13:44 +08:00
Donald Zou
9b981fcea8 Autostart feature is done 2024-10-31 22:13:00 +08:00
Ben Ayles
9d3a189d77
fix: Support Rocky Linux 2024-10-29 23:02:59 -04:00
Donald Zou
01c0175e8f Commit 2024-10-29 14:57:29 +08:00
Donald Zou
d7e5e2f381 Update wgd.sh 2024-10-26 18:09:42 +08:00
Donald Zou
c27de8b9a5 Build 2024-10-26 13:54:08 +08:00
Donald Zou
c3a55f8b69 Finished create configuration from backup 2024-10-25 23:34:07 +08:00
Donald Zou
78b65a799e Added notification to backup before delete 2024-10-25 23:33:42 +08:00
Donald Zou
6a30cee611 Adjusted some animation 2024-10-25 23:33:26 +08:00
Donald Zou
bc19e3a6ff Adjusted title 2024-10-25 23:33:07 +08:00
Donald Zou
5a8f2fa2be Adjusted some animation 2024-10-25 23:32:30 +08:00
Daan
81168c27c6 Fixed issue https://github.com/donaldzou/WGDashboard/issues/329.
Regarding being able to pass in the -y flag.
2024-10-24 23:10:36 +02:00
Donald Zou
a606626053 UI for restore configuration is done 2024-10-25 00:19:27 +08:00
Daan
adeb57864b Fixed incorrect Docker_IMAGE variable from dselen/ -> donaldzou/ 2024-10-24 10:48:14 +02:00
Daan
747f1a6fae SEC: Fixed CVE-2024-9143 presence. 2024-10-24 10:24:22 +02:00
Daan
3ac9c23573 Removed the default value: wg0 in isolate and enable.
Removed clean_up() function because persistency is done differently.
Overal tried to make readability better in entrypoint.sh
Fixed bug where local config variable causes issues.
Applied ShellCheck recommendations.
2024-10-24 10:13:33 +02:00
Daan
5ad9c0e77a Fixed issue where the wg0.conf template got obliterated.
Moved it to a safe spot.
2024-10-24 00:23:12 +02:00
Daan
ba5ba2f1d6 Removed copy step in entrypoint.sh
Tested updating, works as long as presistent files are compatible.
2024-10-24 00:09:27 +02:00
Daan
4902b5f351 Initial testing to update from version 4.0.3 to 4.0.4 have succeeded! 2024-10-23 23:47:00 +02:00
Daan
166fcda193 Minor changes to compose and Dockerfile. 2024-10-23 23:15:41 +02:00
Daan
83560bc775 Changed around Docker image building and entrypoint.
- Succeeding my tests.
2024-10-23 22:40:40 +02:00
Daan
4ffb00c9f5 Updated ensure install. 2024-10-23 16:57:51 +02:00
Daan
fbac41a774 Changed ensure install 2024-10-23 16:57:40 +02:00
Daan
c837ab8693 Complete Docker Container redo, making updates possible.
- Through symlinks.

Refactored the set env variables function.
2024-10-23 16:41:03 +02:00
Donald Zou
1cc321ddff
Merge pull request #436 from donaldzou/v4.1-workflows
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
V4.1 workflows
2024-10-23 17:30:33 +08:00
dselen
7861cffb91
Merge pull request #430 from DaanSelen/main
Modified GitHub workflows
2024-10-22 08:52:52 +02:00
Donald Zou
82a472f368 Delete configuration, restore configuration 2024-10-22 12:28:51 +08:00
Daan
cfe59774e7 Changed Docker image names: dselen -> donaldzou 2024-10-21 12:09:53 +02:00
Daan
1098475473 Changed failing criteria 2024-10-21 12:07:33 +02:00
Donald Zou
4546e795ef
Merge pull request #433 from reloadlife/patch-1
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Added a try/catch statement to prevent panel from crashing #432
2024-10-21 15:37:49 +08:00
Donald Zou
bb0aba586b
Update dashboard.py
Instead of catching one sql statement error, I moved the catch statement to `sqlSelect` to prevent all database error
2024-10-20 16:05:32 +08:00
Mohammad Mahdi "Mamad" Afshar
204b995e6c
added a try/catch statement to prevent panel from crashing #432 2024-10-19 19:25:38 +03:30
Daan
321b7b4cee Modified GitHub workflows 2024-10-17 12:52:34 +02:00
Donald Zou
413377fbb9 Backup and restore function is done
Completed with SQLDump and .conf backup
2024-10-17 00:04:26 +08:00
Donald Zou
e2e821881c Peer restore works
Still need to SQL Dump the table aswell
2024-10-16 17:44:49 +08:00
Donald Zou
51712ed2a8 Re-adjust backup & restore location 2024-10-15 23:07:49 +08:00
Donald Zou
27de7ddbf8 Still working on backup & restore 2024-10-15 00:30:20 +08:00
Donald Zou
bb700f3a3d Update selectPeers.vue 2024-10-14 17:27:34 +08:00
Donald Zou
563268558b Finished selecting peers in bulk to delete and download 2024-10-14 16:32:17 +08:00
Donald Zou
56744cec7b Commit 2024-10-06 23:09:55 +08:00
Donald Zou
87696a2e6c Fixed 2024-10-06 17:27:16 +08:00
Donald Zou
79f1c20f8a Added custom build.sh 2024-10-06 17:24:53 +08:00
Donald Zou
4e5638df36 Fixed issue #346 2024-10-06 17:13:50 +08:00
Donald Zou
71349f35e4 Fixed issue #352
Fixed issue when allowed_ips have more than 1 IP Address, allow access will crash
2024-10-06 16:59:11 +08:00
Donald Zou
2cb06bb4bb Added total peers in peers count 2024-10-05 16:10:36 +08:00
Donald Zou
5e1769b81f Updated Translation 2024-10-05 15:38:56 +08:00
Donald Zou
e344f28265 Added peer's endpoint IP back 2024-10-05 15:03:27 +08:00
Donald Zou
2297d6b85b
Merge pull request #417 from donaldzou/v4.0.4-almalinux-support
Added AlmaLinux Support
2024-10-05 10:24:46 +08:00
Donald Zou
baaecdbd8c
Update wgd.sh 2024-10-05 10:05:48 +08:00
Donald Zou
31d8af642d
Merge pull request #363 from martin-g-it/patch-1
Update dashboard.py - sort WG configurations
2024-10-04 20:15:04 +08:00
Donald Zou
27c67ec202 Added loading bar between each routes 2024-10-04 17:48:24 +08:00
Donald Zou
4833a29e57 Adjusted some transition between routes 2024-10-04 17:27:25 +08:00
Donald Zou
4a2f3e0372 Configuration Settings done 2024-10-04 16:58:47 +08:00
Donald Zou
f3eeff4ec8
Merge pull request #415 from donaldzou/DaanSelen-patch-1
Fix README.md
2024-10-04 16:22:16 +08:00
dselen
221e03ecfa
Fix README.md 2024-10-03 16:03:42 +02:00
dselen
392a9c6f53
Merge pull request #414 from DaanSelen/main
Second try. Merged Docker update.
2024-10-03 15:59:33 +02:00
Dselen
145d12b2c8 Added minor changes and deletions. 2024-10-03 08:26:30 -05:00
Dselen
0c5033ff79 fixed issues with commits 2024-10-03 08:23:17 -05:00
Donald Zou
5f46f54dfd Updated mobile UI
Using dvh and vh as fallback for mobile browsers.
2024-10-03 21:20:15 +08:00
Dselen
d4819b13eb working tests 2024-10-03 08:15:21 -05:00
Donald Zou
9dd9be3b8c
Merge branch 'main' into main 2024-10-03 20:59:58 +08:00
Dselen
dd38809866 Rebase 2024-10-03 07:45:24 -05:00
Donald Zou
c414725f12
Merge pull request #406 from 3vis97/v4.1-dev-italian
Added italian language issues/#397
2024-10-03 20:13:46 +08:00
Donald Zou
d3c8a350a4
Merge branch 'v4.1-dev' into v4.1-dev-italian 2024-10-03 20:13:38 +08:00
Donald Zou
e04b748b91
Merge pull request #345 from DaanSelen/conflict-resolved
Updated Docker image
2024-10-03 20:09:31 +08:00
Donald Zou
1eee8c4725 Update 2024-10-03 20:07:50 +08:00
dselen
2b7a4b170c
Merge branch 'main' into conflict-resolved 2024-10-03 12:17:18 +02:00
Donald Zou
7c0bf4f137 Fixed #357: Brought back IP Address and Port
But still manually restart WGDashboard is needed
2024-10-03 15:24:50 +08:00
Donald Zou
54bae43d2e Update osmap.vue
Added "Dark Mode" to OSM
2024-10-02 22:00:53 +08:00
Donald Zou
25be1155a6 Added testing to OSM before loading map
Prevent users in locations blocked OSM seeing an empty div
2024-10-02 21:53:57 +08:00
Donald Zou
4905d61a1a Some adjustment on map 2024-10-02 18:01:20 +08:00
Donald Zou
ff0147bebb Added OpenStreetMap for Ping and Traceroute 2024-10-02 17:09:35 +08:00
Donald Zou
7fe4889b6e Updated some languages 2024-10-02 17:09:04 +08:00
Donald Zou
3c9b1b1833 Thanks to Pixnet for providing the Russian translation :) 2024-09-27 22:07:50 +08:00
Dselen
2a46c873b8 Removed Debian container 2024-09-27 03:22:03 -05:00
Trevis97
6ed09324ad Updated Italian translations and fixed typos upstream/issues/#397 2024-09-26 22:32:43 +02:00
Mattia Trevisani
d1f9c10790 Added italian language upstream/issues/#397 2024-09-26 22:31:27 +02:00
Donald Zou
5d041b2fd3
Update README.md 2024-09-25 18:01:05 +08:00
Donald Zou
5cea0fa87b
Merge pull request #401 from orangeferdi/patch-3
Create de.json
2024-09-25 00:11:05 +08:00
Donald Zou
6f140eef29
Merge pull request #400 from orangeferdi/patch-2
Update active_languages.json
2024-09-25 00:10:52 +08:00
Donald Zou
e5850adfd7 Update dashboard.py 2024-09-24 22:54:18 +08:00
orangeferdi
6921833ce2
Create de.json
Adding german language
2024-09-24 10:13:34 +02:00
orangeferdi
57b9accd97
Update active_languages.json
Adding german language
2024-09-24 10:10:16 +02:00
Donald Zou
de94f5b233
Update README.md 2024-09-24 00:40:20 +08:00
Donald Zou
b5519a73fb
Merge pull request #398 from shuricksumy/v4.1-dev-uk
Add Ukrainian language
2024-09-23 16:32:00 +08:00
Oleksandr Suchkov
c5d8c2c355 Add Ukrainian language 2024-09-22 23:58:38 +01:00
Donald Zou
c5b02a426c
Update README.md 2024-09-23 03:12:06 +08:00
Donald Zou
4cae910b68 Added some update :) 2024-09-23 03:07:48 +08:00
Donald Zou
b664fccce2 Finished Chinese Simplified and Traditional translation 2024-09-23 00:17:30 +08:00
Donald Zou
21672f99d1 Translating to zh-cn is done 2024-09-22 21:50:30 +08:00
Donald Zou
c269e46892 Added some new translation 2024-09-22 16:44:36 +08:00
Donald Zou
8534e8cf5b Still working on translating.... 2024-09-22 16:33:22 +08:00
Donald Zou
94bf1c2484 Finished translating most of the UI. Left with notifications 2024-09-19 22:32:15 +08:00
Donald Zou
b3b30470fc Merge branch 'main' of https://github.com/donaldzou/WGDashboard 2024-09-19 14:45:11 +08:00
Donald Zou
41d91e75fc Prepare for v4.0.4 2024-09-19 14:44:49 +08:00
Donald Zou
a97a91b844
Merge pull request #395 from donaldzou/fix-#391
Fixed issue where Preshared Key is not added when unrestricted peers
2024-09-19 14:31:41 +08:00
Donald Zou
f1c577ab76 Fixed issue mentioned in #391 2024-09-19 14:21:38 +08:00
Donald Zou
17a9fe5024 Fixed issue mentioned in #391 2024-09-17 14:42:25 +08:00
Donald Zou
d74a76dee3
Merge pull request #389 from donaldzou/v4.0.3-fix
Merge new changes to v4.1
2024-09-14 16:23:17 +08:00
Donald Zou
c01201b88e
Merge branch 'v4.1-dev' into v4.0.3-fix 2024-09-14 16:23:08 +08:00
Donald Zou
833bdf878a Update dashboard.py 2024-09-14 15:49:41 +08:00
Donald Zou
891990b2f1
Merge pull request #387 from donaldzou/v4.0.3-fix
Ready for v4.0.3
2024-09-14 15:44:26 +08:00
Donald Zou
e9ab7029c9 Ready for v4.0.3 2024-09-14 15:21:10 +08:00
Donald Zou
6f681dba09
Merge pull request #386 from donaldzou/v4.0.3-fix
Update privatePublicKeyInput.vue
2024-09-14 15:14:50 +08:00
Donald Zou
b3edff947d Update privatePublicKeyInput.vue
Fixed issue mentioned in #375
2024-09-14 15:13:47 +08:00
Donald Zou
ce6d80d601 Update dashboard.py 2024-09-14 15:11:06 +08:00
Donald Zou
a80a2866de Almost done... 2024-09-13 16:32:56 +08:00
Donald Zou
02c2221970 Still working on localization 2024-09-12 15:21:42 +08:00
Donald Zou
d35bd6e75b
Merge pull request #379 from donaldzou/DaanSelen-patch-1
Update README.md
2024-09-12 12:17:24 +08:00
dselen
f3a2f98864
Update README.md
Removed Docker notice, because it is no longer relevant.
2024-09-10 10:12:57 +02:00
Donald Zou
a3a312e3db Still working on translation... 2024-09-09 23:43:55 +08:00
dselen
f5cb5c4516
Merge branch 'main' into conflict-resolved 2024-09-09 09:01:07 +02:00
Donald Zou
d458a28337 Started working on localization 😏 2024-09-06 22:38:56 +08:00
Donald Zou
a102a780f8 Adjusted search functions 2024-09-06 17:15:38 +08:00
Donald Zou
4dbbc32108 Updated Bootstrap Icons 2024-09-06 16:32:05 +08:00
Donald Zou
b6aedb43ee Fixed updating WG configuration path 2024-09-06 16:31:54 +08:00
Donald Zou
ec50dcbbd9 Preshared Key switch is added for both single and bullk add peers 2024-09-05 17:10:24 +08:00
Donald Zou
bcc983f11f Update presharedKeyInput.vue
Added preshared key switch
2024-09-05 16:43:46 +08:00
Donald Zou
809651054e Update dashboard.py 2024-09-05 16:17:56 +08:00
Donald Zou
2e965ceb9e Update dashboard.py 2024-09-05 14:51:00 +08:00
Martin
e35f942964
Update dashboard.py - sort WG configurations
Sort WG configurations alphabetically
2024-09-04 14:40:04 +02:00
Dselen
40e6fce281 Fix typos 2024-08-27 02:30:01 -05:00
dselen
2139865876
Merge pull request #1 from DaanSelen/dev
Dev
2024-08-27 09:28:16 +02:00
Dselen
c3cda05d98 Move fix. 2024-08-27 02:26:19 -05:00
Dselen
548f3db33d quickfix 2024-08-26 16:16:43 -05:00
Dselen
a76e9ed98b Testing more changes for better handling of variables. 2024-08-26 16:16:09 -05:00
Dselen
c0ef41a9bb Forgot to reorder 2024-08-26 15:54:27 -05:00
Dselen
f6e5d9675a Alternative testing. 2024-08-26 15:53:53 -05:00
Dselen
ef028659d8 Testing improvement 2024-08-26 15:46:17 -05:00
Dselen
40f39e918d Finished work for now on the alpine docker image. 2024-08-26 15:28:27 -05:00
Dselen
2ec3ee2734 Fixed typo 2024-08-26 13:42:08 -05:00
Dselen
bc29b89a16 Rebased and going further 2024-08-26 13:07:42 -05:00
Donald Zou
e21853286e Did some refactor on wgd.sh 2024-08-25 16:26:36 +08:00
Donald Zou
c012b8c4a5
Merge pull request #340 from donaldzou/v4.0-alpine-linux
V4.0 alpine linux
2024-08-25 16:19:23 +08:00
Donald Zou
48f6c28556
Merge pull request #334 from NOXCIS/main
Fixed Docker Image
2024-08-25 16:18:34 +08:00
Noxcis
0c1502f801 Streamiline
+ Added Docker Install arg to wgd.sh
2024-08-25 03:01:21 -05:00
Donald Zou
fec20ed381 Reduced the time to open the config file 2024-08-25 15:59:48 +08:00
Donald Zou
252c147dcf Update dashboard.py 2024-08-25 15:15:07 +08:00
Donald Zou
453d474104 Fixed multiple IP address on a Configuration 2024-08-25 15:14:09 +08:00
Donald Zou
84cf4a9b66 Update README.md 2024-08-25 11:43:06 +08:00
Noxcis
fb016bebde Update wgd.sh 2024-08-24 20:04:07 -05:00
Noxcis
8f6a738481 Docker 2 Stage 2024-08-24 20:02:34 -05:00
Noxcis
b07f958577 Update compose.yaml 2024-08-24 06:46:06 -05:00
Noxcis
8da0fde52a + 2024-08-24 06:45:13 -05:00
Donald Zou
39be16cb63
Update README.md 2024-08-24 19:37:18 +08:00
Donald Zou
59d0c0def4
Merge pull request #337 from donaldzou/v4.0-alpine-linux
V4.0 alpine linux
2024-08-24 16:30:43 +08:00
Donald Zou
79c03db9a0 Update 2024-08-24 16:27:02 +08:00
Noxcis
0c77823020
Update main.yml 2024-08-24 03:00:51 -05:00
Noxcis
deed7e0022
Update main.yml 2024-08-24 02:56:40 -05:00
Noxcis
99db8c7335
Update main.yml 2024-08-24 02:53:30 -05:00
Noxcis
9fe2aa9ed5
Update main.yml 2024-08-24 02:49:51 -05:00
Noxcis
4c80dc256b
Update main.yml 2024-08-24 02:46:43 -05:00
Noxcis
cafe9e9c11
Update main.yml 2024-08-24 02:41:57 -05:00
Noxcis
27ff4e63b6
Update main.yml 2024-08-24 02:38:10 -05:00
Noxcis
8020714e07
Update main.yml 2024-08-24 02:33:56 -05:00
Noxcis
dbd825ba4b
Update main.yml 2024-08-24 02:28:35 -05:00
Noxcis
fee6cf29eb
Update main.yml 2024-08-24 02:26:30 -05:00
Noxcis
56287d8e7a
Update main.yml 2024-08-24 02:18:21 -05:00
Noxcis
45504eaf95
Update main.yml 2024-08-24 02:15:41 -05:00
Noxcis
b8a9b1150a
Update main.yml 2024-08-24 02:13:04 -05:00
Donald Zou
8bd0e43f58 Update wgd.sh 2024-08-24 15:12:28 +08:00
Noxcis
2c83e9e83c
Update main.yml 2024-08-24 02:06:57 -05:00
Noxcis
53c9ca10a7
Update main.yml 2024-08-24 02:04:46 -05:00
Noxcis
75fbdac42e
Update main.yml 2024-08-24 01:40:34 -05:00
Noxcis
09d54546ca
Update main.yml 2024-08-24 01:34:03 -05:00
Noxcis
b62fece3d0
Update main.yml 2024-08-24 01:29:51 -05:00
Noxcis
284a2b7f64
Update main.yml 2024-08-24 01:25:50 -05:00
Noxcis
9c873ccbbd
Update main.yml 2024-08-24 01:22:37 -05:00
Noxcis
5f72f90031
Update main.yml 2024-08-24 01:18:49 -05:00
Noxcis
93cf3c69b8
Update main.yml 2024-08-24 01:04:28 -05:00
Noxcis
88f856cbc7
Create DockerScout.yml 2024-08-24 01:01:56 -05:00
Noxcis
2d5796d161 Added Auto Config Creation
Reimplemented Automatic Wireguard Configuration Generation

Setting global Env Vars via the docker image build is still insecure, better to pass to dashboard before init.
2024-08-23 16:49:54 -05:00
Dselen
1d20dc9fcb Looking like a promising end of this task. 2024-08-23 13:01:50 -05:00
Dselen
49502235b5 These needed to be added. 2024-08-23 12:48:33 -05:00
Dselen
6e9d71fcf8 Added reverted some no longer needed changes 2024-08-23 12:48:16 -05:00
Dselen
27c7e33773 added RHEL etc workings. 2024-08-23 12:27:41 -05:00
Dselen
3012619049 testing 2024-08-23 11:58:14 -05:00
dselen
d6801966c4
Merge branch 'donaldzou:main' into main 2024-08-23 16:19:58 +02:00
Dselen
518e29118c Reoganise the documents and added experimental Alpine Linux support in wgd.sh 2024-08-23 07:46:41 -05:00
Noxcis
acf4f3fbf0 Merge branch 'main' of https://github.com/NOXCIS/WGDashboard 2024-08-22 23:16:46 -05:00
Noxcis
8378030c70 Fixed Docker Vulnerability
+ Switched Base Image to Alpine
+ Simplified Docker Build
+ Added Alpine support to wgd.sh script.
+ Maintained Project Layout.
2024-08-22 23:15:39 -05:00
Donald Zou
dc7140d486
Update README.md 2024-08-23 09:24:18 +08:00
Dselen
e3771a1c53 Refined logging output a bit. 2024-08-22 16:58:29 -05:00
Dselen
2e9ac00a42 modified all and patched security vulnerability issue #333 2024-08-22 16:31:47 -05:00
Dselen
4b8b3acd39 Small readme change 2024-08-22 14:00:55 -05:00
Dselen
8703798ca0 Modified all files and have a working product, awaiting feedback! 2024-08-22 13:38:29 -05:00
dselen
47ac438844
Update README.md
Rearranged Ubuntu match other descending formats.
2024-08-22 16:24:07 +02:00
Dselen
bd3aa28523 Changed readme and compose for templating. 2024-08-20 14:48:36 -05:00
Dselen
68d0ae4002 Added context and refined code. 2024-08-20 13:54:49 -05:00
Dselen
6991039640 Working prototype. 2024-08-20 12:58:30 -05:00
Dselen
00611ef9dc Progress so far. 2024-08-20 09:58:25 -05:00
Donald Zou
3c50e4768a
Merge pull request #317 from donaldzou/v4.0-fix3
Fixed recursive use of cursor
2024-08-20 00:02:46 -07:00
Donald Zou
63dc9834be Fixed recursive use of cursor 2024-08-20 00:02:00 -07:00
Donald Zou
f042e42633 Adjust version to v4.0.2 2024-08-19 21:30:47 -04:00
Donald Zou
39b80a2e7e Fixed the issue where updating is not working 2024-08-19 19:17:07 -04:00
Donald Zou
fb6e948358 Update production UI 2024-08-19 16:55:18 -04:00
Donald Zou
181b0845bf
Merge pull request #313 from donaldzou/v4.0-fix2
Fixed #312, #311
2024-08-19 16:50:48 -04:00
Donald Zou
b2a82dcfe5 Fixed #312, #311
- Fixed issue in #312: The dashboard will automatically get the actual Dashboard version number.
- Fixed issue in #311: WGDashboard was not treating restricted peers correctly.
2024-08-19 16:50:00 -04:00
Noxcis
ed1c05dec9 Merge branch 'main' of https://github.com/NOXCIS/WGDashboard 2024-08-18 21:34:42 -05:00
Donald Zou
cd73aef0c9
Merge pull request #307 from donaldzou/donaldzou-patch-3
Update README.md
2024-08-17 20:34:29 -04:00
Donald Zou
ed522ec024
Update README.md 2024-08-17 20:34:20 -04:00
Donald Zou
16998d1e16
Merge pull request #306 from donaldzou/v4.0-fix1
Fixed peer status is not refreshing correctly
2024-08-17 20:25:34 -04:00
Donald Zou
11421d2d32 Try now 2024-08-17 20:19:52 -04:00
Donald Zou
1af708aaea Update 2024-08-17 01:11:48 -04:00
Noxcis
a4151800f1
Update requirements.txt 2023-12-05 04:47:40 -08:00
Noxcis
932f24c966
Update dashboard.py 2023-12-05 04:44:01 -08:00
203 changed files with 15420 additions and 5026 deletions

View File

@ -1,61 +0,0 @@
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "antonioag95",
"name": "antonioag95",
"avatar_url": "https://avatars.githubusercontent.com/u/30556866?v=4",
"profile": "https://github.com/antonioag95",
"contributions": [
"test",
"code"
]
},
{
"login": "tonjo",
"name": "tonjo",
"avatar_url": "https://avatars.githubusercontent.com/u/4726289?v=4",
"profile": "https://github.com/tonjo",
"contributions": [
"code"
]
},
{
"login": "reafian",
"name": "Richard Newton",
"avatar_url": "https://avatars.githubusercontent.com/u/11992416?v=4",
"profile": "https://github.com/reafian",
"contributions": [
"code"
]
},
{
"login": "davejlong",
"name": "David Long",
"avatar_url": "https://avatars.githubusercontent.com/u/175317?v=4",
"profile": "http://www.davejlong.com",
"contributions": [
"code"
]
},
{
"login": "marneu",
"name": "Markus Neubauer",
"avatar_url": "https://avatars.githubusercontent.com/u/5978293?v=4",
"profile": "http://www.std-soft.com",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
"projectName": "WGDashboard",
"projectOwner": "donaldzou",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true
}

View File

@ -38,11 +38,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
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.
@ -53,7 +53,7 @@ jobs:
# 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@v1
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -67,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3

55
.github/workflows/docker-related.yaml vendored Normal file
View File

@ -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 }}

View File

@ -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'

58
Dockerfile Normal file
View File

@ -0,0 +1,58 @@
FROM alpine:latest
LABEL maintainer="dselen@nerthus.nl"
# 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="0.0.0.0"
# 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/wireguarddashboard
# 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
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
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

583
README.md
View File

@ -1,9 +1,16 @@
> [!TIP]
> 🎉 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!
> [!NOTE]
> **Help Wanted 🎉**: Localizing WGDashboard to other languages! If you're willing to help, please visit https://github.com/donaldzou/WGDashboard/issues/397. Many thanks!
<hr>
<p align="center">
<img alt="WGDashboard" src="./src/static/img/logo.png" width="128">
<img alt="WGDashboard" src="./src/static/app/public/img/logo.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">
@ -12,555 +19,47 @@
<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://hits.seeyoufarm.com"><img src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fdonaldzou%2FWGDashboard&count_bg=%2379C83D&title_bg=%23555555&icon=github.svg&icon_color=%23E7E7E7&title=Visitor&edge_flat=false"/></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">Monitoring WireGuard is not convenient, need to remote access to server and type <code>wg show</code>. That's why this project is being created, to view all configurations and manage them in a easy way.</p>
<p align="center">With all these awesome features, while keeping it <b>simple</b>, <b>easy to install and use</b></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>
## 📣 What's New: v4.0
### 🎉 New Features
<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>
- **Updated dashboard design**: Re-designed some of the section with more modern style and layout, the UI is faster and more responsive, it also uses less memory. But overall is still the same dashboard you're familiarized.
- **Docker Solution**: We now have 2 docker solutions! Thanks to @DaanSelen & @shuricksumy for providing them. For more information, please see the [Docker](#-docker-solutions) section below.
- **Peer Job Scheduler**: Now you can schedule jobs for each peer to either **restrict** or **delete** the peer if the peer's total / upload / download data usage exceeded a limit, or you can set a specific datetime to restrict or delete the peer.
- **Share Peer's QR Code with Public Link**: You can share a peer's QR code and `.conf` file without the need to loging in.
- **WGDashboard's REST API**: You can now request all the api endpoint used in the dashboard. For more details please review the [API Documentation](./docs/api-documents.md).
- **Logging**: Dashboard will now log all activity on the dashboard and API requests.
- **Time-Based One-Time Password (TOTP)**: You can enable this function to add one more layer of security, and generate the TOTP with your choice of authenticator.
- **Designs**
- **Real-time Graphs**: You can view real-time data changes with graphs in each configuration.
- **Night mode**: You know what that means, it avoids bugs ;)
- **Enforce Python Virtual Environment**: I noticed newer Python version (3.12) does not allow to install packages globally, and plus I think is a good idea to use venv.
### 🧐 Other Changes
- **Deprecated jQuery from the project, and migrated and rewrote the whole front-end with Vue.js. This allows the dashboard is future proofed, and potential cross server access with a desktop app.**
- Rewrote the backend into a REST API structure
- Improved SQL query efficient
- Removed all templates, except for `index.html` where it will load the Vue.js app.
- Parsing names in `.conf`
- Minimized the need to read `.conf`, only when any `.conf` is modified
### 🥘 New Experimental Features
- **Cross-Server Access**: Now you can access other servers that installed `v4` of WGDashboard through API key.
- **Desktop App**: Thanks to **Cross-Server Access**, you can now download an ElectronJS based desktop app of WGDashboard, and use that to access WGDashboard on different servers.
- > For more information, please scroll down to [🥘 Experimental Functions](#-experimental-functions)
> I can't thank enough for all of you who wait for this release, and for those who are new to this project, welcome :)
> Also, huge thanks to who contributed to this major release:
> @bolgovrussia, @eduardorosabales, @Profik, @airgapper, @tokon2000, @bkeenke, @kontorskiy777, @bugsse, @Johnnykson, @DaanSelen, @shuricksumy and many others!
<hr>
## 📋 Table of Content
<!-- TOC -->
* [📣 What's New: v4.0](#-whats-new-v40)
* [🎉 New Features](#-new-features)
* [🧐 Other Changes](#-other-changes)
* [🥘 New Experimental Features](#-new-experimental-features)
* [📋 Table of Content](#-table-of-content)
* [💡 Features](#-features)
* [📝 Requirements](#-requirements)
* [Supported Operating Systems](#supported-operating-systems)
* [Existing WireGuard Configurations](#existing-wireguard-configurations)
* [🛠 Install](#-install)
* [Install Commands](#install-commands)
* [Ubuntu 20.04 LTS](#ubuntu-2004-lts)
* [Ubuntu 22.04 LTS & Ubuntu 24.02 LTS](#ubuntu-2204-lts--ubuntu-2402-lts)
* [Debian 12.6](#debian-126)
* [Debian 11.10](#debian-1110)
* [Red Hat Enterprise Linux 9.4 & CentOS 9-Stream](#red-hat-enterprise-linux-94--centos-9-stream)
* [Fedora 40 & Fedora 39 & Fedora 38](#fedora-40--fedora-39--fedora-38)
* [Manual Installation](#manual-installation)
* [🪜 Usage](#-usage)
* [Start/Stop/Restart WGDashboard](#startstoprestart-wgdashboard)
* [Autostart WGDashboard on boot (>= v2.2)](#autostart-wgdashboard-on-boot--v22)
* [✂️ Dashboard Configuration](#-dashboard-configuration)
* [Dashboard Configuration file](#dashboard-configuration-file)
* [Generating QR code and peer configuration file (.conf)](#generating-qr-code-and-peer-configuration-file-conf)
* [❓ How to update the dashboard?](#-how-to-update-the-dashboard)
* [**Please note for users who are using `v3 - v3.0.6` want to update to `v4.0`**](#please-note-for-users-who-are-using-v3---v306-want-to-update-to-v40)
* [**Please note for users who are using `v2.3.1` or below**](#please-note-for-users-who-are-using-v231-or-below)
* [🐬 Docker Solutions](#-docker-solutions)
* [Solution 1 from @DaanSelen](#solution-1-from-daanselen)
* [Solution 2 from @shuricksumy](#solution-2-from-shuricksumy)
* [📖 WGDashboard REST API Documentation & How to use API Key](#-wgdashboard-rest-api-documentation--how-to-use-api-key)
* [🥘 Experimental Features](#-experimental-features)
* [Cross-Server Access](#cross-server-access)
* [Desktop App](#desktop-app)
* [🔍 Screenshot](#-screenshot)
* [🕰️ Changelogs](#-changelogs)
<!-- TOC -->
## 💡 Features
- Automatically look for existing WireGuard configuration under `/etc/wireguard`
- Easy to use interface, provided credential and TOTP protection to the dashboard
- Manage peers and configuration
- Add Peers or by bulk with auto-generated information
- Edit peer information
- Delete peers with ease
- Restrict peers
- Generate QR Code and `.conf` file for peers, share it through a public link
- Schedule jobs to delete / restrict peer when conditions are met
- View real time peer status
- Testing tool: Ping and Traceroute to your peer
## 📝 Requirements
1. Supported operating systems. Please view the list below.
2. WireGuard & WireGuard-Tools (`wg-quick`)
3. Python 3.10 / 3.11 / 3.12
4. `git`, `net-tools`, `sudo` (_This should only apply to RHEL 9 & 8, interestingly it doesn't have it preinstalled)_
### Supported Operating Systems
> [!NOTE]
> All operating systems below are tested by myself. All are ARM64 ran in UTM Virtual Machine.
| Ubuntu | Debian | Red Hat Enterprise Linux | CentOS | Fedora |
|-----------|--------|--------------------------|----------|--------|
| 20.04 LTS | 12.6 | 9.4 | 9-Stream | 40 |
| 22.04 LTS | 11.10 | | | 39 |
| 24.02 LTS | | | | 38 |
> [!TIP]
> If you installed WGDashboard on other systems without any issues, please let me know. Thank you!
### Existing WireGuard Configurations
> [!NOTE]
> This only applies to existing WireGuard Configuration under `/etc/wireguard`
```ini
[Interface]
...
SaveConfig = true
# Need to include this line to allow WireGuard Tool to save your configuration,
# or if you just want it to monitor your WireGuard Interface and don't need to
# make any changes with the dashboard, you can set it to false.
[Peer]
#Name# = Donald's iPhone
PublicKey = abcd1234
AllowedIPs = 1.2.3.4/32
```
> [!TIP]
> With `v4`, WGDashboard will look for entry with `#Name# = abc...` in each peer and use that for the name.
## 🛠 Install
### Install Commands
These commands are tested by myself in each OS. It contains commands to install WireGuard, Git, Net Tools, and even Python on some OS.
> [!WARNING]
> Please make sure you understand these commands before you run them.
#### Ubuntu 20.04 LTS
```shell
sudo add-apt-repository ppa:deadsnakes/ppa -y && \
sudo apt-get update -y && \
sudo apt-get install python3.10 python3.10-distutils wireguard-tools net-tools --no-install-recommends -y && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p
```
#### Ubuntu 22.04 LTS & Ubuntu 24.02 LTS
```shell
sudo apt-get update -y && \
sudo apt install wireguard-tools net-tools --no-install-recommends -y && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd ./WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p /etc/sysctl.conf
```
#### Debian 12.6
```shell
apt-get install sudo git iptables -y && \
sudo apt-get update && \
sudo apt install wireguard-tools net-tools && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd ./WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p /etc/sysctl.conf
```
#### Debian 11.10
> [!WARNING]
> This commands will download Python 3.10's source code and build from it, since Debian 11.10 doesn't comes with Python 3.10
```shell
apt-get install sudo -y && \
sudo apt-get update && \
sudo apt install -y git iptables build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev wireguard-tools net-tools && \
wget https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tgz && \
tar -xvf Python-3.10.0.tgz && \
cd Python-3.10.0 && \
sudo ./configure --enable-optimizations && \
sudo make && \
sudo make altinstall && \
cd .. && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd ./WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p /etc/sysctl.conf
```
#### Red Hat Enterprise Linux 9.4 & CentOS 9-Stream
```shell
sudo yum install wireguard-tools net-tools git python3.11 -y && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd ./WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p /etc/sysctl.conf && \
firewall-cmd --add-port=10086/tcp --permanent && \
firewall-cmd --add-port=51820/udp --permanent && \
firewall-cmd --reload
```
#### Fedora 40 & Fedora 39 & Fedora 38
```shell
sudo yum install wireguard-tools net-tools git -y && \
git clone https://github.com/donaldzou/WGDashboard.git && \
cd ./WGDashboard/src && \
chmod +x ./wgd.sh && \
./wgd.sh install && \
sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && \
sudo sysctl -p /etc/sysctl.conf && \
firewall-cmd --add-port=10086/tcp --permanent && \
firewall-cmd --add-port=51820/udp --permanent && \
firewall-cmd --reload
```
### Manual Installation
> [!NOTE]
> To ensure a smooth installation process, please make sure Python 3.10/3.11/3.12, `git`, `wireguard-tools` and `net-tools` are installed :)
1. Download WGDashboard
```shell
git clone https://github.com/donaldzou/WGDashboard.git wgdashboard
2. Open the WGDashboard folder
```shell
cd wgdashboard/src
```
3. Install WGDashboard
```shell
sudo chmod u+x wgd.sh && \
sudo ./wgd.sh install
```
4. Give read and execute permission to root of the WireGuard configuration folder, you can change the path if your configuration files are not stored in `/etc/wireguard`
```shell
sudo chmod -R 755 /etc/wireguard
```
5. Run WGDashboard
```shell
sudo ./wgd.sh start
```
6. Access dashboard
Access your server with port `10086` (e.g. http://your_server_ip:10086), using username `admin` and password `admin`. See below how to change port and ip that the dashboard is running with.
## 🪜 Usage
#### Start/Stop/Restart WGDashboard
```shell
cd wgdashboard/src
-----------------------------
./wgd.sh start # Start the dashboard in background
-----------------------------
./wgd.sh debug # Start the dashboard in foreground (debug mode)
-----------------------------
./wgd.sh stop # Stop the dashboard
-----------------------------
./wgd.sh restart # Restart the dasboard
```
#### Autostart WGDashboard on boot (>= v2.2)
In the `src` folder, it contained a file called `wg-dashboard.service`, we can use this file to let our system to autostart the dashboard after reboot. The following guide has tested on **Ubuntu**, most **Debian** based OS might be the same, but some might not. Please don't hesitate to provide your system if you have tested the autostart on another system.
1. Changing the directory to the dashboard's directory
```shell
cd wgdashboard/src
```
2. Get the full path of the dashboard's directory
```shell
pwd
#Output: /root/wgdashboard/src
```
For this example, the output is `/root/wireguard-dashboard/src`, your path might be different since it depends on where you downloaded the dashboard in the first place. **Copy the the output to somewhere, we will need this in the next step.**
3. Edit the service file, the service file is located in `wireguard-dashboard/src`, you can use other editor you like, here will be using `nano`
```shell
nano wg-dashboard.service
```
You will see something like this:
```ini
[Unit]
After=syslog.target network-online.target
Wants=wg-quick.target
ConditionPathIsDirectory=/etc/wireguard
[Service]
Type=forking
PIDFile=<absolute_path_of_wgdashboard_src>/gunicorn.pid
WorkingDirectory=<absolute_path_of_wgdashboard_src>
ExecStart=<absolute_path_of_wgdashboard_src>/wgd.sh start
ExecStop=<absolute_path_of_wgdashboard_src>/wgd.sh stop
ExecReload=<absolute_path_of_wgdashboard_src>/wgd.sh restart
TimeoutSec=120
PrivateTmp=yes
Restart=always
[Install]
WantedBy=multi-user.target
```
Now, we need to replace all `<absolute_path_of_wgdashboard_src>` to the one you just copied from step 2. After doing this, the file will become something like this, your file might be different:
**Be aware that after the value of `WorkingDirectory`, it does not have a `/` (slash).** And then save the file after you edited it
4. Copy the service file to systemd folder
```bash
$ sudo cp wg-dashboard.service /etc/systemd/system/wg-dashboard.service
```
To make sure you copy the file successfully, you can use this command `cat /etc/systemd/system/wg-dashboard.service` to see if it will output the file you just edited.
5. Enable the service
```bash
$ sudo chmod 664 /etc/systemd/system/wg-dashboard.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable wg-dashboard.service
$ sudo systemctl start wg-dashboard.service # <-- To start the service
```
6. Check if the service run correctly
```bash
$ sudo systemctl status wg-dashboard.service
```
And you should see something like this
```shell
● wg-dashboard.service
Loaded: loaded (/etc/systemd/system/wg-dashboard.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2024-08-14 22:21:47 EDT; 55s ago
Process: 494968 ExecStart=/home/donaldzou/Wireguard-Dashboard/src/wgd.sh start (code=exited, status=0/SUCCESS)
Main PID: 495005 (gunicorn)
Tasks: 5 (limit: 4523)
Memory: 36.8M
CPU: 789ms
CGroup: /system.slice/wg-dashboard.service
├─495005 /home/donaldzou/Wireguard-Dashboard/src/venv/bin/python3 ./venv/bin/gunicorn --config ./gunicorn.conf.py
└─495007 /home/donaldzou/Wireguard-Dashboard/src/venv/bin/python3 ./venv/bin/gunicorn --config ./gunicorn.conf.py
Aug 14 22:21:40 wg sudo[494978]: root : PWD=/home/donaldzou/Wireguard-Dashboard/src ; USER=root ; COMMAND=./venv/bin/gunicorn --config ./gunicorn.conf.py
Aug 14 22:21:40 wg sudo[494978]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Aug 14 22:21:40 wg wgd.sh[494979]: [WGDashboard] WGDashboard w/ Gunicorn will be running on 0.0.0.0:10086
Aug 14 22:21:40 wg wgd.sh[494979]: [WGDashboard] Access log file is at ./log/access_2024_08_14_22_21_40.log
Aug 14 22:21:40 wg wgd.sh[494979]: [WGDashboard] Error log file is at ./log/error_2024_08_14_22_21_40.log
Aug 14 22:21:40 wg sudo[494978]: pam_unix(sudo:session): session closed for user root
Aug 14 22:21:45 wg wgd.sh[494968]: [WGDashboard] Checking if WGDashboard w/ Gunicorn started successfully
Aug 14 22:21:47 wg wgd.sh[494968]: [WGDashboard] WGDashboard w/ Gunicorn started successfully
Aug 14 22:21:47 wg wgd.sh[494968]: ------------------------------------------------------------
Aug 14 22:21:47 wg systemd[1]: Started wg-dashboard.service.
```
If you see `Active:` followed by `active (running) since...` then it means it run correctly.
7. Stop/Start/Restart the service
```bash
sudo systemctl stop wg-dashboard.service # <-- To stop the service
sudo systemctl start wg-dashboard.service # <-- To start the service
sudo systemctl restart wg-dashboard.service # <-- To restart the service
```
8. **And now you can reboot your system, and use the command at step 6 to see if it will auto start after the reboot, or just simply access the dashboard through your browser. If you have any questions or problem, please report it in the issue page.**
## ✂️ Dashboard Configuration
#### Dashboard Configuration file
Since version 2.0, WGDashboard will be using a configuration file called `wg-dashboard.ini`, (It will generate automatically after first time running the dashboard). More options will include in future versions, and for now it included the following configurations:
| | Description | Default | Edit Available |
|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|----------------|
| **`[Account]`** | *Configuration on account* | | |
| `username` | Dashboard login username | `admin` | Yes |
| `password` | Password, will be hash with SHA256 | `admin` hashed in SHA256 | Yes |
| | | | |
| **`[Server]`** | *Configuration on dashboard* | | |
| `wg_conf_path` | The path of all the Wireguard configurations | `/etc/wireguard` | Yes |
| `app_ip` | IP address the dashboard will run with | `0.0.0.0` | Yes |
| `app_port` | Port the the dashboard will run with | `10086` | Yes |
| `auth_req` | Does the dashboard need authentication to access, if `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **User can only edit the file directly in system**. | `true` | **No** |
| `version` | Dashboard Version | `v4.0` | **No** |
| `dashboard_refresh_interval` | How frequent the dashboard will refresh on the configuration page | `60000ms` | Yes |
| `dashboard_sort` | How configuration is sorting | `status` | Yes |
| `dashboard_theme` | Dashboard Theme | `dark` | Yes |
| | | | |
| **`[Peers]`** | *Default Settings on a new peer* | | |
| `peer_global_dns` | DNS Server | `1.1.1.1` | Yes |
| `peer_endpoint_allowed_ip` | Endpoint Allowed IP | `0.0.0.0/0` | Yes |
| `peer_display_mode` | How peer will display | `grid` | Yes |
| `remote_endpoint` | Remote Endpoint (i.e where your peers will connect to) | *depends on your server's default network interface* | Yes |
| `peer_mtu` | Maximum Transmit Unit | `1420` | |
| `peer_keep_alive` | Keep Alive | `21` | Yes |
#### Generating QR code and peer configuration file (.conf)
Starting version 2.2, dashboard can now generate QR code and configuration file for each peer. Here is a template of what each QR code encoded with and the same content will be inside the file:
```ini
[Interface]
PrivateKey = QWERTYUIOPO234567890YUSDAKFH10E1B12JE129U21=
Address = 0.0.0.0/32
DNS = 1.1.1.1
[Peer]
PublicKey = QWERTYUIOPO234567890YUSDAKFH10E1B12JE129U21=
AllowedIPs = 0.0.0.0/0
Endpoint = 0.0.0.0:51820
```
| | Description | Default Value | Available in Peer setting |
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------- |
| **`[Interface]`** | | | |
| `PrivateKey` | The private key of this peer | Private key generated by WireGuard (`wg genkey`) or provided by user | Yes |
| `Address` | The `allowed_ips` of your peer | N/A | Yes |
| `DNS` | The DNS server your peer will use | `1.1.1.1` - Cloud flare DNS, you can change it when you adding the peer or in the peer setting. | Yes |
| **`[Peer]`** | | | |
| `PublicKey` | The public key of your server | N/A | No |
| `AllowedIPs` | IP ranges for which a peer will route traffic | `0.0.0.0/0` - Indicated a default route to send all internet and VPN traffic through that peer. | Yes |
| `Endpoint` | Your wireguard server ip and port, the dashboard will search for your server's default interface's ip. | `<your server default interface ip>:<listen port>` | Yes |
## ❓ How to update the dashboard?
#### **Please note for users who are using `v3 - v3.0.6` want to update to `v4.0`**
- Although theoretically updating through `wgd.sh` should work, but I still suggest you to update the dashboard manually.
#### **Please note for users who are using `v2.3.1` or below**
- For user who is using `v2.3.1` or below, please notice that all data that stored in the current database will **not** transfer to the new database. This is hard decision to move from TinyDB to SQLite. But SQLite does provide a thread-safe access and TinyDB doesn't. I couldn't find a safe way to transfer the data, so you need to do them manually... Sorry about that :pensive:。 But I guess this would be a great start for future development :sunglasses:.
1. Change your directory to `wgdashboard`
```shell
cd wgdashboard/src
```
2. Update the dashboard
```shell
git pull https://github.com/donaldzou/WGDashboard.git v4.0 --force
```
3. Install
```shell
sudo ./wgd.sh install
```
Starting with `v3.0`, you can simply do `sudo ./wgd.sh update` !! (I hope)
## 🐬 Docker Solutions
Current, we have 2 beloved contributors provided solutions for hosting WGDashboard with Docker
### Solution 1 from @DaanSelen
Please visit [Docker-explain.md](./docker/Docker-explain.md)
### Solution 2 from @shuricksumy
Please visit [shuricksumy/docker-wgdashboard](https://github.com/shuricksumy/docker-wgdashboard)
> For questions or issues related to Docker, please visit [#272](https://github.com/donaldzou/WGDashboard/issues/272)
## 📖 WGDashboard REST API Documentation & How to use API Key
Please visit the [API Documentation](./docs/api-documents.md)
## 🥘 Experimental Features
### Cross-Server Access
Starting with `v4.0`, you can access WGDashboards on other server through one WGDashboard with API Keys
![Cross Server Example](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/cross-server.gif)
### Desktop App
Since the major changes for `v4.0` is to move the whole front-end code to Vue.js. And with this change, we can take the
advantage of combining ElectronJS and Vue.js to create a Desktop version of WGDashboard. Currently, we provide an Universal macOS app and a Windows app.
To download the app, please visit the [latest release](https://github.com/donaldzou/WGDashboard/releases).
![ElectronJS App Demo](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/electronjs-app.gif)
## 🔍 Screenshot
![Sign In](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/sign-in.png)
![Cross Server](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/cross-server.png)
![Index](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/index.png)
![New Configuration](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/new-configuration.png)
![Settings](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/settings.png)
![Light-Dark Mode](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/light-dark.png)
![Configuration](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/configuration.png)
![Add Peers](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/add-peers.png)
![Ping](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/ping.png)
![Traceroute](https://donaldzou.nyc3.cdn.digitaloceanspaces.com/wgdashboard-images/traceroute.png)
## 🕰️ Changelogs
Please visit the [Changelogs.md](./docs/changelogs.md)
> To better manage documentation for this project. I've moved it to its own [repo](https://github.com/donaldzou/WGDashboard-Documentation). I will keep updating over there and leave this README only with important information.
- [💡 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/)

View File

@ -1,82 +0,0 @@
# WG-Dashboard Docker Explanation:
Author: DaanSelen<br>
This document delves into how the WG-Dashboard 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.<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 `isolated_peers` and interface startup on container-start (through `enable_wg0`).
<img src="https://raw.githubusercontent.com/donaldzou/WGDashboard/main/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, at the moment: `repo.nerthus.nl/app/wireguard-dashboard:latest`.<br>
From there either use the environment variables describe below as parameters or use the Docker Compose file: `compose.yaml`.
An example of a simple command to get the container running is show below:<br>
```shell
docker run -d \
--name wireguard-dashboard \
--restart unless-stopped \
-e enable_wg0=true \
-e isolated_peers=true \
-p 10086:10086/tcp \
-p 51820:51820/udp \
--cap-add NET_ADMIN \
repo.nerthus.nl/app/wireguard-dashboard: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:
wireguard-dashboard:
image: repo.nerthus.nl/app/wireguard-dashboard:latest
restart: unless-stopped
container_name: wire-dash
environment:
#- tz=
#- global_dns=
- enable_wg0=true
- isolated_peers=false
#- public_ip=
ports:
- 10086:10086/tcp
- 51820:51820/udp
volumes:
- conf:/etc/wireguard
- app:/opt/wireguarddashboard/app
cap_add:
- NET_ADMIN
volumes:
conf:
app:
```
If you want to customize the yaml, make sure the core stays the same, but for example volume PATHs can be freely changed.<br>
This setup is just generic and will use the Docker volumes.
## 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 | Verbose |
| -------------- | ------- | ------- | ------- |
| tz | Europe/Amsterdam or any confirming timezone notation. | Europe/Amsterdam | 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 | Set the default DNS given to clients once they connect to the WireGuard tunnel (VPN).
| enable_wg0 | `true` or `false` | `false` | Enables or disables the starting of the WireGuard interface on container 'boot-up'.
| isolated_peers | `true` or `false` | `true` | For security the default is true, and it disables peers to ping or reach eachother, the WireGuard interface IS able to reach the peers (Done through `iptables`).
| public_ip | Any IPv4 (public recommended) address, such as the one returned by default | Default uses the return of `curl ifconfig.me` | 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.
## Closing remarks:
For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.

View File

@ -1,77 +0,0 @@
# Pull from small Debian stable image.
FROM debian:stable-slim
LABEL maintainer="dselen@nerthus.nl"
# Declaring environment variables, change Peernet to an address you like, standard is a 24 bit subnet.
ENV wg_net="10.0.0.1"
# wg_net is used functionally as an ARG for its environment variable nature, do not change unless you know what you are doing.
# 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 enable_wg0="false"
ENV isolated_peers="true"
ENV public_ip="0.0.0.0"
# Doing basic system maintenance. Change the timezone to the desired timezone.
RUN ln -sf /usr/share/zoneinfo/${tz} /etc/localtime
# Doing package management operations, such as upgrading
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends curl \
git \
iproute2 \
iptables \
iputils-ping \
openresolv \
procps \
python3 \
python3-pip \
python3-venv \
traceroute \
wireguard \
wireguard-tools \
&& apt-get remove linux-image-* --autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 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.
# 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/wireguarddashboard
RUN python3 -m venv ${WGDASH}/venv
# Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example.
RUN . ${WGDASH}/venv/bin/activate \
&& git clone https://github.com/donaldzou/WGDashboard.git ${WGDASH}/app \
&& pip3 install -r ${WGDASH}/app/src/requirements.txt \
&& chmod +x ${WGDASH}/app/src/wgd.sh \
&& .${WGDASH}/app/src/wgd.sh install
# Set the volume to be used for persistency.
VOLUME /etc/wireguard
# 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 wg genkey | tee /etc/wireguard/wg0_privatekey \
&& echo "[Interface]" > /wg0.conf \
&& echo "SaveConfig = true" >> /wg0.conf \
&& echo "Address = ${wg_net}/24" >> /wg0.conf \
&& echo "PrivateKey = $(cat /etc/wireguard/wg0_privatekey)" >> /wg0.conf \
&& echo "PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o $(ip -o -4 route show to default | awk '{print $NF}') -j MASQUERADE" >> /wg0.conf \
&& echo "PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP" >> /wg0.conf \
&& echo "PreDown = iptables -t nat -D POSTROUTING 1" >> /wg0.conf \
&& echo "PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP" >> /wg0.conf \
&& echo "ListenPort = 51820" >> /wg0.conf \
#&& echo "DNS = ${global_dns}" >> /wg0.conf \
&& rm /etc/wireguard/wg0_privatekey
# Defining a way for Docker to check the health of the container. In this case: checking the login URL.
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD curl -f http://localhost:10086/signin || exit 1
# Copy the basic entrypoint.sh script.
COPY entrypoint.sh /entrypoint.sh
# Exposing the default WireGuard Dashboard port for web access.
EXPOSE 10086
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

109
docker/README.md Normal file
View File

@ -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.

View File

@ -1,23 +1,22 @@
services:
wireguard-dashboard:
image: repo.nerthus.nl/app/wireguard-dashboard:latest
image: donaldzou/wgdashboard:latest
restart: unless-stopped
container_name: wire-dash
environment:
container_name: wgdashboard
#environment:
#- tz= # <--- Set container timezone, default: Europe/Amsterdam.
#- global_dns= # <--- Set global DNS address, default: 1.1.1.1.
- enable_wg0=true # <--- If true, wg0 will be started on container startup. default: false.
- isolated_peers=false # <--- When set to true, it disallows peers to talk to eachother, setting to false, allows it, default: true.
#- 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.
ports:
- 10086:10086/tcp
- 51820:51820/udp
volumes:
- conf:/etc/wireguard
- app:/opt/wireguarddashboard/app
- data:/data
cap_add:
- NET_ADMIN
volumes:
conf:
app:
data:

View File

@ -1,109 +0,0 @@
#!/bin/bash
echo "Starting the WireGuard Dashboard Docker container."
clean_up() {
# Cleaning out previous data such as the .pid file and starting the WireGuard Dashboard. Making sure to use the python venv.
echo "Looking for remains of previous instances..."
if [ -f "/opt/wireguarddashboard/app/src/gunicorn.pid" ]; then
echo "Found old .pid file, removing."
rm /opt/wireguarddashboard/app/src/gunicorn.pid
else
echo "No remains found, continuing."
fi
}
start_core() {
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage.
if [ ! -f "/etc/wireguard/wg0.conf" ]; then
cp "/wg0.conf" "/etc/wireguard/wg0.conf"
echo "WireGuard interface file copied over."
else
echo "WireGuard interface file looks to already be existing."
fi
echo "Activating Python venv and executing the WireGuard Dashboard service."
. "${WGDASH}"/venv/bin/activate
cd "${WGDASH}"/app/src || return # If changing the directory fails (permission or presence error), then bash will exist this function, causing the WireGuard Dashboard to not be succesfully launched.
bash wgd.sh start
# The following section takes care of the firewall rules regarding the 'isolated_peers' feature, which allows or drops packets destined from the wg0 to the wg0 interface.
if [ "${isolated_peers,,}" = "false" ]; then
echo "Isolated peers disabled, adjusting."
sed -i '/PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP/d' /etc/wireguard/wg0.conf
sed -i '/PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP/d' /etc/wireguard/wg0.conf
elif [ "${isolated_peers,,}" = "true" ]; then
upblocking=$(grep -c "PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP" /etc/wireguard/wg0.conf)
downblocking=$(grep -c "PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP" /etc/wireguard/wg0.conf)
if [ "$upblocking" -lt 1 ] && [ "$downblocking" -lt 1 ]; then
echo "Isolated peers enabled, adjusting."
sed -i '/PostUp = iptables -t nat -I POSTROUTING 1 -s/a PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP' /etc/wireguard/wg0.conf
sed -i '/PreDown = iptables -t nat -D POSTROUTING 1 -s/a PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP' /etc/wireguard/wg0.conf
fi
fi
# The following section takes care of
if [ "${enable_wg0,,}" = "true" ]; then
echo "Preference for wg0 to be turned on found."
wg-quick up wg0
else
echo "Preference for wg0 to be turned off found."
fi
}
set_envvars() {
echo "Setting relevant variables for operation."
# If the timezone is different, for example in North-America or Asia.
if [ "${tz}" != "$(cat /etc/timezone)" ]; then
echo "Changing timezone."
ln -sf /usr/share/zoneinfo/"${tz}" /etc/localtime
echo "${tz}" > /etc/timezone
fi
# Changing the DNS used for clients and the dashboard itself.
if [ "${global_dns}" != "$(grep "peer_global_dns = " /opt/wireguarddashboard/app/src/wg-dashboard.ini | awk '{print $NF}')" ]; then
echo "Changing default dns."
#sed -i "s/^DNS = .*/DNS = ${global_dns}/" /etc/wireguard/wg0.conf # Uncomment if you want to have DNS on server-level.
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" /opt/wireguarddashboard/app/src/wg-dashboard.ini
fi
# Setting the public IP of the WireGuard Dashboard container host. If not defined, it will trying fetching it using a curl to ifconfig.me.
if [ "${public_ip}" = "0.0.0.0" ]; 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}/" /opt/wireguarddashboard/app/src/wg-dashboard.ini
elif [ "${public_ip}" != "$(grep "remote_endpoint = " /opt/wireguarddashboard/app/src/wg-dashboard.ini | awk '{print $NF}')" ]; then
echo "Setting the Public-IP using given variable: ${public_ip}"
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${public_ip}/" /opt/wireguarddashboard/app/src/wg-dashboard.ini
fi
}
ensure_blocking() {
sleep 1s
echo "Ensuring container continuation."
# This function checks if the latest error log is created and tails it for docker logs uses.
if find "/opt/wireguarddashboard/app/src/log" -mindepth 1 -maxdepth 1 -type f | read -r; then
latestErrLog=$(find /opt/wireguarddashboard/app/src/log -name "error_*.log" | head -n 1)
latestAccLog=$(find /opt/wireguarddashboard/app/src/log -name "access_*.log" | head -n 1)
tail -f "${latestErrLog}" "${latestAccLog}"
fi
# Blocking command in case of erroring. So the container does not quit.
sleep infinity
}
# Execute functions for the WireGuard Dashboard services, then set the environment variables
clean_up
start_core
set_envvars
ensure_blocking

View File

@ -1,612 +0,0 @@
# 📖 API Document for WGDashboard
**Version: v4.0**
**Created by: Donald Zou**
<!-- TOC -->
* [📖 API Document for WGDashboard](#-api-document-for-wgdashboard)
* [🔑 How to use API Key?](#-how-to-use-api-key)
* [Create API Key](#create-api-key)
* [Use API Key](#use-api-key)
* [API Endpoints](#api-endpoints)
* [Handshake to Server](#handshake-to-server)
* [Request](#request)
* [Response](#response)
* [Validate Authentication](#validate-authentication)
* [Request](#request-1)
* [Response](#response-1)
* [Authenticate](#authenticate)
* [Request](#request-2)
* [Body Parameters](#body-parameters)
* [Response](#response-2)
* [Sign Out](#sign-out)
* [Request](#request-3)
* [Response](#response-3)
* [Get WireGuard Configurations](#get-wireguard-configurations)
* [Request](#request-4)
* [Response](#response-4)
* [Add WireGuard Configuration](#add-wireguard-configuration)
* [Request](#request-5)
* [Body Parameters](#body-parameters-1)
* [Response](#response-5)
* [Toggle WireGuard Configuration](#toggle-wireguard-configuration)
* [Request](#request-6)
* [Query String Parameter](#query-string-parameter)
* [Response](#response-6)
* [Get WGDashboard Configuration](#get-wgdashboard-configuration)
* [Request](#request-7)
* [Response](#response-7)
* [Update WGDashboard Configuration Item](#update-wgdashboard-configuration-item)
* [Request](#request-8)
* [Body Parameters](#body-parameters-2)
* [Response](#response-8)
* [Get WGDashboard API Keys](#get-wgdashboard-api-keys)
* [Request](#request-9)
* [Response](#response-9)
* [Add WGDashboard API Key](#add-wgdashboard-api-key)
* [Request](#request-10)
* [Body Parameters](#body-parameters-3)
* [Response](#response-10)
* [Endpoint](#endpoint)
* [Request](#request-11)
* [Response](#response-11)
<!-- TOC -->
<hr>
## 🔑 How to use API Key?
### Create API Key
1. To request an API Key, simply login to your WGDashboard, go to **Settings**, scroll to the very bottom. Click the **switch** on the right to enable API Key.
2. Click the blur **Create** button, set an **expiry date** you want or **never expire**, then click **Done**.
### Use API Key
- Simply add `wg-dashboard-apikey` with the value of your API key into the HTTP Header.
```javascript
fetch('http://server:10086/api/handshake', {
headers: {
'content-type': 'application/json',
'wg-dashboard-apikey': 'insert your api key here'
},
method: "GET"
})
```
## API Endpoints
### Handshake to Server
This endpoint is designed for a simple handshake when using API key to connect. If `status` is `true` that means
#### Request
`GET /api/handshake`
#### Response
`200 - OK`
```json
{
"data": null,
"message": null,
"status": true
}
```
`401 - UNAUTHORIZED`
```json
{
"data": null,
"message": "Unauthorized access.",
"status": false
}
```
> Notice: this `401` response will return at all endpoint if your API Key or session is invalid.
<hr>
### Validate Authentication
This endpoint if needed for non-cross-server access. This will check if the cookie on the client side is still valid on the server side.
#### Request
`GET /api/validateAuthentication`
#### Response
`200 - OK`
Session is still valid
```json
{
"data": null,
"message": null,
"status": true
}
```
Session is invalid
```json
{
"data": null,
"message": "Invalid authentication.",
"status": false
}
```
<hr>
### Authenticate
This endpoint is dedicated for non-cross-server access. It is used to authenticate user's username, password and TOTP
#### Request
`POST /api/authenticate`
##### Body Parameters
```json
{
"username": "admin",
"password": "admin",
"totp": "123456"
}
```
| Parameter | Type |
|------------|--------|
| `username` | string |
| `password` | string |
| `totp` | string |
#### Response
`200 - OK`
If username, password and TOTP matched
```json
{
"data": null,
"message": null,
"status": true
}
```
If username, password or TOTP is not match
```json
{
"data": null,
"message": "Sorry, your username, password or OTP is incorrect.",
"status": false
}
```
<hr>
### Sign Out
To remove the current session on server side
#### Request
`GET /api/signout`
#### Response
`200 - OK`
```json
{
"data": null,
"message": null,
"status": true
}
```
<hr>
### Get WireGuard Configurations
To get all WireGuard configurations in `/etc/wireguard`
#### Request
`GET /api/getWireguardConfigurations`
#### Response
`200 - OK`
```json
{
"data": [
{
"Address": "10.200.200.1/24",
"ConnectedPeers": 0,
"DataUsage": {
"Receive": 0.1582,
"Sent": 2.1012999999999997,
"Total": 2.2595
},
"ListenPort": "51820",
"Name": "wg0",
"PostDown": "iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp0s1 -j MASQUERADE;",
"PostUp": "iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp0s1 -j MASQUERADE;",
"PreDown": "",
"PreUp": "",
"PrivateKey": "8DsSMli3okgUx5frKbFQ0fMW5ZMyqyxOdOW7+g21L18=",
"PublicKey": "GQlGi8QJ93hWY7L2xlJyh+7S6+ekER9xP11T92T0O0Q=",
"SaveConfig": true,
"Status": false
}
],
"message": null,
"status": true
}
```
<hr>
### Add WireGuard Configuration
Add a new WireGuard Configuration
#### Request
`POST /api/addWireguardConfiguration`
##### Body Parameters
```json
{
"ConfigurationName": "wg0",
"Address": "10.0.0.1/24",
"ListenPort": 51820,
"PrivateKey": "eJuuamCgakVs2xUZGHh/g7C6Oy89JGh7eE2jjEGbbFc=",
"PublicKey": "3Ruirgw9qNRwNpBepkiVjjSe82tY+lDZr6WaFC4wO2g=",
"PresharedKey": "GMMLKWdJlgsKVoR26BJPsNbDXyfILL+x1Nd6Ecmn4lg=",
"PreUp": "",
"PreDown": "iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp0s1 -j MASQUERADE;",
"PostUp": "iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp0s1 -j MASQUERADE;",
"PostDown": ""
}
```
| Parameter | Type |
|---------------------|--------|
| `ConfigurationName` | string |
| `Address` | string |
| `ListenPort` | int |
| `PrivateKey` | string |
| `PublicKey` | string |
| `PresharedKey` | string |
| `PreUp` | string |
| `PreDown` | string |
| `PostUp` | string |
| `PostDown` | string |
#### Response
`200 - OK`
If everything is good
```json
{
"data": null,
"message": null,
"status": true
}
```
If the new configuration's `ConfigurationName` is already existed
```json
{
"data": null,
"message": "Already have a configuration with the name \"wg0\"",
"status": false
}
```
If the new configuration's `ListenPort` is used by another configuration
```json
{
"data": null,
"message": "Already have a configuration with the port \"51820\"",
"status": false
}
```
If the new configuration's `Address` is used by another configuration
```json
{
"data": null,
"message": "Already have a configuration with the address \"10.0.0.1/24\"",
"status": false
}
```
<hr>
### Toggle WireGuard Configuration
To turn on/off of a WireGuard Configuration
#### Request
`GET /api/toggleWireguardConfiguration/?configurationName=`
##### Query String Parameter
| Parameter | Type |
|---------------------|--------|
| `configurationName` | string |
#### Response
`200 - OK`
If toggle is successful, server will return the current status in `status`: `true` or `false` indicating if the configuration is up or not.
```json
{
"data": true,
"message": null,
"status": true
}
```
If the `configurationName` provided does not exist
```json
{
"data": null,
"message": "Please provide a valid configuration name",
"status": false
}
```
<hr>
### Get WGDashboard Configuration
Get the WGDashboard Configuration, such as `dashboard_theme`...
#### Request
`GET /api/getDashboardConfiguration`
#### Response
`200 - OK`
```json
{
"data": {
"Account": {
"enable_totp": false,
"password": "some hashed value :(",
"totp_verified": false,
"username": "admin"
},
"Database": {
"type": "sqlite"
},
"Other": {
"welcome_session": false
},
"Peers": {
"peer_display_mode": "grid",
"peer_endpoint_allowed_ip": "0.0.0.0/0",
"peer_global_dns": "1.1.1.1",
"peer_keep_alive": "21",
"peer_mtu": "1420",
"remote_endpoint": "192.168.2.38"
},
"Server": {
"app_ip": "0.0.0.0",
"app_port": "10086",
"app_prefix": "",
"auth_req": true,
"dashboard_api_key": true,
"dashboard_refresh_interval": "5000",
"dashboard_sort": "status",
"dashboard_theme": "dark",
"version": "v4.0",
"wg_conf_path": "/etc/wireguard"
}
},
"message": null,
"status": true
}
```
<hr>
### Update WGDashboard Configuration Item
Update the WGDashboard Configuration one at a time
#### Request
`POST /api/updateDashboardConfigurationItem`
##### Body Parameters
```json
{
"section": "Server",
"key": "dashboard_theme",
"value": "dark"
}
```
| Parameter | Type | |
|-----------|--------|----------------------------------------------------------|
| `section` | string | Each section in the `wg-dashboard.ini` |
| `key` | string | Each key/value pair under each in the `wg-dashboard.ini` |
| `value` | string | Value for this key/value pair |
#### Response
`200 - OK`
If update is success
```json
{
"data": true,
"message": null,
"status": true
}
```
If update failed
```json
{
"data": true,
"message": "Message related to the error will appear here",
"status": false
}
```
<hr>
### Get WGDashboard API Keys
Get a list of active API key in WGDashboard
#### Request
`GET /api/getDashboardAPIKeys`
#### Response
`200 - OK`
If API Key function is enabled and there are active API keys
> If `ExpiredAt` is `null`, that means this API key will never expire
```json
{
"data": [
{
"CreatedAt": "2024-08-15 00:42:31",
"ExpiredAt": null,
"Key": "AXt1x3TZMukmA-eSnAyESy08I14n20boppSsknHOB-Y"
},
{
"CreatedAt": "2024-08-14 22:50:44",
"ExpiredAt": "2024-08-21 22:50:43",
"Key": "ry0Suo0BrypSMzbq0C_TjkEcgrFHHj6UBZGmC2-KI2o"
}
],
"message": null,
"status": true
}
```
If API key function is disabled
```json
{
"data": null,
"message": "Dashboard API Keys function is disabled",
"status": false
}
```
<hr>
### Add WGDashboard API Key
Add a new API Key in WGDashboard
#### Request
`POST /api/newDashboardAPIKey`
##### Body Parameters
```json
{
"neverExpire": false,
"ExpiredAt": "2024-12-31 16:00:00"
}
```
| Parameter | Type | |
|---------------|--------|-----------------------------------------------------------------------------------|
| `neverExpire` | bool | If this is `false`, please specify a date in `ExpiredAt` |
| `ExpiredAt` | string | If `neverExpire` is `true`, this can be omitted. Format is `YYYY-MM-DD hh:mm:ss`. |
#### Response
`200 - OK`
If success, it will return the latest list of API Keys
```json
{
"data": [
{
"CreatedAt": "2024-08-15 00:42:31",
"ExpiredAt": null,
"Key": "AXt1x3TZMukmA-eSnAyESy08I14n20boppSsknHOB-Y"
},
{
"CreatedAt": "2024-08-14 22:50:44",
"ExpiredAt": "2024-12-31 16:50:43",
"Key": "ry0Suo0BrypSMzbq0C_TjkEcgrFHHj6UBZGmC2-KI2o"
}
],
"message": null,
"status": true
}
```
If API key function is disabled
```json
{
"data": null,
"message": "Dashboard API Keys function is disabled",
"status": false
}
```
<hr>
### Endpoint
Description
#### Request
`GET`
#### Response
`200 - OK`
```json
{
"data": true,
"message": null,
"status": true
}
```

View File

@ -1,105 +0,0 @@
# ⏰ Changelogs of WGDashboard
#### v3.0.0 - v3.0.6.2 - Jan 18, 2022
- 🎉 **New Features**
- **Moved from TinyDB to SQLite**: SQLite provide a better performance and loading speed when getting peers! Also avoided crashing the database due to **race condition**.
- **Added Gunicorn WSGI Server**: This could provide more stable on handling HTTP request, and more flexibility in the future (such as HTTPS support). **BIG THANKS to @pgalonza :heart:**
- **Add Peers by Bulk:** User can add peers by bulk, just simply set the amount and click add.
- **Delete Peers by Bulk**: User can delete peers by bulk, without deleting peers one by one.
- **Download Peers in Zip**: User can download all *downloadable* peers in a zip.
- **Added Pre-shared Key to peers:** Now each peer can add with a pre-shared key to enhance security. Previously added peers can add the pre-shared key through the peer setting button.
- **Redirect Back to Previous Page:** The dashboard will now redirect you back to your previous page if the current session got timed out and you need to sign in again.
- **Added Some [🥘 Experimental Functions](#-experimental-functions)**
- 🪚 **Bug Fixed**
- [IP Sorting range issues #99](https://github.com/donaldzou/WGDashboard/issues/99) [❤️ @barryboom]
- [INvalid character written to tunnel json file #108](https://github.com/donaldzou/WGDashboard/issues/108) [❤️ @ikidd]
- [Add IPv6 #91](https://github.com/donaldzou/WGDashboard/pull/91) [❤️ @pgalonza]
- [Added MTU and PersistentKeepalive to QR code and download files #112](https://github.com/donaldzou/WGDashboard/pull/112) [:heart: @reafian]
- **And many other bugs provided by our beloved users** :heart:
- **🧐 Other Changes**
- **Key generating moved to front-end**: No longer need to use the server's WireGuard to generate keys, thanks to the `wireguard.js` from the [official repository](https://git.zx2c4.com/wireguard-tools/tree/contrib/keygen-html/wireguard.js)!
- **Peer transfer calculation**: each peer will now show all transfer amount (previously was only showing transfer amount from the last configuration start-up).
- **UI adjustment on running peers**: peers will have a new style indicating that it is running.
- **`wgd.sh` finally can update itself**: So now user could update the whole dashboard from `wgd.sh`, with the `update` command.
- **Minified JS and CSS files**: Although only a small changes on the file size, but I think is still a good practice to save a bit of bandwidth ;)
*And many other small changes for performance and bug fixes! :laughing:*
#### v2.3.1 - Sep 8, 2021
- Updated dashboard's name to **WGDashboard**!!
#### v2.3 - Sep 8, 2021
- 🎉 **New Features**
- **Update directly from `wgd.sh`:** Now you can update WGDashboard directly from the bash script.
- **Displaying Peers:** You can switch the display mode between list and table in the configuration page.
- 🪚 **Bug Fixed**
- [Peer DNS Validation Fails #67](issues/67): Added DNS format check. [❤️ @realfian]
- [configparser.NoSectionError: No section: 'Interface' #66](issues/66): Changed permission requirement for `etc/wireguard` from `744` to `755`. [❤️ @ramalmaty]
- [Feature request: Interface not loading when information missing #73](issues/73): Fixed when Configuration Address and Listen Port is missing will crash the dashboard. [❤️ @js32]
- [Remote Peer, MTU and PersistentKeepalives added #70](pull/70): Added MTU, remote peer and Persistent Keepalive. [❤️ @realfian]
- [Fixes DNS check to support search domain #65](pull/65): Added allow input domain into DNS. [❤️@davejlong]
- **🧐 Other Changes**
- Moved Add Peer Button into the right bottom corner.
#### v2.2.1 - Aug 16, 2021
Bug Fixed:
- Added support for full subnet on Allowed IP
- Peer setting Save button
#### v2.2 - Aug 14, 2021
- 🎉 **New Features**
- **Add new peers**: Now you can add peers directly on dashboard, it will generate a pair of private key and public key. You can also set its DNS, endpoint allowed IPs. Both can set a default value in the setting page. [❤️ in [#44](https://github.com/donaldzou/wireguard-dashboard/issues/44)]
- **QR Code:** You can add the private key in peer setting of your existed peer to create a QR code. Or just create a new one, dashboard will now be able to auto generate a private key and public key ;) Don't worry, all keys will be generated on your machine, and **will delete all key files after they got generated**. [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
- **Peer configuration file download:** Same as QR code, you now can download the peer configuration file, so you don't need to manually input all the details on the peer machine! [❤️ in [#40](https://github.com/donaldzou/wireguard-dashboard/issues/40)]
- **Search peers**: You can now search peers by their name.
- **Autostart on boot:** Added a tutorial on how to start the dashboard to on boot! Please read the [tutorial below](#autostart-wireguard-dashboard-on-boot). [❤️ in [#29](https://github.com/donaldzou/wireguard-dashboard/issues/29)]
- **Click to copy**: You can now click and copy all peer's public key and configuration's public key.
- ....
- 🪚 **Bug Fixed**
- When there are comments in the wireguard config file, will cause the dashboard to crash.
- Used regex to search for config files.
- **🧐 Other Changes**
- Moved all external CSS and JavaScript file to local hosting (Except Bootstrap Icon, due to large amount of SVG files).
- Updated Python dependencies
- Flask: `v1.1.2 => v2.0.1`
- Jinja: `v2.10.1 => v3.0.1`
- icmplib: `v2.1.1 => v3.0.1`
- Updated CSS/JS dependencies
- Bootstrap: `v4.5.3 => v4.6.0`
- UI adjustment
- Adjusted how peers will display in larger screens, used to be 1 row per peer, now is 3 peers in 1 row.
#### v2.1 - Jul 2, 2021
- Added **Ping** and **Traceroute** tools!
- Adjusted the calculation of data usage on each peers
- Added refresh interval of the dashboard
- Bug fixed when no configuration on fresh install ([#23](https://github.com/donaldzou/wireguard-dashboard/issues/23))
- Fixed crash when too many peers ([#22](https://github.com/donaldzou/wireguard-dashboard/issues/22))
#### v2.0 - May 5, 2021
- Added login function to dashboard
- ***I'm not using the most ideal way to store the username and password, feel free to provide a better way to do this if you any good idea!***
- Added a config file to the dashboard
- Dashboard config can be change within the **Setting** tab on the side bar
- Adjusted UI
- And much more!
#### v1.1.2 - Apr 3, 2021
- Resolved issue [#3](https://github.com/donaldzou/wireguard-dashboard/issues/3).
#### v1.1.1 - Apr 2, 2021
- Able to add a friendly name to each peer. Thanks [#2](https://github.com/donaldzou/wireguard-dashboard/issues/2) !
#### v1.0 - Dec 27, 2020
- Added the function to remove peers

235
entrypoint.sh Normal file
View File

@ -0,0 +1,235 @@
#!/bin/bash
# Path to the configuration file (exists because of previous function).
config_file="/data/wg-dashboard.ini"
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..."
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
chmod +x "${WGDASH}"/src/wgd.sh
cd "${WGDASH}"/src || exit
./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]"
} > "${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 correct, moving on."
else
echo "Changing default DNS..."
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" "${config_file}"
fi
if [ "${public_ip}" == "0.0.0.0" ]; 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}"
else
echo "Public-IP is correct, moving on."
fi
}
# === CORE SERVICES ===
start_core() {
printf "\n---------------------- STARTING CORE -----------------------\n"
echo "Activating Python venv and executing the WireGuard Dashboard service."
. "${WGDASH}"/src/venv/bin/activate
cd "${WGDASH}"/src || return
bash wgd.sh start
# Isolated peers feature, first converting the existing configuration files and the given names to arrays.
#
# WILL BE REMOVED IN FUTURE WHEN WGDASHBOARD ITSELF SUPPORTS THIS!!
#
local configurations=(/etc/wireguard/*)
IFS=',' read -r -a do_isolate <<< "${isolate}"
non_isolate=()
# Checking if there are matches between the two arrays.
for config in "${configurations[@]}"; do
config=$(echo "$config" | sed -e 's|.*/etc/wireguard/||' -e 's|\.conf$||')
local found
found=false
for interface in "${do_isolate[@]}"; do
if [[ "$config" == "$interface" ]]; then
found=true
break
fi
done
if [ "$found" = false ]; then
non_isolate+=("$config")
fi
done
# Isolating the matches.
noneFound=0
for interface in "${do_isolate[@]}"; do
if [ "$interface" = "none" ] || [ "$interface" = "" ]; then
echo "Found none, stopping isolation checking."
noneFound=1
break
else
if [ ! -f "/etc/wireguard/${interface}.conf" ]; then
echo "Ignoring ${interface}"
elif [ -f "/etc/wireguard/${interface}.conf" ]; then
echo "Isolating interface:" "$interface"
upblocking=$(grep -c "PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf)
downblocking=$(grep -c "PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf)
if [ "$upblocking" -lt 1 ] && [ "$downblocking" -lt 1 ]; then
sed -i "/PostUp =/a PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf
sed -i "/PreDown =/a PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf
fi
else
echo "Configuration for $interface in enforce isolation does not seem to exist, continuing."
fi
fi
done
# Removing isolation for the configurations that did not match.
for interface in "${non_isolate[@]}"; do
if [ $noneFound -eq 1 ]; then
break
elif [ ! -f "/etc/wireguard/${interface}.conf" ]; then
echo "Ignoring ${interface}"
elif [ -f "/etc/wireguard/${interface}.conf" ]; then
echo "Removing isolation, if isolation is present for:" "$interface"
sed -i "/PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/"${interface}".conf
sed -i "/PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/"${interface}".conf
else
echo "Configuration for $interface in removing isolation does not seem to exist, continuing."
fi
done
}
ensure_blocking() {
sleep 1s
echo -e "\nEnsuring container continuation."
# Find and tail the latest error and access logs if they exist
local logdir="/opt/wireguarddashboard/src/log"
latestErrLog=$(find "$logdir" -name "error_*.log" -type f -print | sort -r | head -n 1)
latestAccLog=$(find "$logdir" -name "access_*.log" -type f -print | sort -r | head -n 1)
# Only tail the logs if they are found
if [ -n "$latestErrLog" ] || [ -n "$latestAccLog" ]; then
tail -f "$latestErrLog" "$latestAccLog"
else
echo "No log files found to tail."
fi
# Blocking command to keep the container running as a last resort.
sleep infinity
}
# Execute functions for the WireGuard Dashboard services, then set the environment variables
ensure_installation
set_envvars
start_core
ensure_blocking

1081
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,8 @@
{
"dependencies": {
"@volar/language-server": "2.4.0-alpha.18",
"@vue/language-server": "2.0.28",
"ag-charts-vue3": "^10.3.1",
"dayjs": "^1.11.12"
}
}

6
qodana.yaml Normal file
View File

@ -0,0 +1,6 @@
version: "1.0"
linter: jetbrains/qodana-python:2024.3
profile:
name: qodana.recommended
include:
- name: CheckDependencyLicenses

View File

@ -1,244 +0,0 @@
import ipaddress, subprocess, datetime, os, util
from datetime import datetime, timedelta
from flask import jsonify
from util import *
import configparser
notEnoughParameter = {"status": False, "reason": "Please provide all required parameters."}
good = {"status": True, "reason": ""}
def ret(status=True, reason="", data=""):
return {"status": status, "reason": reason, "data": data}
def togglePeerAccess(data, g):
checkUnlock = g.cur.execute(f"SELECT * FROM {data['config']} WHERE id='{data['peerID']}'").fetchone()
if checkUnlock:
moveUnlockToLock = g.cur.execute(
f"INSERT INTO {data['config']}_restrict_access SELECT * FROM {data['config']} WHERE id = '{data['peerID']}'")
if g.cur.rowcount == 1:
print(g.cur.rowcount)
print(util.deletePeers(data['config'], [data['peerID']], g.cur, g.db))
else:
moveLockToUnlock = g.cur.execute(
f"SELECT * FROM {data['config']}_restrict_access WHERE id = '{data['peerID']}'").fetchone()
try:
if len(moveLockToUnlock[-1]) == 0:
status = subprocess.check_output(
f"wg set {data['config']} peer {moveLockToUnlock[0]} allowed-ips {moveLockToUnlock[11]}",
shell=True, stderr=subprocess.STDOUT)
else:
now = str(datetime.datetime.now().strftime("%m%d%Y%H%M%S"))
f_name = now + "_tmp_psk.txt"
f = open(f_name, "w+")
f.write(moveLockToUnlock[-1])
f.close()
subprocess.check_output(
f"wg set {data['config']} peer {moveLockToUnlock[0]} allowed-ips {moveLockToUnlock[11]} preshared-key {f_name}",
shell=True, stderr=subprocess.STDOUT)
os.remove(f_name)
status = subprocess.check_output(f"wg-quick save {data['config']}", shell=True, stderr=subprocess.STDOUT)
g.cur.execute(
f"INSERT INTO {data['config']} SELECT * FROM {data['config']}_restrict_access WHERE id = '{data['peerID']}'")
if g.cur.rowcount == 1:
g.cur.execute(f"DELETE FROM {data['config']}_restrict_access WHERE id = '{data['peerID']}'")
except subprocess.CalledProcessError as exc:
return {"status": False, "reason": str(exc.output.strip())}
return good
class managePeer:
def getPeerDataUsage(self, data, cur):
now = datetime.now()
now_string = now.strftime("%d/%m/%Y %H:%M:%S")
interval = {
"30min": now - timedelta(hours=0, minutes=30),
"1h": now - timedelta(hours=1, minutes=0),
"6h": now - timedelta(hours=6, minutes=0),
"24h": now - timedelta(hours=24, minutes=0),
"all": ""
}
if data['interval'] not in interval.keys():
return {"status": False, "reason": "Invalid interval."}
intv = ""
if data['interval'] != "all":
t = interval[data['interval']].strftime("%d/%m/%Y %H:%M:%S")
intv = f" AND time >= '{t}'"
timeData = cur.execute(f"SELECT total_receive, total_sent, time FROM wg0_transfer WHERE id='{data['peerID']}' {intv} ORDER BY time DESC;")
chartData = []
for i in timeData:
chartData.append({
"total_receive": i[0],
"total_sent": i[1],
"time": i[2]
})
return {"status": True, "reason": "", "data": chartData}
class manageConfiguration:
def AddressCheck(self, data):
address = data['address']
address = address.replace(" ", "")
address = address.split(',')
amount = 0
for i in address:
try:
ips = ipaddress.ip_network(i, False)
amount += ips.num_addresses
except ValueError as e:
return {"status": False, "reason": str(e)}
if amount >= 1:
return {"status": True, "reason": "", "data": f"Total of {amount} IPs"}
else:
return {"status": True, "reason": "", "data": f"0 available IPs"}
def PortCheck(self, data, configs):
port = data['port']
if (not port.isdigit()) or int(port) < 1 or int(port) > 65535:
return {"status": False, "reason": f"Invalid port."}
for i in configs:
if i['port'] == port:
return {"status": False, "reason": f"{port} used by {i['conf']}."}
checkSystem = subprocess.run(f'ss -tulpn | grep :{port} > /dev/null', shell=True)
if checkSystem.returncode != 1:
return {"status": False, "reason": f"Port {port} used by other process in your system."}
return good
def NameCheck(self, data, configs):
name = data['name']
name = name.replace(" ", "")
for i in configs:
if name == i['conf']:
return {"status": False, "reason": f"{name} already existed."}
illegal_filename = ["(Space)", " ", ".", ",", "/", "?", "<", ">", "\\", ":", "*", '|' '\"', "com1", "com2",
"com3",
"com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4",
"lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "con", "nul", "prn"]
for i in illegal_filename:
name = name.replace(i, "")
if len(name) == 0:
return {"status": False, "reason": "Invalid name."}
return good
def addConfiguration(self, data, configs, WG_CONF_PATH):
output = ["[Interface]", "SaveConfig = true"]
required = ['addConfigurationPrivateKey', 'addConfigurationListenPort',
'addConfigurationAddress', 'addConfigurationPreUp', 'addConfigurationPreDown',
'addConfigurationPostUp', 'addConfigurationPostDown']
for i in required:
e = data[i]
if len(e) != 0:
key = i.replace("addConfiguration", "")
o = f"{key} = {e}"
output.append(o)
name = data['addConfigurationName']
illegal_filename = ["(Space)", " ", ".", ",", "/", "?", "<", ">", "\\", ":", "*", '|' '\"', "com1", "com2",
"com3",
"com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4",
"lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "con", "nul", "prn"]
for i in illegal_filename:
name = name.replace(i, "")
try:
newFile = open(f"{WG_CONF_PATH}/{name}.conf", "w+")
newFile.write("\n".join(output))
except Exception as e:
return {"status": False, "reason": str(e)}
return {"status": True, "reason": "", "data": name}
def deleteConfiguration(self, data, config, g, WG_CONF_PATH):
confs = []
for i in config:
confs.append(i['conf'])
print(confs)
if data['name'] not in confs:
return {"status": False, "reason": "Configuration does not exist", "data": ""}
for i in config:
if i['conf'] == data['name']:
if i['status'] == "running":
try:
subprocess.check_output("wg-quick down " + data['name'], shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
return {"status": False, "reason": "Can't stop peer", "data": str(exc.output.strip().decode("utf-8"))}
g.cur.execute(f'DROP TABLE {data["name"]}')
g.cur.execute(f'DROP TABLE {data["name"]}_restrict_access')
g.db.commit()
try:
os.remove(f'{WG_CONF_PATH}/{data["name"]}.conf')
except Exception as e:
return {"status": False, "reason": "Can't delete peer", "data": str(e)}
return good
def getConfigurationInfo(self, configName, WG_CONF_PATH):
conf = configparser.RawConfigParser(strict=False)
conf.optionxform = str
try:
with open(f'{WG_CONF_PATH}/{configName}.conf', 'r'):
conf.read(f'{WG_CONF_PATH}/{configName}.conf')
if not conf.has_section("Interface"):
return ret(status=False, reason="No [Interface] in configuration file")
return ret(data=dict(conf['Interface']))
except FileNotFoundError as err:
return ret(status=False, reason=str(err))
def saveConfiguration(self, data, WG_CONF_PATH, configs):
conf = configparser.RawConfigParser(strict=False)
conf.optionxform = str
configName = data['configurationName']
pc = manageConfiguration.PortCheck(self, {'port': data['ListenPort']}, configs)
if pc['status']:
try:
newData = []
with open(f'{WG_CONF_PATH}/{configName}.conf', 'r') as f:
conf.read(f'{WG_CONF_PATH}/{configName}.conf')
if not conf.has_section("Interface"):
return ret(status=False, reason="No [Interface] in configuration file")
l = ['ListenPort', 'PostUp', 'PostDown', 'PreUp', 'PreDown']
for i in l:
conf.set("Interface", i, data[i])
conf.remove_section("Peer")
newData = list(map(lambda x : f"{x[0]} = {x[1]}\n", list(conf.items("Interface"))))
originalData = f.readlines()
for i in range(len(originalData)):
if originalData[i] == "[Peer]\n":
originalData = originalData[i:]
break
newData.insert(0, "[Interface]\n")
newData.append("\n")
newData = newData + originalData
conf.clear()
try:
check = subprocess.check_output("wg-quick down " + configName,
shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
pass
with open(f'{WG_CONF_PATH}/{configName}.conf', 'w') as f:
for i in newData:
f.write(i)
try:
check = subprocess.check_output("wg-quick up " + configName,
shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
pass
return ret()
except FileNotFoundError as err:
return ret(status=False, reason=str(err))
else:
return pc
class settings:
def setTheme(self, theme, config, setConfig):
themes = ['light', 'dark']
if theme not in themes:
return ret(status=False, reason="Theme does not exist")
config['Server']['dashboard_theme'] = theme
setConfig(config)
return ret()

View File

@ -1,7 +0,0 @@
for ((i = 0 ; i<$1 ; i++ ))
do
privateKey=$(wg genkey)
presharedKey=$(wg genkey)
publicKey=$(wg pubkey <<< "$privateKey")
echo "$privateKey,$publicKey,$presharedKey"
done

File diff suppressed because it is too large Load Diff

View File

@ -5,4 +5,5 @@ pyotp
Flask
flask-cors
icmplib
gunicorn
gunicorn
requests

27
src/static/app/build.sh Executable file
View File

@ -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.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{_ as r,c as i,d as o,w as e,j as l,a as t,T as _,i as a,l as d,S as u}from"./index-BQ9jnFZu.js";const m={name:"configuration"},p={class:"mt-md-5 mt-3 text-body"};function f(x,h,k,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};

View File

@ -0,0 +1 @@
.confirmationContainer[data-v-a575be12]{background-color:#00000087;z-index:9999;backdrop-filter:blur(1px);-webkit-backdrop-filter:blur(1px)}.list1-enter-active[data-v-a575be12]{transition-delay:var(--6919ade8)!important}.card[data-v-1f718118],.title[data-v-1f718118]{width:100%}@media screen and (min-width: 700px){.card[data-v-1f718118],.title[data-v-1f718118]{width:700px}}.animate__fadeInUp[data-v-1f718118]{animation-timing-function:cubic-bezier(.42,0,.22,1)}.list1-move[data-v-1f718118],.list1-enter-active[data-v-1f718118],.list1-leave-active[data-v-1f718118]{transition:all .5s cubic-bezier(.42,0,.22,1)}.list1-enter-from[data-v-1f718118],.list1-leave-to[data-v-1f718118]{opacity:0;transform:translateY(30px)}.list1-leave-active[data-v-1f718118]{width:100%;position:absolute}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.fade-enter-active[data-v-a85a04a5]{transition-delay:var(--1d5189b2)!important}.configurationListTitle{.btn[data-v-16b5ab33]{border-radius:50%!important}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{$ as w,r as c,H as x,D as B,o as _,a as l,c as b,b as t,d as o,n as D,m as $,s as N,B as m,i as v,q as M,g as T}from"./index-BQ9jnFZu.js";import{L as s}from"./localeText-BzleuEA0.js";const I={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},R={class:"container d-flex h-100 w-100"},S={class:"m-auto modal-dialog-centered dashboardModal",style:{width:"700px"}},V={class:"card rounded-3 shadow flex-grow-1 bg-danger-subtle border-danger-subtle",id:"deleteConfigurationContainer"},A={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},L={class:"mb-0"},P={class:"card-body px-4 text-muted"},W={class:"mb-0"},q={key:0},z={key:1},E={key:2,class:"d-flex align-items-center gap-2"},G=["placeholder"],H=["disabled"],J={__name:"deleteConfiguration",emits:["backup"],setup(O,{emit:k}){const i=w().params.id,g=c(""),h=x(),p=B(),r=c(!1),y=()=>{clearInterval(p.Peers.RefreshInterval),r.value=!0,M("/api/deleteWireguardConfiguration",{Name:i},n=>{n.status?(h.push("/"),p.newMessage("Server","Configuration deleted","success")):r.value=!1})},u=c(!0),d=c([]),f=()=>{u.value=!0,T("/api/getWireguardConfigurationBackup",{configurationName:i},n=>{d.value=n.data,u.value=!1})};_(()=>{f()});const C=k;return(n,e)=>(l(),b("div",I,[t("div",R,[t("div",S,[t("div",V,[t("div",A,[t("h5",L,[o(s,{t:"Are you sure to delete this configuration?"})]),t("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=a=>n.$emit("close"))})]),t("div",P,[t("p",W,[o(s,{t:"Once you deleted this configuration:"})]),t("ul",null,[t("li",null,[o(s,{t:"All connected peers will get disconnected"})]),t("li",null,[o(s,{t:"Both configuration file (.conf) and database table related to this configuration will get deleted"})])]),t("div",{class:D(["alert",[u.value?"alert-secondary":d.value.length>0?"alert-success":"alert-danger"]])},[u.value?(l(),b("div",q,[e[5]||(e[5]=t("i",{class:"bi bi-search me-2"},null,-1)),o(s,{t:"Checking backups..."})])):d.value.length>0?(l(),b("div",z,[e[6]||(e[6]=t("i",{class:"bi bi-check-circle-fill me-2"},null,-1)),o(s,{t:"This configuration have "+d.value.length+" backups"},null,8,["t"])])):(l(),b("div",E,[e[9]||(e[9]=t("i",{class:"bi bi-x-circle-fill me-2"},null,-1)),o(s,{t:"This configuration have no backup"}),t("a",{role:"button",onClick:e[1]||(e[1]=a=>C("backup")),class:"ms-auto btn btn-sm btn-primary rounded-3"},[e[7]||(e[7]=t("i",{class:"bi bi-clock-history me-2"},null,-1)),o(s,{t:"Backup"})]),t("a",{role:"button",onClick:e[2]||(e[2]=a=>f()),class:"btn btn-sm btn-primary rounded-3"},e[8]||(e[8]=[t("i",{class:"bi bi-arrow-clockwise"},null,-1)]))]))],2),e[11]||(e[11]=t("hr",null,null,-1)),t("p",null,[o(s,{t:"If you're sure, please type in the configuration name below and click Delete"})]),$(t("input",{class:"form-control rounded-3 mb-3",placeholder:m(i),"onUpdate:modelValue":e[3]||(e[3]=a=>g.value=a),type:"text"},null,8,G),[[N,g.value]]),t("button",{class:"btn btn-danger w-100",onClick:e[4]||(e[4]=a=>y()),disabled:g.value!==m(i)||r.value},[e[10]||(e[10]=t("i",{class:"bi bi-trash-fill me-2 rounded-3"},null,-1)),r.value?(l(),v(s,{key:1,t:"Deleting..."})):(l(),v(s,{key:0,t:"Delete"}))],8,H)])])])])]))}};export{J as default};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
@media screen and (max-width: 567px){.inputGroup{&[data-v-4be4f48a]{flex-direction:column}h3[data-v-4be4f48a]{transform:rotate(90deg)}}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
@media screen and (max-width: 768px){.navbar-container[data-v-83a7789f]{position:absolute;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-83a7789f]{animation-direction:normal;display:block!important;animation-name:zoomInFade-83a7789f}}.navbar-container[data-v-83a7789f]{height:100vh}@supports (height: 100dvh){@media screen and (max-width: 768px){.navbar-container[data-v-83a7789f]{height:calc(100dvh - 50px)}}}@keyframes zoomInFade-83a7789f{0%{opacity:0;transform:translateY(60px);filter:blur(3px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}.messageCentre[data-v-ce114a8b]{top:1rem;right:1rem;width:calc(100% - 2rem)}main[data-v-ce114a8b]{height:100vh}@supports (height: 100dvh){@media screen and (max-width: 768px){main[data-v-ce114a8b]{height:calc(100dvh - 50px)}}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{_ as t,G as e,t as o}from"./index-BQ9jnFZu.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return e(this.t)}}};function a(c,r,n,p,_,i){return o(this.getLocaleText)}const x=t(s,[["render",a]]);export{x as L};

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -0,0 +1 @@
.message[data-v-f50b8f0c]{width:100%}@media screen and (min-width: 576px){.message[data-v-f50b8f0c]{width:400px}}

View File

@ -0,0 +1 @@
import{L as c}from"./localeText-BzleuEA0.js";import{d as n}from"./dayjs.min-BjPotxO2.js";import{_ as d,a as r,c as m,b as s,d as i,f as t,t as e,n as l,j as _}from"./index-BQ9jnFZu.js";const p={name:"message",methods:{dayjs:n},components:{LocaleText:c},props:{message:Object},mounted(){setTimeout(()=>{this.message.show=!1},5e3)}},g=["id"],h={class:"card-body"},f={class:"d-flex"},x={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},u={class:"ms-auto"};function b(y,v,w,T,j,a){const o=_("LocaleText");return r(),m("div",{class:l(["card shadow rounded-3 position-relative message ms-auto",{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"}]),id:this.message.id},[s("div",h,[s("div",f,[s("small",x,[i(o,{t:"FROM "}),t(" "+e(this.message.from),1)]),s("small",u,e(a.dayjs().format("hh:mm A")),1)]),t(" "+e(this.message.content),1)])],10,g)}const M=d(p,[["render",b],["__scopeId","data-v-f50b8f0c"]]);export{M};

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

View File

@ -0,0 +1 @@
.slide-up-enter-active[data-v-fcd3ae95],.slide-up-leave-active[data-v-fcd3ae95]{transition:all .2s cubic-bezier(.42,0,.22,1)}.slide-up-enter-from[data-v-fcd3ae95],.slide-up-leave-to[data-v-fcd3ae95]{opacity:0;transform:scale(.9)}@keyframes spin-fcd3ae95{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#check[data-v-fcd3ae95]{animation:cubic-bezier(.42,0,.22,1.3) .7s spin-fcd3ae95}

View File

@ -0,0 +1 @@
import{_ as f,D as m,r as _,a as s,c as a,b as e,d as l,w as g,T as h}from"./index-BQ9jnFZu.js";import{L as v}from"./localeText-BzleuEA0.js";const y={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},x={class:"container d-flex h-100 w-100"},w={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},C={class:"card rounded-3 shadow w-100"},k={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},F={class:"mb-0"},T={class:"card-body p-4"},D={class:"d-flex"},S=["disabled"],B={key:0,class:"d-block"},M={key:1,class:"d-block",id:"check"},G=["value"],L={__name:"peerConfigurationFile",props:{configurationFile:String},emits:["close"],setup(i,{emit:r}){const c=r,d=i,n=m(),o=_(!1),u=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(d.configurationFile).then(()=>{o.value=!0,setTimeout(()=>{o.value=!1},3e3)}).catch(()=>{n.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(o.value=!0,setTimeout(()=>{o.value=!1},3e3)):n.newMessage("WGDashboard","Failed to copy","danger"))};return(p,t)=>(s(),a("div",y,[e("div",x,[e("div",w,[e("div",C,[e("div",k,[e("h4",F,[l(v,{t:"Peer Configuration File"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=b=>c("close"))})]),e("div",T,[e("div",D,[e("button",{onClick:t[1]||(t[1]=b=>u()),disabled:o.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[l(h,{name:"slide-up",mode:"out-in"},{default:g(()=>[o.value?(s(),a("span",M,t[3]||(t[3]=[e("i",{class:"bi bi-check-circle-fill"},null,-1)]))):(s(),a("span",B,t[2]||(t[2]=[e("i",{class:"bi bi-clipboard-fill"},null,-1)])))]),_:1})],8,S)]),e("textarea",{style:{height:"300px"},class:"form-control w-100 rounded-3 mt-2",id:"peerConfigurationFile",value:i.configurationFile},null,8,G)])])])])]))}},W=f(L,[["__scopeId","data-v-fcd3ae95"]]);export{W as default};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.list-move[data-v-6d5fc831],.list-enter-active[data-v-6d5fc831],.list-leave-active[data-v-6d5fc831]{transition:all .3s ease}.list-enter-from[data-v-6d5fc831],.list-leave-to[data-v-6d5fc831]{opacity:0;transform:translateY(10px)}.list-leave-active[data-v-6d5fc831]{position:absolute}.peerSettingContainer[data-v-ddffd6ec]{background-color:#00000060;z-index:9998}div[data-v-ddffd6ec]{transition:.2s ease-in-out}.inactiveField[data-v-ddffd6ec]{opacity:.4}.card[data-v-ddffd6ec]{max-height:100%}

View File

@ -0,0 +1 @@
import{S as p,a as b}from"./schedulePeerJob-C54E7DJS.js";import{_ as h,W as u,p as m,j 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,k as g}from"./index-BQ9jnFZu.js";import{L as w}from"./localeText-BzleuEA0.js";import"./vue-datepicker-BkkJgrai.js";import"./dayjs.min-BjPotxO2.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"},j={class:"mb-0 fw-normal"},k={class:"card-body px-4 pb-4 pt-2 position-relative"},N={class:"d-flex align-items-center mb-3"},T={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",j,[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",k,[e("div",N,[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",T,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):x("",!0)]),_:1})])])])])])}const z=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{z as default};

View File

@ -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%}

View File

@ -0,0 +1 @@
import{S as b}from"./schedulePeerJob-C54E7DJS.js";import{_ as g,W as v,p as f,j as l,a as o,c as t,b as e,d as i,F as p,h,t as _,e as y,i as x}from"./index-BQ9jnFZu.js";import{L as J}from"./localeText-BzleuEA0.js";import"./vue-datepicker-BkkJgrai.js";import"./dayjs.min-BjPotxO2.js";const w={name:"peerJobsAllModal",setup(){return{store:v()}},components:{LocaleText:J,SchedulePeerJob:b},props:{configurationPeers:Array[Object]},methods:{getuuid(){return f()}},computed:{getAllJobs(){return this.configurationPeers.filter(r=>r.jobs.length>0)}}},A={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},$={class:"container d-flex h-100 w-100"},k={class:"m-auto modal-dialog-centered dashboardModal"},S={class:"card rounded-3 shadow",style:{width:"700px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},j={class:"mb-0 fw-normal"},P={class:"card-body px-4 pb-4 pt-2"},C={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},M={class:"accordion-header"},B=["data-bs-target"],N={key:0},D={class:"text-muted"},T=["id"],V={class:"accordion-body"},F={key:1,class:"card shadow-sm",style:{height:"153px"}},O={class:"card-body text-muted text-center d-flex"},W={class:"m-auto"};function E(r,s,I,R,q,z){const n=l("LocaleText"),u=l("SchedulePeerJob");return o(),t("div",A,[e("div",$,[e("div",k,[e("div",S,[e("div",L,[e("h4",j,[i(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:s[0]||(s[0]=a=>this.$emit("close"))})]),e("div",P,[this.getAllJobs.length>0?(o(),t("div",C,[(o(!0),t(p,null,h(this.getAllJobs,(a,d)=>(o(),t("div",{class:"accordion-item",key:a.id},[e("h2",M,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[a.name?(o(),t("span",N,_(a.name)+" • ",1)):y("",!0),e("samp",D,_(a.id),1)])])],8,B)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",V,[(o(!0),t(p,null,h(a.jobs,c=>(o(),x(u,{onDelete:s[1]||(s[1]=m=>this.$emit("refresh")),onRefresh:s[2]||(s[2]=m=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:c.JobID,pjob:c},null,8,["dropdowns","pjob"]))),128))])],8,T)]))),128))])):(o(),t("div",F,[e("div",O,[e("span",W,[i(n,{t:"No active job at the moment."})])])]))])])])])])}const X=g(w,[["render",E]]);export{X 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

View File

@ -0,0 +1 @@
import{b as a}from"./browser-CjSdxGTc.js";import{L as n}from"./localeText-BzleuEA0.js";import{_ as c,j as r,a as d,c as i,b as e,d as l}from"./index-BQ9jnFZu.js";const p={name:"peerQRCode",components:{LocaleText:n},props:{peerConfigData:String},mounted(){a.toCanvas(document.querySelector("#qrcode"),this.peerConfigData,o=>{o&&console.error(o)})}},_={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},m={class:"container d-flex h-100 w-100"},h={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},u={class:"card rounded-3 shadow"},f={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},b={class:"mb-0"},v={class:"card-body"},C={id:"qrcode",class:"rounded-3 shadow",ref:"qrcode"};function g(o,t,x,$,w,q){const s=r("LocaleText");return d(),i("div",_,[e("div",m,[e("div",h,[e("div",u,[e("div",f,[e("h4",b,[l(s,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=y=>this.$emit("close"))})]),e("div",v,[e("canvas",C,null,512)])])])])])}const Q=c(p,[["render",g]]);export{Q as default};

View File

@ -0,0 +1 @@
.toggleShowKey[data-v-a63ae8cb]{position:absolute;top:35px;right:12px}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{_ as g,D as f,q as h,j as p,a as s,c as r,b as t,d as o,n as m,i as n,t as _,e as b}from"./index-BQ9jnFZu.js";import{d}from"./dayjs.min-BjPotxO2.js";import{V as y}from"./vue-datepicker-BkkJgrai.js";import{L as S}from"./localeText-BzleuEA0.js";const k={name:"peerShareLinkModal",props:{peer:Object},components:{LocaleText:S,VueDatePicker:y},data(){return{dataCopy:void 0,loading:!1}},setup(){return{store:f()}},mounted(){this.dataCopy=JSON.parse(JSON.stringify(this.peer.ShareLink)).at(0)},watch:{"peer.ShareLink":{deep:!0,handler(e,a){a.length!==e.length&&(this.dataCopy=JSON.parse(JSON.stringify(this.peer.ShareLink)).at(0))}}},methods:{startSharing(){this.loading=!0,h("/api/sharePeer/create",{Configuration:this.peer.configuration.Name,Peer:this.peer.id,ExpireDate:d().add(7,"d").format("YYYY-MM-DD HH:mm:ss")},e=>{e.status?(this.peer.ShareLink=e.data,this.dataCopy=e.data.at(0)):this.store.newMessage("Server","Share link failed to create. Reason: "+e.message,"danger"),this.loading=!1})},updateLinkExpireDate(){h("/api/sharePeer/update",this.dataCopy,e=>{e.status?(this.dataCopy=e.data.at(0),this.peer.ShareLink=e.data,this.store.newMessage("Server","Link expire date updated","success")):this.store.newMessage("Server","Link expire date failed to update. Reason: "+e.message,"danger"),this.loading=!1})},stopSharing(){this.loading=!0,this.dataCopy.ExpireDate=d().format("YYYY-MM-DD HH:mm:ss"),this.updateLinkExpireDate()},parseTime(e){e?this.dataCopy.ExpireDate=d(e).format("YYYY-MM-DD HH:mm:ss"):this.dataCopy.ExpireDate=void 0,this.updateLinkExpireDate()}},computed:{getUrl(){const e=this.store.getActiveCrossServer();return e?`${e.host}/${this.$router.resolve({path:"/share",query:{ShareID:this.dataCopy.ShareID}}).href}`:window.location.origin+window.location.pathname+this.$router.resolve({path:"/share",query:{ShareID:this.dataCopy.ShareID}}).href}}},x={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},v={class:"container d-flex h-100 w-100"},C={class:"m-auto modal-dialog-centered dashboardModal",style:{width:"500px"}},D={class:"card rounded-3 shadow flex-grow-1"},w={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4"},L={class:"mb-0"},M={key:0,class:"card-body px-4 pb-4"},Y={key:0},$={class:"mb-3 text-muted"},E=["disabled"],H={key:1},V={class:"d-flex gap-2 mb-4"},N=["href"],P={class:"d-flex flex-column gap-2 mb-3"},O=["disabled"];function T(e,a,U,B,I,c){const i=p("LocaleText"),u=p("VueDatePicker");return s(),r("div",x,[t("div",v,[t("div",C,[t("div",D,[t("div",w,[t("h4",L,[o(i,{t:"Share Peer"})]),t("button",{type:"button",class:"btn-close ms-auto",onClick:a[0]||(a[0]=l=>this.$emit("close"))})]),this.peer.ShareLink?(s(),r("div",M,[this.dataCopy?(s(),r("div",H,[t("div",V,[a[4]||(a[4]=t("i",{class:"bi bi-link-45deg"},null,-1)),t("a",{href:this.getUrl,class:"text-decoration-none",target:"_blank"},_(c.getUrl),9,N)]),t("div",P,[t("small",null,[a[5]||(a[5]=t("i",{class:"bi bi-calendar me-2"},null,-1)),o(i,{t:"Expire At"})]),o(u,{is24:!0,"min-date":new Date,"model-value":this.dataCopy.ExpireDate,"onUpdate:modelValue":this.parseTime,"time-picker-inline":"",format:"yyyy-MM-dd HH:mm:ss","preview-format":"yyyy-MM-dd HH:mm:ss",dark:this.store.Configuration.Server.dashboard_theme==="dark"},null,8,["min-date","model-value","onUpdate:modelValue","dark"])]),t("button",{onClick:a[2]||(a[2]=l=>this.stopSharing()),disabled:this.loading,class:"w-100 btn bg-danger-subtle text-danger-emphasis border-1 border-danger-subtle rounded-3 shadow-sm"},[t("span",{class:m({"animate__animated animate__flash animate__infinite animate__slower":this.loading})},a[6]||(a[6]=[t("i",{class:"bi bi-send-slash-fill me-2"},null,-1)]),2),this.loading?(s(),n(i,{key:0,t:"Stop Sharing..."})):(s(),n(i,{key:1,t:"Stop Sharing"}))],8,O)])):(s(),r("div",Y,[t("h6",$,[o(i,{t:"Currently the peer is not sharing"})]),t("button",{onClick:a[1]||(a[1]=l=>this.startSharing()),disabled:this.loading,class:"w-100 btn bg-success-subtle text-success-emphasis border-1 border-success-subtle rounded-3 shadow-sm"},[t("span",{class:m({"animate__animated animate__flash animate__infinite animate__slower":this.loading})},a[3]||(a[3]=[t("i",{class:"bi bi-send-fill me-2"},null,-1)]),2),this.loading?(s(),n(i,{key:0,t:"Sharing..."})):(s(),n(i,{key:1,t:"Start Sharing"}))],8,E)]))])):b("",!0)])])])])}const R=g(k,[["render",T]]);export{R as default};

File diff suppressed because one or more lines are too long

View File

@ -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)}

View File

@ -0,0 +1 @@
.dropdownIcon[data-v-626f1988]{transition:all .2s ease-in-out}.dropdownIcon.active[data-v-626f1988]{transform:rotate(180deg)}.steps{&[data-v-f0245d51]{transition:all .3s ease-in-out;opacity:.3}&.active[data-v-f0245d51]{opacity:1}}

File diff suppressed because one or more lines are too long

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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)}

View File

@ -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-0f26916d]{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)}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import{_ as u,D as m,q as p,c as r,b as e,d as o,f as c,t as h,e as f,m as l,s as d,a as i,j as w}from"./index-BQ9jnFZu.js";import{L as g}from"./localeText-BzleuEA0.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"},q={for:"confirmPassword",class:"mb-1 text-muted"},$=["disabled"],A={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",q,[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",A,[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 W=u(b,[["render",B]]);export{W as default};

View File

@ -0,0 +1 @@
.animate__fadeInUp[data-v-1b44aacd]{animation-timing-function:cubic-bezier(.42,0,.22,1)}

View File

@ -0,0 +1 @@
import{_,r,D as p,g as u,c as m,b as t,d as c,$ as h,a as f,j as b}from"./index-BQ9jnFZu.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-BzleuEA0.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"},B={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},k={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 j(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",B,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),c(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",k,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 $=_(g,[["render",j],["__scopeId","data-v-1b44aacd"]]);export{$ as default};

File diff suppressed because one or more lines are too long

View File

@ -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-eca07c7a]{width:100%!important}.login-box div[data-v-eca07c7a]{width:auto!important}}.navbar[data-v-eca07c7a]{display:none!important}

View File

@ -0,0 +1 @@
import{_ as h,D as m,g as p,q as f,c as b,b as t,d as i,t as _,m as v,s as g,i as d,w as r,j as c,a as n}from"./index-BQ9jnFZu.js";import{b as x}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-BzleuEA0.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"}},q={for:"totp",class:"mb-2"},D={class:"text-muted"},S={class:"form-group mb-2"},A=["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,j){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",q,[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,A),[[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};

View File

@ -0,0 +1 @@
import{_ as h,W as b,g,c as o,b as t,d as n,m as y,s as f,A as v,w as r,T as c,a,f as x,F as u,h as m,n as T,z as k,t as i,e as A,j as _}from"./index-BQ9jnFZu.js";import{O as w}from"./osmap-DVGZjOTw.js";import{L as R}from"./localeText-BzleuEA0.js";const M={name:"traceroute",components:{LocaleText:R,OSMap:w},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:b()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,g("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},S={class:"mt-md-5 mt-3 text-body"},$={class:"container-md"},C={class:"mb-3 text-body"},L={class:"d-flex gap-2 flex-column mb-5"},P={class:"mb-1 text-muted",for:"ipAddress"},V=["disabled"],N=["disabled"],O={key:0,class:"d-block"},z={key:1,class:"d-block"},B={class:"position-relative"},I={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};function J(d,s,Q,X,Y,Z){const l=_("LocaleText"),p=_("OSMap");return a(),o("div",S,[t("div",$,[t("h3",C,[n(l,{t:"Traceroute"})]),t("div",L,[t("div",null,[t("label",P,[t("small",null,[n(l,{t:"Enter IP Address / Hostname"})])]),y(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=v(e=>this.execute(),["enter"])),type:"text"},null,40,V),[[f,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 mt-3 position-relative",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(c,{name:"slide"},{default:r(()=>[this.tracing?(a(),o("span",z,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)]))):(a(),o("span",O,s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),x("Trace! ")])))]),_:1})],8,N)]),t("div",B,[n(c,{name:"ping"},{default:r(()=>[this.tracerouteResult?(a(),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(l,{t:"Hop"})]),t("th",H,[n(l,{t:"IP Address"})]),t("th",K,[n(l,{t:"Average RTT (ms)"})]),t("th",W,[n(l,{t:"Min RTT (ms)"})]),t("th",j,[n(l,{t:"Max RTT (ms)"})]),t("th",U,[n(l,{t:"Geolocation"})])])]),t("tbody",null,[(a(!0),o(u,null,m(this.tracerouteResult,(e,tt)=>(a(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,i(e.ip),1)]),t("td",null,[t("small",null,i(e.avg_rtt),1)]),t("td",null,[t("small",null,i(e.min_rtt),1)]),t("td",null,[t("small",null,i(e.max_rtt),1)]),t("td",null,[e.geo.city&&e.geo.country?(a(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):A("",!0)])]))),256))])])])])):(a(),o("div",I,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(a(),o(u,null,m(5,e=>t("div",{class:T(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:k({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const ot=h(M,[["render",J],["__scopeId","data-v-549eb223"]]);export{ot as default};

View File

@ -0,0 +1 @@
.pingPlaceholder[data-v-549eb223]{width:100%;height:40px}.ping-leave-active[data-v-549eb223]{position:absolute}table th[data-v-549eb223],table td[data-v-549eb223]{padding:.5rem}.table[data-v-549eb223]>:not(caption)>*>*{background-color:transparent!important}.ping-move[data-v-549eb223],.ping-enter-active[data-v-549eb223],.ping-leave-active[data-v-549eb223]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.ping-leave-active[data-v-549eb223]{position:absolute;width:100%}.ping-enter-from[data-v-549eb223],.ping-leave-to[data-v-549eb223]{opacity:0;filter:blur(3px)}

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

BIN
src/static/app/dist/img/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1,14 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/static/app/dist/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WGDashboard</title>
<script type="module" crossorigin src="/static/app/dist/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/static/app/dist/assets/index.css">
</head>
<body>
<div id="app" class="w-100 vh-100"></div>
</body>
<head>
<meta charset="UTF-8">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="WGDashboard">
<meta name="apple-mobile-web-app-title" content="WGDashboard">
<link rel="manifest" href="/static/app/dist/json/manifest.json">
<link rel="icon" href="/static/app/dist/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WGDashboard</title>
<script type="module" crossorigin src="/static/app/dist/assets/index-BQ9jnFZu.js"></script>
<link rel="stylesheet" crossorigin href="/static/app/dist/assets/index-D2eeEsuX.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

44
src/static/app/dist/json/manifest.json vendored Normal file
View File

@ -0,0 +1,44 @@
{
"theme_color": "#343a40",
"background_color": "#343a40",
"display": "fullscreen",
"scope": "/",
"start_url": "/",
"name": "WGDashboard",
"short_name": "WGDashboard",
"screenshots": [
{
"src": "https://donaldzou.github.io/WGDashboard-Documentation/images/sign-in.png",
"sizes": "2880x1826",
"type": "image/png",
"form_factor": "wide"
},
{
"src": "https://donaldzou.github.io/WGDashboard-Documentation/images/sign-in.png",
"sizes": "2880x1826",
"type": "image/png"
}
],
"icons": [
{
"src": "../img/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "../img/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "../img/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "../img/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 MiB

View File

@ -1,13 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WGDashboard</title>
</head>
<body>
<div id="app" class="w-100 vh-100"></div>
<script type="module" src="./src/main.js"></script>
</body>
<head>
<meta charset="UTF-8">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="WGDashboard">
<meta name="apple-mobile-web-app-title" content="WGDashboard">
<link rel="manifest" href="/json/manifest.json">
<link rel="icon" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WGDashboard</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./src/main.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,13 @@
{
"name": "app",
"version": "4.0.0",
"version": "4.1.4",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"build electron": "vite build && vite build --mode electron && cd ../../../../WGDashboard-Desktop && electron-builder",
"buildcommitpush": "./build.sh",
"build electron": "vite build && vite build --mode electron && cd ../../../../WGDashboard-Desktop && electron-builder --mac --win",
"preview": "vite preview"
},
"dependencies": {
@ -15,7 +16,7 @@
"@vueuse/shared": "^10.9.0",
"animate.css": "^4.1.1",
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.2",
"bootstrap-icons": "^1.11.3",
"cidr-tools": "^7.0.4",
"dayjs": "^1.11.12",
"electron-builder": "^24.13.3",
@ -23,6 +24,7 @@
"i": "^0.3.7",
"is-cidr": "^5.0.3",
"npm": "^10.5.0",
"ol": "^10.2.1",
"pinia": "^2.1.7",
"qrcode": "^1.5.3",
"qrcodejs": "^1.0.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

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