1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-06 07:50:13 +01:00

Working on some updates

This commit is contained in:
Donald Zou 2024-08-14 22:45:36 -04:00
parent fd0e519e41
commit 47efb644b7
17 changed files with 208 additions and 190 deletions

130
README.md
View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, '/')}`
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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