mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-22 15:20:09 +01:00
Working on some updates
This commit is contained in:
parent
fd0e519e41
commit
47efb644b7
130
README.md
130
README.md
@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
## 📣 What's New: v4.0
|
## 📣 What's New: v4.0
|
||||||
|
|
||||||
> 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 who sponsored me GitHub :heart:
|
|
||||||
|
|
||||||
- 🎉 **New Features**
|
- 🎉 **New Features**
|
||||||
- **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.
|
- **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 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.
|
- **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.
|
||||||
- **API Key for WGDashboard's REST API**: You can now request all the api endpoint used in the dashboard. For more details please review the API Documentation below.
|
- **API Key for WGDashboard's REST API**: You can now request all the api endpoint used in the dashboard. For more details please review the API Documentation below.
|
||||||
- **Logging**: Dashboard will now log all activity on the dashboard and API requests.
|
- **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.
|
- **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.
|
||||||
@ -36,9 +36,14 @@
|
|||||||
- Improved SQL query efficient
|
- Improved SQL query efficient
|
||||||
- Removed all templates, except for `index.html` where it will load the Vue.js app.
|
- Removed all templates, except for `index.html` where it will load the Vue.js app.
|
||||||
|
|
||||||
|
- **🥘 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 :)
|
||||||
**For users who is using `v2.x.x` please be sure to read [this](#please-note-for-user-who-is-using-v231-or-below) before updating WGDashboard**
|
> 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>
|
<hr>
|
||||||
|
|
||||||
@ -70,7 +75,7 @@
|
|||||||
- Edit peer information
|
- Edit peer information
|
||||||
- Delete peers with ease
|
- Delete peers with ease
|
||||||
- Restrict peers
|
- Restrict peers
|
||||||
- Generate QR Code and `.conf` file for 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
|
- Schedule jobs to delete / restrict peer when conditions are met
|
||||||
- View real time peer status
|
- View real time peer status
|
||||||
- Testing tool: Ping and Traceroute to your peer
|
- Testing tool: Ping and Traceroute to your peer
|
||||||
@ -79,7 +84,7 @@
|
|||||||
## 📝 Requirement
|
## 📝 Requirement
|
||||||
|
|
||||||
- Recommend the following OS, tested by our beloved users:
|
- Recommend the following OS, tested by our beloved users:
|
||||||
- [x] Ubuntu 18.04.1 LTS, 20.04.1 LTS, 22.04.4 LTS [@Me]
|
- [x] Ubuntu 18.04.1 LTS, 20.04.1 LTS, 22.04.4 LTS, 24.02 LTS, Fedora 38 [@Me]
|
||||||
- [x] Debian GNU/Linux 10 (buster) [❤️ @[robchez](https://github.com/robchez)]
|
- [x] Debian GNU/Linux 10 (buster) [❤️ @[robchez](https://github.com/robchez)]
|
||||||
- [x] AlmaLinux 8.4 (Electric Cheetah) [❤️ @[barry-smithjr](https://github.com/)]
|
- [x] AlmaLinux 8.4 (Electric Cheetah) [❤️ @[barry-smithjr](https://github.com/)]
|
||||||
- [x] CentOS 7 [❤️ @[PrzemekSkw](https://github.com/PrzemekSkw)]
|
- [x] CentOS 7 [❤️ @[PrzemekSkw](https://github.com/PrzemekSkw)]
|
||||||
@ -193,40 +198,33 @@ In the `src` folder, it contained a file called `wg-dashboard.service`, we can u
|
|||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
After=network.service
|
After=syslog.target network-online.target
|
||||||
|
Wants=wg-quick.target
|
||||||
|
ConditionPathIsDirectory=/etc/wireguard
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
WorkingDirectory=<your dashboard directory full path here>
|
Type=forking
|
||||||
ExecStart=/usr/bin/python3 <your dashboard directory full path here>/dashboard.py
|
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
|
Restart=always
|
||||||
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, we need to replace both `<your dashboard directory full path here>` to the one you just copied from step 2. After doing this, the file will become something like this, your file might be different:
|
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:
|
||||||
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
After=netword.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
WorkingDirectory=/root/wgdashboard/src
|
|
||||||
ExecStart=/usr/bin/python3 /root/wgdashboard/src/dashboard.py
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target
|
|
||||||
```
|
|
||||||
|
|
||||||
**Be aware that after the value of `WorkingDirectory`, it does not have a `/` (slash).** And then save the file after you edited it
|
**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
|
4. Copy the service file to systemd folder
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cp wg-dashboard.service /etc/systemd/system/wg-dashboard.service
|
$ 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.
|
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.
|
||||||
@ -245,28 +243,31 @@ In the `src` folder, it contained a file called `wg-dashboard.service`, we can u
|
|||||||
```bash
|
```bash
|
||||||
$ sudo systemctl status wg-dashboard.service
|
$ sudo systemctl status wg-dashboard.service
|
||||||
```
|
```
|
||||||
|
|
||||||
And you should see something like this
|
And you should see something like this
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
● wg-dashboard.service
|
● wg-dashboard.service
|
||||||
Loaded: loaded (/etc/systemd/system/wg-dashboard.service; enabled; vendor preset: enabled)
|
Loaded: loaded (/etc/systemd/system/wg-dashboard.service; enabled; vendor preset: enabled)
|
||||||
Active: active (running) since Tue 2021-08-03 22:31:26 UTC; 4s ago
|
Active: active (running) since Wed 2024-08-14 22:21:47 EDT; 55s ago
|
||||||
Main PID: 6602 (python3)
|
Process: 494968 ExecStart=/home/donaldzou/Wireguard-Dashboard/src/wgd.sh start (code=exited, status=0/SUCCESS)
|
||||||
Tasks: 1 (limit: 453)
|
Main PID: 495005 (gunicorn)
|
||||||
Memory: 26.1M
|
Tasks: 5 (limit: 4523)
|
||||||
CGroup: /system.slice/wg-dashboard.service
|
Memory: 36.8M
|
||||||
└─6602 /usr/bin/python3 /root/wgdashboard/src/dashboard.py
|
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 03 22:31:26 ubuntu-wg systemd[1]: Started wg-dashboard.service.
|
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 03 22:31:27 ubuntu-wg python3[6602]: * Serving Flask app1 "WGDashboard" (lazy loading)
|
Aug 14 22:21:40 wg sudo[494978]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
|
||||||
Aug 03 22:31:27 ubuntu-wg python3[6602]: * Environment: production
|
Aug 14 22:21:40 wg wgd.sh[494979]: [WGDashboard] WGDashboard w/ Gunicorn will be running on 0.0.0.0:10086
|
||||||
Aug 03 22:31:27 ubuntu-wg python3[6602]: WARNING: This is a development server. Do not use it in a production deployment.
|
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 03 22:31:27 ubuntu-wg python3[6602]: Use a production WSGI server instead.
|
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 03 22:31:27 ubuntu-wg python3[6602]: * Debug mode: off
|
Aug 14 22:21:40 wg sudo[494978]: pam_unix(sudo:session): session closed for user root
|
||||||
Aug 03 22:31:27 ubuntu-wg python3[6602]: * Running on all addresses.
|
Aug 14 22:21:45 wg wgd.sh[494968]: [WGDashboard] Checking if WGDashboard w/ Gunicorn started successfully
|
||||||
Aug 03 22:31:27 ubuntu-wg python3[6602]: WARNING: This is a development server. Do not use it in a production deployment.
|
Aug 14 22:21:47 wg wgd.sh[494968]: [WGDashboard] WGDashboard w/ Gunicorn started successfully
|
||||||
Aug 03 22:31:27 ubuntu-wg python3[6602]: * Running on http://0.0.0.0:10086/ (Press CTRL+C to quit)
|
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.
|
If you see `Active:` followed by `active (running) since...` then it means it run correctly.
|
||||||
@ -339,29 +340,12 @@ Endpoint = 0.0.0.0:51820
|
|||||||
|
|
||||||
## ❓ How to update the dashboard?
|
## ❓ How to update the dashboard?
|
||||||
|
|
||||||
#### **Please note for user who is using `v2.3.1` or below**
|
#### **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.
|
||||||
|
|
||||||
- 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:.
|
#### **Please note for users who are using `v2.3.1` or below**
|
||||||
|
|
||||||
<hr>
|
- 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:.
|
||||||
|
|
||||||
#### Update Method 1 (For `v3.0` or above)
|
|
||||||
|
|
||||||
1. Change your directory to `wgdashboard/src`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd wgdashboard/src
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Update the dashboard with the following
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./wgd.sh update
|
|
||||||
```
|
|
||||||
|
|
||||||
> If this doesn't work, please use the method below. Sorry about that :(
|
|
||||||
|
|
||||||
#### Update Method 2
|
|
||||||
|
|
||||||
|
|
||||||
1. Change your directory to `wgdashboard`
|
1. Change your directory to `wgdashboard`
|
||||||
@ -372,26 +356,24 @@ Endpoint = 0.0.0.0:51820
|
|||||||
|
|
||||||
2. Update the dashboard
|
2. Update the dashboard
|
||||||
```shell
|
```shell
|
||||||
git pull https://github.com/donaldzou/WGDashboard.git v3.0.5 --force
|
git pull https://github.com/donaldzou/WGDashboard.git v4.0 --force
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Install
|
3. Install
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./wgd.sh install
|
sudo ./wgd.sh install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Starting with `v3.0`, you can simply do `sudo ./wgd.sh update` !! (I hope)
|
||||||
|
|
||||||
Starting with `v3.0`, you can simply do `./wgd.sh update` !! (I hope, lol)
|
|
||||||
|
|
||||||
## 🥘 Experimental Functions
|
## 🥘 Experimental Functions
|
||||||
|
|
||||||
#### Progressive Web App (PWA) for WGDashboard
|
### Cross-Server Access
|
||||||
|
|
||||||
|
Starting with `v4.0`, you can access WGDashboards on other server through one WGDashboard with API Keys
|
||||||
|
|
||||||
- With `v3.0`, I've added a `manifest.json` into the dashboard, so user could add their dashboard as a PWA to their browser or mobile device.
|
|
||||||
|
|
||||||
<img src="img/PWA.gif"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4
src/static/app/dist/assets/index.css
vendored
4
src/static/app/dist/assets/index.css
vendored
File diff suppressed because one or more lines are too long
56
src/static/app/dist/assets/index.js
vendored
56
src/static/app/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
@ -108,7 +108,6 @@ export default {
|
|||||||
</h3>
|
</h3>
|
||||||
<h3 class="text-body mb-0">Add Peers</h3>
|
<h3 class="text-body mb-0">Add Peers</h3>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column gap-2">
|
<div class="d-flex flex-column gap-2">
|
||||||
<BulkAdd :saving="saving" :data="this.data" :availableIp="this.availableIp"></BulkAdd>
|
<BulkAdd :saving="saving" :data="this.data" :availableIp="this.availableIp"></BulkAdd>
|
||||||
|
@ -402,7 +402,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!this.loading">
|
<div v-if="!this.loading" class="container-md">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div>
|
<div>
|
||||||
<small CLASS="text-muted">CONFIGURATION</small>
|
<small CLASS="text-muted">CONFIGURATION</small>
|
||||||
@ -545,10 +545,7 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-3">
|
||||||
<!-- <div class="d-flex align-items-center gap-3 mb-2">-->
|
|
||||||
<!-- <h3>Peers</h3>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<PeerSearch
|
<PeerSearch
|
||||||
@jobsAll="this.peerScheduleJobsAll.modalOpen = true"
|
@jobsAll="this.peerScheduleJobsAll.modalOpen = true"
|
||||||
@jobLogs="this.peerScheduleJobsLogs.modalOpen = true"
|
@jobLogs="this.peerScheduleJobsLogs.modalOpen = true"
|
||||||
|
@ -30,7 +30,9 @@ export default {
|
|||||||
'60000': '1 Minutes'
|
'60000': '1 Minutes'
|
||||||
},
|
},
|
||||||
searchString: "",
|
searchString: "",
|
||||||
searchStringTimeout: undefined
|
searchStringTimeout: undefined,
|
||||||
|
showDisplaySettings: false,
|
||||||
|
showMoreSettings: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -93,68 +95,98 @@ export default {
|
|||||||
@click="this.downloadAllPeer()">
|
@click="this.downloadAllPeer()">
|
||||||
<i class="bi bi-download me-2"></i> Download All
|
<i class="bi bi-download me-2"></i> Download All
|
||||||
</button>
|
</button>
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1 mt-3 mt-md-0">
|
||||||
<input class="form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle shadow-sm w-100"
|
<input class="form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle shadow-sm w-100"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
id="searchPeers"
|
id="searchPeers"
|
||||||
@keyup="this.debounce()"
|
@keyup="this.debounce()"
|
||||||
v-model="this.searchString">
|
v-model="this.searchString">
|
||||||
</div>
|
</div>
|
||||||
<div class="">
|
<button
|
||||||
|
@click="this.showDisplaySettings = true"
|
||||||
</div>
|
class="btn text-secondary-emphasis bg-secondary-subtle rounded-3 border-1 border-secondary-subtle shadow-sm"
|
||||||
|
type="button" aria-expanded="false">
|
||||||
<div class="dropdown dropup">
|
<i class="bi bi-filter-circle me-2"></i>
|
||||||
<button class="btn text-secondary-emphasis bg-secondary-subtle rounded-3 border-1 border-secondary-subtle shadow-sm"
|
Display
|
||||||
type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
</button>
|
||||||
<i class="bi bi-filter-circle me-2"></i>
|
<button class="btn text-secondary-emphasis bg-secondary-subtle rounded-3 border-1 border-secondary-subtle shadow-sm"
|
||||||
Display
|
@click="this.showMoreSettings = true"
|
||||||
</button>
|
type="button" aria-expanded="false">
|
||||||
<ul class="dropdown-menu mt-2 shadow rounded-3 animate__animated animation__fadeInDropdown dropdown-menu-end">
|
<i class="bi bi-three-dots"></i>
|
||||||
<li>
|
</button>
|
||||||
<small class="dropdown-header">Sort by</small>
|
<Transition name="zoom">
|
||||||
</li>
|
<div
|
||||||
<li v-for="(value, key) in this.sort">
|
v-if="this.showDisplaySettings"
|
||||||
<a class="dropdown-item d-flex align-items-center" role="button" @click="this.updateSort(key)">
|
class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll displayModal">
|
||||||
<small class="me-auto">{{value}}</small>
|
<div class="container-md d-flex h-100 w-100">
|
||||||
<i class="bi bi-check text-primary"
|
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||||
v-if="store.Configuration.Server.dashboard_sort === key"></i>
|
<div class="card rounded-3 shadow w-100">
|
||||||
</a>
|
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2">
|
||||||
</li>
|
<h4 class="mb-0 fw-normal">Display
|
||||||
<li><hr class="dropdown-divider"></li>
|
</h4>
|
||||||
<li>
|
<button type="button" class="btn-close ms-auto" @click="this.showDisplaySettings = false"></button>
|
||||||
<small class="dropdown-header">Refresh Interval</small>
|
</div>
|
||||||
</li>
|
<div class="card-body px-4 pb-4 d-flex gap-3 flex-column">
|
||||||
<li v-for="(value, key) in this.interval">
|
<div>
|
||||||
<a class="dropdown-item d-flex" role="button" @click="updateRefreshInterval(key)">
|
<p class="text-muted fw-bold mb-2"><small>Sort by</small></p>
|
||||||
<small class="me-auto">{{value}}</small>
|
<div class="list-group">
|
||||||
<i class="bi bi-check text-primary"
|
<a v-for="(value, key) in this.sort" class="list-group-item list-group-item-action d-flex" role="button" @click="this.updateSort(key)">
|
||||||
v-if="store.Configuration.Server.dashboard_refresh_interval === key"></i>
|
<span class="me-auto">{{value}}</span>
|
||||||
</a>
|
<i class="bi bi-check text-primary"
|
||||||
</li>
|
v-if="store.Configuration.Server.dashboard_sort === key"></i>
|
||||||
</ul>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropup">
|
</div>
|
||||||
<button class="btn text-secondary-emphasis bg-secondary-subtle rounded-3 border-1 border-secondary-subtle shadow-sm"
|
<div>
|
||||||
type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<p class="text-muted fw-bold mb-2"><small>Refresh interval</small></p>
|
||||||
<i class="bi bi-three-dots"></i>
|
<div class="list-group">
|
||||||
</button>
|
<a v-for="(value, key) in this.interval"
|
||||||
<ul class="dropdown-menu shadow mt-2 rounded-3 animate__animated animation__fadeInDropdown">
|
class="list-group-item list-group-item-action d-flex" role="button"
|
||||||
<li>
|
@click="this.updateRefreshInterval(key)">
|
||||||
<h6 class="dropdown-header">Peer Jobs</h6>
|
<span class="me-auto">{{value}}</span>
|
||||||
</li>
|
<i class="bi bi-check text-primary"
|
||||||
<li>
|
v-if="store.Configuration.Server.dashboard_refresh_interval === key"></i>
|
||||||
<a role="button" class="dropdown-item" @click="this.$emit('jobsAll')">
|
</a>
|
||||||
Active Jobs
|
</div>
|
||||||
</a>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
<li>
|
</div>
|
||||||
<a role="button" class="dropdown-item" @click="this.$emit('jobLogs')">
|
</div>
|
||||||
Logs
|
</div>
|
||||||
</a>
|
</div>
|
||||||
</li>
|
</Transition>
|
||||||
</ul>
|
<Transition name="zoom">
|
||||||
</div>
|
<div
|
||||||
|
v-if="this.showMoreSettings"
|
||||||
|
class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll displayModal">
|
||||||
|
<div class="container-md d-flex h-100 w-100">
|
||||||
|
<div class="m-auto modal-dialog-centered dashboardModal">
|
||||||
|
<div class="card rounded-3 shadow w-100">
|
||||||
|
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2">
|
||||||
|
<h4 class="mb-0 fw-normal">Configuration Settings
|
||||||
|
</h4>
|
||||||
|
<button type="button" class="btn-close ms-auto" @click="this.showMoreSettings = false"></button>
|
||||||
|
</div>
|
||||||
|
<div class="card-body px-4 pb-4 d-flex gap-3 flex-column">
|
||||||
|
<div>
|
||||||
|
<p class="text-muted fw-bold mb-2"><small>Peer Jobs</small></p>
|
||||||
|
<div class="list-group">
|
||||||
|
<a class="list-group-item list-group-item-action d-flex" role="button"
|
||||||
|
@click="this.$emit('jobsAll')">
|
||||||
|
Active Jobs
|
||||||
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-action d-flex" role="button"
|
||||||
|
@click="this.$emit('jobLogs')">
|
||||||
|
Logs
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -180,9 +212,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.displayModal .dashboardModal{
|
||||||
|
width: 400px !important;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.peerSearchContainer{
|
.peerSearchContainer{
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.peerSettingContainer .dashboardModal{
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -31,7 +31,7 @@ export default {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-md-5 mt-3">
|
||||||
<div class="container-md">
|
<div class="container-md">
|
||||||
<div class="d-flex mb-4 configurationListTitle">
|
<div class="d-flex mb-4 configurationListTitle">
|
||||||
<h3 class="text-body d-flex">
|
<h3 class="text-body d-flex">
|
||||||
|
@ -41,8 +41,8 @@ export default {
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<RouterLink :to="'/configuration/'+c.Name + '/peers'" class="nav-link nav-conf-link rounded-3"
|
<RouterLink :to="'/configuration/'+c.Name + '/peers'" class="nav-link nav-conf-link rounded-3"
|
||||||
active-class="active"
|
active-class="active"
|
||||||
|
|
||||||
v-for="c in this.wireguardConfigurationsStore.Configurations">
|
v-for="c in this.wireguardConfigurationsStore.Configurations">
|
||||||
|
<span class="dot me-2" :class="{active: c.Status}"></span>
|
||||||
{{c.Name}}
|
{{c.Name}}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
@ -18,8 +18,9 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
async handshake(){
|
async handshake(){
|
||||||
this.active = false;
|
this.active = false;
|
||||||
this.refreshing = true;
|
|
||||||
if (this.server.host && this.server.apiKey){
|
if (this.server.host && this.server.apiKey){
|
||||||
|
|
||||||
|
this.refreshing = true;
|
||||||
this.startTime = undefined;
|
this.startTime = undefined;
|
||||||
this.endTime = undefined;
|
this.endTime = undefined;
|
||||||
this.startTime = dayjs()
|
this.startTime = dayjs()
|
||||||
|
@ -26,7 +26,7 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
|
|||||||
this.ActiveServerConfiguration = localStorage.getItem("ActiveCrossServerConfiguration");
|
this.ActiveServerConfiguration = localStorage.getItem("ActiveCrossServerConfiguration");
|
||||||
}
|
}
|
||||||
if (currentConfiguration === null){
|
if (currentConfiguration === null){
|
||||||
localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
window.localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
||||||
}else{
|
}else{
|
||||||
this.CrossServerConfiguration = JSON.parse(currentConfiguration)
|
this.CrossServerConfiguration = JSON.parse(currentConfiguration)
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export const DashboardConfigurationStore = defineStore('DashboardConfigurationSt
|
|||||||
|
|
||||||
},
|
},
|
||||||
syncCrossServerConfiguration(){
|
syncCrossServerConfiguration(){
|
||||||
localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
window.localStorage.setItem('CrossServerConfiguration', JSON.stringify(this.CrossServerConfiguration))
|
||||||
},
|
},
|
||||||
addCrossServerConfiguration(){
|
addCrossServerConfiguration(){
|
||||||
this.CrossServerConfiguration.ServerList[v4().toString()] = {host: "", apiKey: "", active: false}
|
this.CrossServerConfiguration.ServerList[v4().toString()] = {host: "", apiKey: "", active: false}
|
||||||
|
@ -20,8 +20,8 @@ const getUrl = (url) => {
|
|||||||
return `${apiKey.host}${url}`
|
return `${apiKey.host}${url}`
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("URL fetching: ", import.meta.env.MODE === 'development' ? url
|
// console.log("URL fetching: ", import.meta.env.MODE === 'development' ? url
|
||||||
: `${window.location.protocol}//${(window.location.host + window.location.pathname + url).replace(/\/\//g, '/')}`)
|
// : `${window.location.protocol}//${(window.location.host + window.location.pathname + url).replace(/\/\//g, '/')}`)
|
||||||
return import.meta.env.MODE === 'development' ? url
|
return import.meta.env.MODE === 'development' ? url
|
||||||
: `${window.location.protocol}//${(window.location.host + window.location.pathname + url).replace(/\/\//g, '/')}`
|
: `${window.location.protocol}//${(window.location.host + window.location.pathname + url).replace(/\/\//g, '/')}`
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5 text-body">
|
<div class="mt-md-5 mt-3 text-body">
|
||||||
<RouterView v-slot="{ Component, route }">
|
<RouterView v-slot="{ Component, route }">
|
||||||
<Transition name="fade2" mode="out-in">
|
<Transition name="fade2" mode="out-in">
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
@ -60,7 +60,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5 text-body">
|
<div class="mt-md-5 mt-3 text-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h3 class="mb-3 text-body">Ping</h3>
|
<h3 class="mb-3 text-body">Ping</h3>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -39,8 +39,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5">
|
<div class="mt-md-5 mt-3">
|
||||||
<div class="container">
|
<div class="container-md">
|
||||||
<h3 class="mb-3 text-body">Settings</h3>
|
<h3 class="mb-3 text-body">Settings</h3>
|
||||||
<DashboardTheme></DashboardTheme>
|
<DashboardTheme></DashboardTheme>
|
||||||
<div class="card mb-4 shadow rounded-3">
|
<div class="card mb-4 shadow rounded-3">
|
||||||
|
@ -38,8 +38,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mt-5 text-body">
|
<div class="mt-md-5 mt-3 text-body">
|
||||||
<div class="container">
|
<div class="container-md">
|
||||||
<h3 class="mb-3 text-body">Traceroute</h3>
|
<h3 class="mb-3 text-body">Traceroute</h3>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4 d-flex gap-2 flex-column">
|
<div class="col-sm-4 d-flex gap-2 flex-column">
|
||||||
|
@ -5,11 +5,11 @@ ConditionPathIsDirectory=/etc/wireguard
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
PIDFile=/opt/wgdashboard/src/gunicorn.pid
|
PIDFile=<absolute_path_of_wgdashboard_src>/gunicorn.pid
|
||||||
WorkingDirectory=/opt/wgdashboard/src
|
WorkingDirectory=<absolute_path_of_wgdashboard_src>
|
||||||
ExecStart=/opt/wgdashboard/src/wgd.sh start
|
ExecStart=<absolute_path_of_wgdashboard_src>/wgd.sh start
|
||||||
ExecStop=/opt/wgdashboard/src/wgd.sh stop
|
ExecStop=<absolute_path_of_wgdashboard_src>/wgd.sh stop
|
||||||
ExecReload=/opt/wgdashboard/src/wgd.sh restart
|
ExecReload=<absolute_path_of_wgdashboard_src>/wgd.sh restart
|
||||||
TimeoutSec=120
|
TimeoutSec=120
|
||||||
PrivateTmp=yes
|
PrivateTmp=yes
|
||||||
Restart=always
|
Restart=always
|
||||||
|
@ -64,13 +64,13 @@ _determineOS(){
|
|||||||
_installPython(){
|
_installPython(){
|
||||||
case "$OS" in
|
case "$OS" in
|
||||||
ubuntu|debian)
|
ubuntu|debian)
|
||||||
{ sudo apt update ; sudo apt-get install -y python3; printf "\n\n"; } &>> ./log/install.txt
|
{ sudo apt update ; sudo apt-get install -y python3 net-tools; printf "\n\n"; } &>> ./log/install.txt
|
||||||
;;
|
;;
|
||||||
centos|fedora|redhat)
|
centos|fedora|redhat)
|
||||||
if command -v dnf &> /dev/null; then
|
if command -v dnf &> /dev/null; then
|
||||||
{ sudo dnf install -y python3; printf "\n\n"; } >> ./log/install.txt
|
{ sudo dnf install -y python3 net-tools; printf "\n\n"; } >> ./log/install.txt
|
||||||
else
|
else
|
||||||
{ sudo yum install -y python3; printf "\n\n"; } >> ./log/install.txt
|
{ sudo yum install -y python3 net-tools ; printf "\n\n"; } >> ./log/install.txt
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
# arch)
|
# arch)
|
||||||
@ -305,7 +305,6 @@ update_wgd() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if [ "$#" != 1 ];
|
if [ "$#" != 1 ];
|
||||||
then
|
then
|
||||||
help
|
help
|
||||||
|
Loading…
Reference in New Issue
Block a user