mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-10-03 15:56:17 +00:00
Compare commits
282 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
09cdcf8e53 | ||
|
a4d5b41ca7 | ||
|
9fa0d91d06 | ||
|
510f60bdeb | ||
|
8f0f4b168b | ||
|
cd11c4beb6 | ||
|
4d49cc413a | ||
|
3d50a58a31 | ||
|
d5701230fa | ||
|
ab945d6afe | ||
|
b4f8a36d43 | ||
|
608c1b4eb6 | ||
|
edf3c42157 | ||
|
c523cec113 | ||
|
6f8b987d42 | ||
|
d0d0642bdf | ||
|
924d760e3b | ||
|
f8c207ca2b | ||
|
ada1edd0b7 | ||
|
c79333db61 | ||
|
13778bed87 | ||
|
83b4d96f42 | ||
|
6cf96de0b4 | ||
|
481fadc7fc | ||
|
44f2c59e56 | ||
|
83589a912f | ||
|
fab9f03e7d | ||
|
928c83b13c | ||
|
72f20bc69b | ||
|
8293d5379d | ||
|
1d29445a8b | ||
|
5c308d757f | ||
|
5bf16004c9 | ||
|
417fa437b7 | ||
|
43f893c921 | ||
|
8ad9af4bc2 | ||
|
b3931bdc9d | ||
|
7ac153848b | ||
|
7689ebcac5 | ||
|
bf7adf9ca9 | ||
|
51ab8c556a | ||
|
149a8e910d | ||
|
310746b8cd | ||
|
6681303450 | ||
|
3228f37f09 | ||
|
421785bf6a | ||
|
308e8ca8c7 | ||
|
cb068ef70e | ||
|
acd3ec782f | ||
|
12d1e5b8d0 | ||
|
b165cdbd79 | ||
|
66f4507dee | ||
|
a724e1cb58 | ||
|
f942809de0 | ||
|
8043f77e02 | ||
|
1db9ba90d8 | ||
|
464fa59cb6 | ||
|
a8e2cbf55b | ||
|
fecd8dab38 | ||
|
13a833e3ed | ||
|
8d4784052a | ||
|
d9e9b41861 | ||
|
f0c3ef0aa1 | ||
|
3888831679 | ||
|
1a32fad324 | ||
|
d842ae9540 | ||
|
d0177b7504 | ||
|
e3842b25f3 | ||
|
a29b59c9cd | ||
|
f94eb97aa4 | ||
|
86017b79eb | ||
|
bc22fa5fad | ||
|
d6b70028ff | ||
|
0f7f9acd58 | ||
|
20633a6d1a | ||
|
a23856270d | ||
|
55543e370e | ||
|
8137a46c68 | ||
|
aeb9597c71 | ||
|
5067485e94 | ||
|
dfd456c7dc | ||
|
0ccb07e683 | ||
|
ca67a6897f | ||
|
0390227641 | ||
|
395b0982db | ||
|
f096ab4da7 | ||
|
d5ec9f7640 | ||
|
5732867407 | ||
|
31842f4c12 | ||
|
d5168d2da6 | ||
|
cac5ec836b | ||
|
ee9569e7d4 | ||
|
95df7de026 | ||
|
d3a5bd374d | ||
|
43ac3dddf1 | ||
|
1174328de3 | ||
|
dda54fb907 | ||
|
92ea808a5d | ||
|
2bc3a75c94 | ||
|
07ef97ce7c | ||
|
5fe3539331 | ||
|
4bc3bd5f13 | ||
|
4abce854d7 | ||
|
3b5c73992e | ||
|
c5abea2944 | ||
|
8e5cf14ebc | ||
|
7c8410ab86 | ||
|
369b4b92cc | ||
|
c50bb70383 | ||
|
d84b2060f0 | ||
|
afcf6024e6 | ||
|
3542bd6668 | ||
|
69b9116dd5 | ||
|
a2db4f06b1 | ||
|
b60b0fb511 | ||
|
0c1e9a6bb5 | ||
|
2692f92cb9 | ||
|
a43c8b4b00 | ||
|
6f15389411 | ||
|
f055241802 | ||
|
ac77c3a390 | ||
|
5cd99f2edc | ||
|
7c70fbec30 | ||
|
ac0dc3196f | ||
|
7f4da826b1 | ||
|
cc2af4371f | ||
|
2a79a03d38 | ||
|
47aac7fe33 | ||
|
d4055884b1 | ||
|
61658e847a | ||
|
bd714223ce | ||
|
060154cb89 | ||
|
99a1bfca9d | ||
|
4379f30628 | ||
|
b501244577 | ||
|
6f7b9815ca | ||
|
227bd088f7 | ||
|
b1d6ecb07c | ||
|
41772f28bd | ||
|
393dac1c99 | ||
|
db9d0be6c7 | ||
|
f0774ec273 | ||
|
d4a4d28b58 | ||
|
3ec97021bd | ||
|
56cf972373 | ||
|
2f3ae4c1af | ||
|
bc3dd04e12 | ||
|
4e8fc1b431 | ||
|
cd39aa2968 | ||
|
87ea3fc982 | ||
|
f74a511778 | ||
|
202461fe48 | ||
|
2af6687351 | ||
|
e603af5f24 | ||
|
84069ee882 | ||
|
edbb5cef92 | ||
|
a62c54b4ed | ||
|
41df7c04c3 | ||
|
9b783a8322 | ||
|
57db4df618 | ||
|
9d1081bd56 | ||
|
cc3773817b | ||
|
8956355e57 | ||
|
645db97c14 | ||
|
07a04dc507 | ||
|
a7317af413 | ||
|
ba6d6b8851 | ||
|
3726810108 | ||
|
4f92a7edf3 | ||
|
5d84b61f18 | ||
|
cd1329ec67 | ||
|
48a58b2b69 | ||
|
9b64aba8bf | ||
|
cae8264d98 | ||
|
95d8985336 | ||
|
b26ae90807 | ||
|
66d171c432 | ||
|
40463d9831 | ||
|
eb7dee013d | ||
|
1a878599b1 | ||
|
b9e25abdd9 | ||
|
c612022717 | ||
|
31e7f02b8d | ||
|
75747a2979 | ||
|
a85a8668a7 | ||
|
cca5fd859c | ||
|
2ed49abb1b | ||
|
409e6d49b2 | ||
|
93cfc482b8 | ||
|
85be6d53d0 | ||
|
bf6f58eb5e | ||
|
cd9d17ab18 | ||
|
e0bc6a10d0 | ||
|
ccfc1ad166 | ||
|
812060240f | ||
|
715a266ca4 | ||
|
fa4b3ece56 | ||
|
aac2a002bb | ||
|
8574acaf6e | ||
|
ddf4639354 | ||
|
9bd394f351 | ||
|
6899d48aae | ||
|
514e1ca8d0 | ||
|
eba5be010a | ||
|
f578d5c1c9 | ||
|
e58b1d670b | ||
|
c2642259b4 | ||
|
c47b0c9741 | ||
|
f425156cad | ||
|
7d7e31120e | ||
|
ccd247d154 | ||
|
53df6849f7 | ||
|
c2080bd1b3 | ||
|
9e93f8c2a5 | ||
|
907a142c8d | ||
|
d7bc8cd8e4 | ||
|
bb3e00a695 | ||
|
af5e7974c3 | ||
|
6a88959ec4 | ||
|
7b59149f90 | ||
|
3e01079caf | ||
|
d92e62e40b | ||
|
b4952dea7b | ||
|
00acb04329 | ||
|
939dd0591e | ||
|
febdb2a9e0 | ||
|
bcfd9fc1c9 | ||
|
e4964da5d4 | ||
|
a042298a4a | ||
|
908be168a9 | ||
|
d780bb3937 | ||
|
461e7e8913 | ||
|
819e8b73c3 | ||
|
627b7087a1 | ||
|
f23cf555e1 | ||
|
000978e4fb | ||
|
74782483bd | ||
|
c5f9387b92 | ||
|
57583b6747 | ||
|
434c236210 | ||
|
807bb97b6a | ||
|
da53bd44d1 | ||
|
3b01943649 | ||
|
3340f9c6ee | ||
|
b21cfe8504 | ||
|
97ab6ec299 | ||
|
7fda58e5c8 | ||
|
db6e820d1d | ||
|
8c2e1875ca | ||
|
bd95fe9af1 | ||
|
a517f89234 | ||
|
f994e7bfa8 | ||
|
28716924c9 | ||
|
b597f90f5b | ||
|
5912420467 | ||
|
90f35fd680 | ||
|
3e2d6e71b9 | ||
|
cbffdd829a | ||
|
d77e092948 | ||
|
1f5e10e784 | ||
|
68e3813c6c | ||
|
c9d78e3f67 | ||
|
b4f3fb3b30 | ||
|
bf7fb898f9 | ||
|
6c5e0543b4 | ||
|
578a1db62f | ||
|
6a4d16fae9 | ||
|
53b234252f | ||
|
b8b3992159 | ||
|
8214000713 | ||
|
94337a33d4 | ||
|
8ddee03338 | ||
|
8e2934533b | ||
|
71ee784003 | ||
|
597528e9b7 | ||
|
45fbbf9218 | ||
|
c7a4a01fee | ||
|
e1e147c8f0 | ||
|
b37d889de9 | ||
|
b61c9bfc5e | ||
|
e963788a81 | ||
|
3ef4798e09 |
50
.github/workflows/docker-analyze.yaml
vendored
50
.github/workflows/docker-analyze.yaml
vendored
@@ -1,50 +0,0 @@
|
||||
name: Docker-Analyze
|
||||
|
||||
on:
|
||||
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_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: Install Docker Scout
|
||||
run: |
|
||||
echo "Installing Docker Scout..."
|
||||
curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
|
||||
echo "Docker Scout installed successfully."
|
||||
- name: Analyze Docker image with Docker Scout
|
||||
id: analyze-image
|
||||
run: |
|
||||
echo "Analyzing Docker image with Docker Scout..."
|
||||
docker scout cves ${{ env.DOCKER_IMAGE }}:latest > scout-results.txt
|
||||
cat scout-results.txt
|
||||
echo "Docker Scout analysis completed."
|
||||
- name: Fail if critical CVEs are found
|
||||
run: |
|
||||
if grep -q "0C" scout-results.txt; then
|
||||
echo "No critical vulnerabilities found! Continueing."
|
||||
exit 0
|
||||
else
|
||||
echo "At least one critical vulnerabilities found! Exiting."
|
||||
exit 1
|
||||
fi
|
@@ -1,8 +1,10 @@
|
||||
name: Docker-Build
|
||||
name: Docker Scan and Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Daily at midnight UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
trigger-build:
|
||||
@@ -13,7 +15,7 @@ env:
|
||||
DOCKER_IMAGE: donaldzou/wgdashboard
|
||||
|
||||
jobs:
|
||||
docker_build:
|
||||
docker_build_analyze:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -21,17 +23,17 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||
|
||||
- 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
|
||||
|
||||
@@ -39,6 +41,16 @@ jobs:
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
push: true
|
||||
tags: ${{ env.DOCKER_IMAGE }}:latest
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7 #ARM v6 no longer support by go image.
|
||||
|
||||
- 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 }}
|
28
.github/workflows/qodana_code_quality.yml
vendored
Normal file
28
.github/workflows/qodana_code_quality.yml
vendored
Normal 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'
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -48,4 +48,5 @@ coverage
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
.vite/*
|
||||
.vite/*
|
||||
|
||||
|
61
README.md
61
README.md
@@ -1,9 +1,14 @@
|
||||
> [!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/app/public/img/logo.png" width="128">
|
||||
<img alt="WGDashboard" src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Logos/Logo-2-Rounded-512x512.png" width="128">
|
||||
</p>
|
||||
<h1 align="center">WGDashboard</h1>
|
||||
<p align="center">
|
||||
@@ -14,10 +19,18 @@
|
||||
<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"><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>
|
||||
@@ -30,17 +43,47 @@
|
||||
</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>
|
||||
<p align="center">
|
||||
Alternatively, you can also reach out at our Matrix.org Chatroom :)
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://app.element.io/#/room/#wgd:matrix.org">Matrix.org Chatroom</a>
|
||||
</p>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
> [!NOTE]
|
||||
> 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.
|
||||
# [Demo](https://wgd-demo.donaldzou.dev)
|
||||
If you would like to try out WGDashboard, feel free to access the link above. You won't be able to actually connect it with WireGuard since I blocked all Post/Pre script.
|
||||
|
||||
Username: `admin`
|
||||
|
||||
Password: `admin`
|
||||
|
||||
> **Please don't abuse server 🥺, and do not put any personal information on it.** If you can't access it, [please let me know here](https://github.com/donaldzou/WGDashboard/issues/695).
|
||||
|
||||
<hr>
|
||||
|
||||
# [Official Documentation](https://donaldzou.dev/WGDashboard-Documentations)
|
||||
|
||||
- [💡 Features](https://donaldzou.github.io/WGDashboard-Documentation/features.html)
|
||||
- [📝 Requirements](https://donaldzou.github.io/WGDashboard-Documentation/requirements.html)
|
||||
- [🛠 Install](https://donaldzou.github.io/WGDashboard-Documentation/install.html)
|
||||
- [🪜 Usage](https://donaldzou.github.io/WGDashboard-Documentation/usage.html)
|
||||
- [📖 API Documentation](https://donaldzou.github.io/WGDashboard-Documentation/api-documentation.html)
|
||||
- [🛠 Install](https://donaldzou.github.io/WGDashboard-Documentation/install.html)
|
||||
- [🐬 Docker Solutions](https://github.com/donaldzou/WGDashboard/tree/main/docker)
|
||||
- [🪜 Usage](https://donaldzou.github.io/WGDashboard-Documentation/usage.html)
|
||||
- [📖 API Documentation](https://donaldzou.github.io/WGDashboard-Documentation/api-documentation.html)
|
||||
- [And much more...](https://donaldzou.github.io/WGDashboard-Documentation/)
|
||||
|
||||
# Screenshots
|
||||
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/sign-in.png" alt=""/>
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/cross-server.png" alt=""/>
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/index.png" alt=""/>
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/new-configuration.png" alt="" />
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/settings.png" alt="" />
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/light-dark.png" alt="" />
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/configuration.png" alt=""/>
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/add-peers.png" alt="" />
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/ping.png" alt=""/>
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Documentation%20Images/traceroute.png" alt=""/>
|
@@ -1,6 +1,35 @@
|
||||
FROM golang:1.24 AS compiler
|
||||
WORKDIR /go
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git make bash build-essential \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-tools.git && \
|
||||
git clone --depth=1 https://github.com/amnezia-vpn/amneziawg-go.git
|
||||
RUN cd /go/amneziawg-tools/src && make
|
||||
|
||||
RUN cd /go/amneziawg-go && \
|
||||
go get -u ./... && \
|
||||
go mod tidy && \
|
||||
make && \
|
||||
chmod +x /go/amneziawg-go/amneziawg-go /go/amneziawg-tools/src/wg /go/amneziawg-tools/src/wg-quick/linux.bash
|
||||
RUN echo "DONE AmneziaWG"
|
||||
|
||||
### INTERMEDIATE STAGE
|
||||
FROM scratch AS bins
|
||||
COPY --from=compiler /go/amneziawg-go/amneziawg-go /amneziawg-go
|
||||
COPY --from=compiler /go/amneziawg-tools/src/wg /awg
|
||||
COPY --from=compiler /go/amneziawg-tools/src/wg-quick/linux.bash /awg-quick
|
||||
|
||||
# FINAL STAGE
|
||||
FROM alpine:latest
|
||||
LABEL maintainer="dselen@nerthus.nl"
|
||||
|
||||
COPY --from=bins /amneziawg-go /usr/bin/amneziawg-go
|
||||
COPY --from=bins /awg /usr/bin/awg
|
||||
COPY --from=bins /awg-quick /usr/bin/awg-quick
|
||||
|
||||
# Declaring environment variables, change Peernet to an address you like, standard is a 24 bit subnet.
|
||||
ARG wg_net="10.0.0.1"
|
||||
ARG wg_port="51820"
|
||||
@@ -9,7 +38,8 @@ ARG wg_port="51820"
|
||||
ENV TZ="Europe/Amsterdam"
|
||||
ENV global_dns="1.1.1.1"
|
||||
ENV isolate="none"
|
||||
ENV public_ip="0.0.0.0"
|
||||
ENV public_ip=""
|
||||
ENV wgd_port="10086"
|
||||
|
||||
# Doing package management operations, such as upgrading
|
||||
RUN apk update \
|
||||
@@ -19,14 +49,15 @@ RUN apk update \
|
||||
&& 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
|
||||
ENV WGDASH=/opt/wgdashboard
|
||||
|
||||
# Removing the Linux Image package to preserve space on the image, for this reason also deleting apt lists, to be able to install packages: run apt update.
|
||||
|
||||
# Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example.
|
||||
RUN mkdir /data \
|
||||
&& mkdir /configs \
|
||||
&& mkdir -p ${WGDASH}/src
|
||||
&& mkdir -p ${WGDASH}/src \
|
||||
&& mkdir -p /etc/amnezia/amneziawg
|
||||
COPY ./src ${WGDASH}/src
|
||||
|
||||
# Generate basic WireGuard interface. Echoing the WireGuard interface config for readability, adjust if you want it for efficiency.
|
||||
@@ -50,9 +81,10 @@ 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
|
||||
COPY ./docker/entrypoint.sh /entrypoint.sh
|
||||
|
||||
# Exposing the default WireGuard Dashboard port for web access.
|
||||
EXPOSE 10086
|
||||
WORKDIR $WGDASH
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
@@ -9,7 +9,7 @@ For more details on the source-code specific to this Docker image, refer to the
|
||||
|
||||
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" />
|
||||
<img src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Logos/Logo-2-Rounded-512x512.png" alt="WG-Dashboard Logo" title="WG-Dashboard Logo" width="150" height="150" />
|
||||
|
||||
## Getting the container running:
|
||||
|
||||
|
@@ -8,6 +8,7 @@ services:
|
||||
#- global_dns= # <--- Set global DNS address, default: 1.1.1.1.
|
||||
#- isolate= # <--- Set the interfaces that will disallow peer communication, default: 'none'.
|
||||
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
|
||||
#- wgd_port= # <--- Set the port WGDashboard will use for its web-server.
|
||||
ports:
|
||||
- 10086:10086/tcp
|
||||
- 51820:51820/udp
|
||||
|
@@ -3,6 +3,14 @@
|
||||
# Path to the configuration file (exists because of previous function).
|
||||
config_file="/data/wg-dashboard.ini"
|
||||
|
||||
trap 'stop_service' SIGTERM
|
||||
|
||||
stop_service() {
|
||||
echo "[WGDashboard] Stopping WGDashboard..."
|
||||
bash ./wgd.sh stop
|
||||
exit 0
|
||||
}
|
||||
|
||||
echo "------------------------- START ----------------------------"
|
||||
echo "Starting the WireGuard Dashboard Docker container."
|
||||
|
||||
@@ -10,6 +18,12 @@ ensure_installation() {
|
||||
# When using a custom directory to store the files, this part moves over and makes sure the installation continues.
|
||||
echo "Quick-installing..."
|
||||
|
||||
chmod +x "${WGDASH}"/src/wgd.sh
|
||||
cd "${WGDASH}"/src || exit
|
||||
|
||||
echo "Removing clear command from wgd.sh for better Docker logging."
|
||||
sed -i '/clear/d' ./wgd.sh
|
||||
|
||||
if [ ! -d "/data/db" ]; then
|
||||
echo "Creating database dir"
|
||||
mkdir /data/db
|
||||
@@ -18,7 +32,7 @@ ensure_installation() {
|
||||
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}"
|
||||
@@ -33,13 +47,10 @@ ensure_installation() {
|
||||
|
||||
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."
|
||||
@@ -69,13 +80,14 @@ set_envvars() {
|
||||
# Check if the file is empty
|
||||
if [ ! -s "${config_file}" ]; then
|
||||
echo "Config file is empty. Creating [Peers] section."
|
||||
|
||||
|
||||
# Create [Peers] section with initial values
|
||||
{
|
||||
echo "[Peers]"
|
||||
echo "peer_global_dns = ${global_dns}"
|
||||
echo "remote_endpoint = ${public_ip}"
|
||||
#echo -e "\n[Server]"
|
||||
echo -e "\n[Server]"
|
||||
echo "app_port = ${wgd_port}"
|
||||
} > "${config_file}"
|
||||
|
||||
else
|
||||
@@ -87,24 +99,32 @@ set_envvars() {
|
||||
# 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."
|
||||
|
||||
echo "DNS is set correctly, moving on."
|
||||
|
||||
else
|
||||
echo "Changing default DNS..."
|
||||
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" "${config_file}"
|
||||
fi
|
||||
|
||||
if [ "${public_ip}" == "0.0.0.0" ]; then
|
||||
|
||||
current_public_ip=$(grep "remote_endpoint = " "${config_file}" | awk '{print $NF}')
|
||||
if [ "${public_ip}" == "" ]; then
|
||||
default_ip=$(curl -s ifconfig.me)
|
||||
|
||||
echo "Trying to fetch the Public-IP using ifconfig.me: ${default_ip}"
|
||||
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${default_ip}/" "${config_file}"
|
||||
|
||||
elif [ "${current_public_ip}" != "${public_ip}" ]; then
|
||||
sed -i "s/^remote_endpoint = .*/remote_endpoint = ${public_ip}/" "${config_file}"
|
||||
else
|
||||
echo "Public-IP is correct, moving on."
|
||||
fi
|
||||
|
||||
current_wgd_port=$(grep "app_port = " "${config_file}" | awk '{print $NF}')
|
||||
if [ "${current_wgd_port}" == "${wgd_port}" ]; then
|
||||
echo "Current WGD port is set correctly, moving on."
|
||||
else
|
||||
echo "Changing default WGD port..."
|
||||
sed -i "s/^app_port = .*/app_port = ${wgd_port}/" "${config_file}"
|
||||
fi
|
||||
}
|
||||
|
||||
# === CORE SERVICES ===
|
||||
@@ -112,99 +132,7 @@ 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
|
||||
|
||||
bash ./wgd.sh start
|
||||
}
|
||||
|
||||
ensure_blocking() {
|
||||
@@ -212,24 +140,21 @@ ensure_blocking() {
|
||||
echo -e "\nEnsuring container continuation."
|
||||
|
||||
# Find and tail the latest error and access logs if they exist
|
||||
local logdir="/opt/wireguarddashboard/src/log"
|
||||
|
||||
local logdir="${WGDASH}/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"
|
||||
if [ -n "$latestErrLog" ]; then
|
||||
tail -f "$latestErrLog" &
|
||||
wait $!
|
||||
else
|
||||
echo "No log files found to tail."
|
||||
echo "No log files found to tail. Something went wrong, exiting..."
|
||||
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
|
||||
ensure_blocking
|
2031
package-lock.json
generated
2031
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"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"
|
||||
"marked": "^15.0.7",
|
||||
"openai": "^4.89.0",
|
||||
"pinia-plugin-persistedstate": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
6
qodana.yaml
Normal file
6
qodana.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
version: "1.0"
|
||||
linter: jetbrains/qodana-python:2024.3
|
||||
profile:
|
||||
name: qodana.recommended
|
||||
include:
|
||||
- name: CheckDependencyLicenses
|
76
src/Utilities.py
Normal file
76
src/Utilities.py
Normal file
@@ -0,0 +1,76 @@
|
||||
import re, ipaddress
|
||||
import subprocess
|
||||
|
||||
|
||||
def RegexMatch(regex, text) -> bool:
|
||||
"""
|
||||
Regex Match
|
||||
@param regex: Regex patter
|
||||
@param text: Text to match
|
||||
@return: Boolean indicate if the text match the regex pattern
|
||||
"""
|
||||
pattern = re.compile(regex)
|
||||
return pattern.search(text) is not None
|
||||
|
||||
def GetRemoteEndpoint() -> str:
|
||||
"""
|
||||
Using socket to determine default interface IP address. Thanks, @NOXICS
|
||||
@return:
|
||||
"""
|
||||
import socket
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||
s.connect(("1.1.1.1", 80)) # Connecting to a public IP
|
||||
wgd_remote_endpoint = s.getsockname()[0]
|
||||
return str(wgd_remote_endpoint)
|
||||
|
||||
|
||||
def StringToBoolean(value: str):
|
||||
"""
|
||||
Convert string boolean to boolean
|
||||
@param value: Boolean value in string came from Configuration file
|
||||
@return: Boolean value
|
||||
"""
|
||||
return (value.strip().replace(" ", "").lower() in
|
||||
("yes", "true", "t", "1", 1))
|
||||
|
||||
def ValidateIPAddressesWithRange(ips: str) -> bool:
|
||||
s = ips.replace(" ", "").split(",")
|
||||
for ip in s:
|
||||
try:
|
||||
ipaddress.ip_network(ip)
|
||||
except ValueError as e:
|
||||
return False
|
||||
return True
|
||||
|
||||
def ValidateIPAddresses(ips) -> bool:
|
||||
s = ips.replace(" ", "").split(",")
|
||||
for ip in s:
|
||||
try:
|
||||
ipaddress.ip_address(ip)
|
||||
except ValueError as e:
|
||||
return False
|
||||
return True
|
||||
|
||||
def ValidateDNSAddress(addresses) -> tuple[bool, str]:
|
||||
s = addresses.replace(" ", "").split(",")
|
||||
for address in s:
|
||||
if not ValidateIPAddresses(address) and not RegexMatch(
|
||||
r"(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]", address):
|
||||
return False, f"{address} does not appear to be an valid DNS address"
|
||||
return True, ""
|
||||
|
||||
def GenerateWireguardPublicKey(privateKey: str) -> tuple[bool, str] | tuple[bool, None]:
|
||||
try:
|
||||
publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
return True, publicKey.decode().strip('\n')
|
||||
except subprocess.CalledProcessError:
|
||||
return False, None
|
||||
|
||||
def GenerateWireguardPrivateKey() -> tuple[bool, str] | tuple[bool, None]:
|
||||
try:
|
||||
publicKey = subprocess.check_output(f"wg genkey", shell=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
return True, publicKey.decode().strip('\n')
|
||||
except subprocess.CalledProcessError:
|
||||
return False, None
|
1878
src/dashboard.py
1878
src/dashboard.py
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,13 @@
|
||||
import dashboard
|
||||
import os.path
|
||||
import dashboard, configparser
|
||||
from datetime import datetime
|
||||
|
||||
global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger
|
||||
app_host, app_port = dashboard.gunicornConfig()
|
||||
date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
|
||||
|
||||
|
||||
def post_worker_init(worker):
|
||||
dashboard.startThreads()
|
||||
|
||||
|
||||
worker_class = 'gthread'
|
||||
workers = 1
|
||||
threads = 1
|
||||
@@ -21,6 +19,8 @@ accesslog = f"./log/access_{date}.log"
|
||||
log_level = "debug"
|
||||
capture_output = True
|
||||
errorlog = f"./log/error_{date}.log"
|
||||
print(f"[WGDashboard] WGDashboard w/ Gunicorn will be running on {bind}", flush=True)
|
||||
print(f"[WGDashboard] Access log file is at {accesslog}", flush=True)
|
||||
print(f"[WGDashboard] Error log file is at {errorlog}", flush=True)
|
||||
pythonpath = "., ./modules"
|
||||
|
||||
print(f"[Gunicorn] WGDashboard w/ Gunicorn will be running on {bind}", flush=True)
|
||||
print(f"[Gunicorn] Access log file is at {accesslog}", flush=True)
|
||||
print(f"[Gunicorn] Error log file is at {errorlog}", flush=True)
|
||||
|
35
src/modules/DashboardLogger.py
Normal file
35
src/modules/DashboardLogger.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Dashboard Logger Class
|
||||
"""
|
||||
import sqlite3, os, uuid
|
||||
|
||||
class DashboardLogger:
|
||||
def __init__(self, CONFIGURATION_PATH):
|
||||
self.loggerdb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard_log.db'),
|
||||
isolation_level=None,
|
||||
check_same_thread=False)
|
||||
self.loggerdb.row_factory = sqlite3.Row
|
||||
self.__createLogDatabase()
|
||||
self.log(Message="WGDashboard started")
|
||||
def __createLogDatabase(self):
|
||||
with self.loggerdb:
|
||||
loggerdbCursor = self.loggerdb.cursor()
|
||||
existingTable = loggerdbCursor.execute("SELECT name from sqlite_master where type='table'").fetchall()
|
||||
existingTable = [t['name'] for t in existingTable]
|
||||
if "DashboardLog" not in existingTable:
|
||||
loggerdbCursor.execute(
|
||||
"CREATE TABLE DashboardLog (LogID VARCHAR NOT NULL, LogDate DATETIME DEFAULT (strftime('%Y-%m-%d %H:%M:%S','now', 'localtime')), URL VARCHAR, IP VARCHAR, Status VARCHAR, Message VARCHAR, PRIMARY KEY (LogID))")
|
||||
if self.loggerdb.in_transaction:
|
||||
self.loggerdb.commit()
|
||||
|
||||
def log(self, URL: str = "", IP: str = "", Status: str = "true", Message: str = "") -> bool:
|
||||
try:
|
||||
loggerdbCursor = self.loggerdb.cursor()
|
||||
loggerdbCursor.execute(
|
||||
"INSERT INTO DashboardLog (LogID, URL, IP, Status, Message) VALUES (?, ?, ?, ?, ?);", (str(uuid.uuid4()), URL, IP, Status, Message,))
|
||||
loggerdbCursor.close()
|
||||
self.loggerdb.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[WGDashboard] Access Log Error: {str(e)}")
|
||||
return False
|
69
src/modules/Email.py
Normal file
69
src/modules/Email.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import os.path
|
||||
import smtplib
|
||||
from email import encoders
|
||||
from email.header import Header
|
||||
from email.mime.base import MIMEBase
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import formataddr
|
||||
|
||||
class EmailSender:
|
||||
def __init__(self, DashboardConfig):
|
||||
self.smtp = None
|
||||
self.DashboardConfig = DashboardConfig
|
||||
if not os.path.exists('./attachments'):
|
||||
os.mkdir('./attachments')
|
||||
|
||||
def Server(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "server")[1]
|
||||
|
||||
def Port(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "port")[1]
|
||||
|
||||
def Encryption(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "encryption")[1]
|
||||
|
||||
def Username(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "username")[1]
|
||||
|
||||
def Password(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "email_password")[1]
|
||||
|
||||
def SendFrom(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "send_from")[1]
|
||||
|
||||
def ready(self):
|
||||
return len(self.Server()) > 0 and len(self.Port()) > 0 and len(self.Encryption()) > 0 and len(self.Username()) > 0 and len(self.Password()) > 0 and len(self.SendFrom())
|
||||
|
||||
def send(self, receiver, subject, body, includeAttachment = False, attachmentName = ""):
|
||||
if self.ready():
|
||||
try:
|
||||
self.smtp = smtplib.SMTP(self.Server(), port=int(self.Port()))
|
||||
self.smtp.ehlo()
|
||||
if self.Encryption() == "STARTTLS":
|
||||
self.smtp.starttls()
|
||||
self.smtp.login(self.Username(), self.Password())
|
||||
message = MIMEMultipart()
|
||||
message['Subject'] = subject
|
||||
message['From'] = self.SendFrom()
|
||||
message["To"] = receiver
|
||||
message.attach(MIMEText(body, "plain"))
|
||||
|
||||
if includeAttachment and len(attachmentName) > 0:
|
||||
attachmentPath = os.path.join('./attachments', attachmentName)
|
||||
if os.path.exists(attachmentPath):
|
||||
attachment = MIMEBase("application", "octet-stream")
|
||||
with open(os.path.join('./attachments', attachmentName), 'rb') as f:
|
||||
attachment.set_payload(f.read())
|
||||
encoders.encode_base64(attachment)
|
||||
attachment.add_header("Content-Disposition", f"attachment; filename= {attachmentName}",)
|
||||
message.attach(attachment)
|
||||
else:
|
||||
self.smtp.close()
|
||||
return False, "Attachment does not exist"
|
||||
self.smtp.sendmail(self.SendFrom(), receiver, message.as_string())
|
||||
self.smtp.close()
|
||||
return True, None
|
||||
except Exception as e:
|
||||
return False, f"Send failed | Reason: {e}"
|
||||
return False, "SMTP not configured"
|
22
src/modules/Log.py
Normal file
22
src/modules/Log.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Log Class
|
||||
"""
|
||||
class Log:
|
||||
def __init__(self, LogID: str, JobID: str, LogDate: str, Status: str, Message: str):
|
||||
self.LogID = LogID
|
||||
self.JobID = JobID
|
||||
self.LogDate = LogDate
|
||||
self.Status = Status
|
||||
self.Message = Message
|
||||
|
||||
def toJson(self):
|
||||
return {
|
||||
"LogID": self.LogID,
|
||||
"JobID": self.JobID,
|
||||
"LogDate": self.LogDate,
|
||||
"Status": self.Status,
|
||||
"Message": self.Message
|
||||
}
|
||||
|
||||
def __dict__(self):
|
||||
return self.toJson()
|
32
src/modules/PeerJob.py
Normal file
32
src/modules/PeerJob.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
Peer Job
|
||||
"""
|
||||
from datetime import datetime
|
||||
class PeerJob:
|
||||
def __init__(self, JobID: str, Configuration: str, Peer: str,
|
||||
Field: str, Operator: str, Value: str, CreationDate: datetime, ExpireDate: datetime, Action: str):
|
||||
self.Action = Action
|
||||
self.ExpireDate = ExpireDate
|
||||
self.CreationDate = CreationDate
|
||||
self.Value = Value
|
||||
self.Operator = Operator
|
||||
self.Field = Field
|
||||
self.Configuration = Configuration
|
||||
self.Peer = Peer
|
||||
self.JobID = JobID
|
||||
|
||||
def toJson(self):
|
||||
return {
|
||||
"JobID": self.JobID,
|
||||
"Configuration": self.Configuration,
|
||||
"Peer": self.Peer,
|
||||
"Field": self.Field,
|
||||
"Operator": self.Operator,
|
||||
"Value": self.Value,
|
||||
"CreationDate": self.CreationDate,
|
||||
"ExpireDate": self.ExpireDate,
|
||||
"Action": self.Action
|
||||
}
|
||||
|
||||
def __dict__(self):
|
||||
return self.toJson()
|
53
src/modules/PeerJobLogger.py
Normal file
53
src/modules/PeerJobLogger.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""
|
||||
Peer Job Logger
|
||||
"""
|
||||
import sqlite3, os, uuid
|
||||
from .Log import Log
|
||||
|
||||
class PeerJobLogger:
|
||||
def __init__(self, CONFIGURATION_PATH, AllPeerJobs):
|
||||
self.loggerdb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard_log.db'),
|
||||
check_same_thread=False)
|
||||
self.loggerdb.row_factory = sqlite3.Row
|
||||
self.logs: list[Log] = []
|
||||
self.__createLogDatabase()
|
||||
self.AllPeerJobs = AllPeerJobs
|
||||
def __createLogDatabase(self):
|
||||
with self.loggerdb:
|
||||
loggerdbCursor = self.loggerdb.cursor()
|
||||
|
||||
existingTable = loggerdbCursor.execute("SELECT name from sqlite_master where type='table'").fetchall()
|
||||
existingTable = [t['name'] for t in existingTable]
|
||||
|
||||
if "JobLog" not in existingTable:
|
||||
loggerdbCursor.execute("CREATE TABLE JobLog (LogID VARCHAR NOT NULL, JobID NOT NULL, LogDate DATETIME DEFAULT (strftime('%Y-%m-%d %H:%M:%S','now', 'localtime')), Status VARCHAR NOT NULL, Message VARCHAR, PRIMARY KEY (LogID))")
|
||||
if self.loggerdb.in_transaction:
|
||||
self.loggerdb.commit()
|
||||
def log(self, JobID: str, Status: bool = True, Message: str = "") -> bool:
|
||||
try:
|
||||
with self.loggerdb:
|
||||
loggerdbCursor = self.loggerdb.cursor()
|
||||
loggerdbCursor.execute(f"INSERT INTO JobLog (LogID, JobID, Status, Message) VALUES (?, ?, ?, ?)",
|
||||
(str(uuid.uuid4()), JobID, Status, Message,))
|
||||
if self.loggerdb.in_transaction:
|
||||
self.loggerdb.commit()
|
||||
except Exception as e:
|
||||
print(f"[WGDashboard] Peer Job Log Error: {str(e)}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def getLogs(self, all: bool = False, configName = None) -> list[Log]:
|
||||
logs: list[Log] = []
|
||||
try:
|
||||
allJobs = self.AllPeerJobs.getAllJobs(configName)
|
||||
allJobsID = ", ".join([f"'{x.JobID}'" for x in allJobs])
|
||||
with self.loggerdb:
|
||||
loggerdbCursor = self.loggerdb.cursor()
|
||||
table = loggerdbCursor.execute(f"SELECT * FROM JobLog WHERE JobID IN ({allJobsID}) ORDER BY LogDate DESC").fetchall()
|
||||
self.logs.clear()
|
||||
for l in table:
|
||||
logs.append(
|
||||
Log(l["LogID"], l["JobID"], l["LogDate"], l["Status"], l["Message"]))
|
||||
except Exception as e:
|
||||
return logs
|
||||
return logs
|
135
src/modules/SystemStatus.py
Normal file
135
src/modules/SystemStatus.py
Normal file
@@ -0,0 +1,135 @@
|
||||
import psutil
|
||||
class SystemStatus:
|
||||
def __init__(self):
|
||||
self.CPU = CPU()
|
||||
self.MemoryVirtual = Memory('virtual')
|
||||
self.MemorySwap = Memory('swap')
|
||||
self.Disks = Disks()
|
||||
self.NetworkInterfaces = NetworkInterfaces()
|
||||
self.Processes = Processes()
|
||||
def toJson(self):
|
||||
return {
|
||||
"CPU": self.CPU,
|
||||
"Memory": {
|
||||
"VirtualMemory": self.MemoryVirtual,
|
||||
"SwapMemory": self.MemorySwap
|
||||
},
|
||||
"Disks": self.Disks,
|
||||
"NetworkInterfaces": self.NetworkInterfaces,
|
||||
"Processes": self.Processes
|
||||
}
|
||||
|
||||
|
||||
class CPU:
|
||||
def __init__(self):
|
||||
self.cpu_percent: float = 0
|
||||
self.cpu_percent_per_cpu: list[float] = []
|
||||
def getData(self):
|
||||
try:
|
||||
self.cpu_percent_per_cpu = psutil.cpu_percent(interval=0.5, percpu=True)
|
||||
self.cpu_percent = psutil.cpu_percent(interval=0.5)
|
||||
except Exception as e:
|
||||
pass
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return self.__dict__
|
||||
|
||||
class Memory:
|
||||
def __init__(self, memoryType: str):
|
||||
self.__memoryType__ = memoryType
|
||||
self.total = 0
|
||||
self.available = 0
|
||||
self.percent = 0
|
||||
def getData(self):
|
||||
try:
|
||||
if self.__memoryType__ == "virtual":
|
||||
memory = psutil.virtual_memory()
|
||||
else:
|
||||
memory = psutil.swap_memory()
|
||||
self.total = memory.total
|
||||
self.available = memory.available
|
||||
self.percent = memory.percent
|
||||
except Exception as e:
|
||||
pass
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return self.__dict__
|
||||
|
||||
class Disks:
|
||||
def __init__(self):
|
||||
self.disks : list[Disk] = []
|
||||
def getData(self):
|
||||
try:
|
||||
self.disks = list(map(lambda x : Disk(x.mountpoint), psutil.disk_partitions()))
|
||||
except Exception as e:
|
||||
pass
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return self.disks
|
||||
|
||||
class Disk:
|
||||
def __init__(self, mountPoint: str):
|
||||
self.total = 0
|
||||
self.used = 0
|
||||
self.free = 0
|
||||
self.percent = 0
|
||||
self.mountPoint = mountPoint
|
||||
def getData(self):
|
||||
try:
|
||||
disk = psutil.disk_usage(self.mountPoint)
|
||||
self.total = disk.total
|
||||
self.free = disk.free
|
||||
self.used = disk.used
|
||||
self.percent = disk.percent
|
||||
except Exception as e:
|
||||
pass
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return self.__dict__
|
||||
|
||||
class NetworkInterfaces:
|
||||
def __init__(self):
|
||||
self.interfaces = {}
|
||||
def getData(self):
|
||||
try:
|
||||
network = psutil.net_io_counters(pernic=True, nowrap=True)
|
||||
for i in network.keys():
|
||||
self.interfaces[i] = network[i]._asdict()
|
||||
except Exception as e:
|
||||
pass
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return self.interfaces
|
||||
|
||||
class Process:
|
||||
def __init__(self, name, command, pid, percent):
|
||||
self.name = name
|
||||
self.command = command
|
||||
self.pid = pid
|
||||
self.percent = percent
|
||||
def toJson(self):
|
||||
return self.__dict__
|
||||
|
||||
class Processes:
|
||||
def __init__(self):
|
||||
self.CPU_Top_10_Processes: list[Process] = []
|
||||
self.Memory_Top_10_Processes: list[Process] = []
|
||||
def getData(self):
|
||||
while True:
|
||||
try:
|
||||
processes = list(psutil.process_iter())
|
||||
self.CPU_Top_10_Processes = sorted(
|
||||
list(map(lambda x : Process(x.name(), " ".join(x.cmdline()), x.pid, x.cpu_percent()), processes)),
|
||||
key=lambda x : x.percent, reverse=True)[:20]
|
||||
self.Memory_Top_10_Processes = sorted(
|
||||
list(map(lambda x : Process(x.name(), " ".join(x.cmdline()), x.pid, x.memory_percent()), processes)),
|
||||
key=lambda x : x.percent, reverse=True)[:20]
|
||||
break
|
||||
except Exception as e:
|
||||
break
|
||||
def toJson(self):
|
||||
self.getData()
|
||||
return {
|
||||
"cpu_top_10": self.CPU_Top_10_Processes,
|
||||
"memory_top_10": self.Memory_Top_10_Processes
|
||||
}
|
@@ -6,4 +6,5 @@ Flask
|
||||
flask-cors
|
||||
icmplib
|
||||
gunicorn
|
||||
requests
|
||||
requests
|
||||
tcconfig
|
@@ -1 +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-Nht8Bi7_.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};
|
||||
import{_ as r,c as i,d as o,w as e,k as l,a as t,j as _,i as a,l as d,S as u}from"./index-eyzMkuUX.js";const m={name:"configuration"},p={class:"mt-md-5 mt-3 text-body"};function f(k,x,h,w,$,v){const n=l("RouterView");return t(),i("div",p,[o(n,null,{default:e(({Component:s,route:c})=>[o(_,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(d(s),{key:c.path}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",f]]);export{B as default};
|
@@ -1 +0,0 @@
|
||||
.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
1
src/static/app/dist/assets/configurationList-BY8izVeQ.css
vendored
Normal file
1
src/static/app/dist/assets/configurationList-BY8izVeQ.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.fade-enter-active[data-v-dafd6275]{transition-delay:var(--7d032b58)!important}.progress-bar[data-v-c20f1a80]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.filter a[data-v-ea61b607]{text-decoration:none}
|
1
src/static/app/dist/assets/configurationList-C-awZMSQ.js
vendored
Normal file
1
src/static/app/dist/assets/configurationList-C-awZMSQ.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.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
1
src/static/app/dist/assets/dayjs.min-DZKHFKQc.js
vendored
Normal file
1
src/static/app/dist/assets/dayjs.min-DZKHFKQc.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
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-Nht8Bi7_.js";import{L as s}from"./localeText-ClObbhxX.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
1
src/static/app/dist/assets/editConfiguration-Ca_IlmFH.css
vendored
Normal file
1
src/static/app/dist/assets/editConfiguration-Ca_IlmFH.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
@media screen and (max-width: 567px){.inputGroup{&[data-v-4be4f48a]{flex-direction:column}h3[data-v-4be4f48a]{transform:rotate(90deg)}}}
|
7
src/static/app/dist/assets/editConfiguration-RKuncHfe.js
vendored
Normal file
7
src/static/app/dist/assets/editConfiguration-RKuncHfe.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/index-24JS7yYN.css
vendored
Normal file
1
src/static/app/dist/assets/index-24JS7yYN.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.agentMessage[data-v-8635cf47]{white-space:break-spaces;max-width:80%;display:flex;flex-direction:column;word-wrap:break-word}.text-bg-secondary[data-v-8635cf47]{background-color:RGBA(var(--bs-secondary-rgb),.7)!important}.text-bg-primary[data-v-8635cf47]{background-color:RGBA(var(--bs-primary-rgb),.7)!important}.agentContainer[data-v-694cfad1]{--agentHeight: 100vh;position:absolute;z-index:9999;top:0;left:100%;width:450px;box-shadow:0 10px 30px #0000004d;backdrop-filter:blur(8px);background:linear-gradient(var(--degree),#009dff52 var(--distance2),#ff4a0052 100%)}.agentContainer.enabled[data-v-694cfad1]{height:calc(var(--agentHeight) - 1rem)}@media screen and (max-width: 768px){.agentContainer[data-v-694cfad1]{--agentHeight: 100vh !important;top:0;left:0;max-height:calc(var(--agentHeight) - 58px - 1rem);width:calc(100% - 1rem)}}.agentChatroomBody[data-v-694cfad1]{flex:1 1 auto;overflow-y:auto;max-height:calc(var(--agentHeight) - 70px - 244px)}@media screen and (max-width: 768px){.navbar-container[data-v-58e71749]{position:absolute!important;z-index:1000;animation-duration:.4s;animation-fill-mode:both;display:none;animation-timing-function:cubic-bezier(.82,.58,.17,.9)}.navbar-container.active[data-v-58e71749]{animation-direction:normal;display:block!important;animation-name:zoomInFade-58e71749}}.navbar-container[data-v-58e71749]{height:100vh;position:relative}@supports (height: 100dvh){@media screen and (max-width: 768px){.navbar-container[data-v-58e71749]{height:calc(100dvh - 58px)}}}@keyframes zoomInFade-58e71749{0%{opacity:0;transform:translateY(60px);filter:blur(3px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}.slideIn-enter-active[data-v-58e71749],.slideIn-leave-active[data-v-58e71749]{transition:all .3s cubic-bezier(.82,.58,.17,1)}.slideIn-enter-from[data-v-58e71749],.slideIn-leave-to[data-v-58e71749]{transform:translateY(30px);filter:blur(3px);opacity:0}main[data-v-0c6a5068]{height:100vh}@supports (height: 100dvh){@media screen and (max-width: 768px){main[data-v-0c6a5068]{height:calc(100dvh - 58px)}}}
|
@@ -1 +0,0 @@
|
||||
@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
1
src/static/app/dist/assets/index-DriC7tFa.js
vendored
1
src/static/app/dist/assets/index-DriC7tFa.js
vendored
File diff suppressed because one or more lines are too long
44
src/static/app/dist/assets/index-Nht8Bi7_.js
vendored
44
src/static/app/dist/assets/index-Nht8Bi7_.js
vendored
File diff suppressed because one or more lines are too long
44
src/static/app/dist/assets/index-eyzMkuUX.js
vendored
Normal file
44
src/static/app/dist/assets/index-eyzMkuUX.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
src/static/app/dist/assets/index-hY99QVLy.js
vendored
Normal file
18
src/static/app/dist/assets/index-hY99QVLy.js
vendored
Normal file
File diff suppressed because one or more lines are too long
56
src/static/app/dist/assets/index-uCjEPRch.js
vendored
Normal file
56
src/static/app/dist/assets/index-uCjEPRch.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/localeText-CJmA8xz4.js
vendored
Normal file
1
src/static/app/dist/assets/localeText-CJmA8xz4.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{_ as e,G as t,a as o,c as a,t as c}from"./index-eyzMkuUX.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return o(),a("span",null,c(this.getLocaleText),1)}const u=e(s,[["render",n]]);export{u as L};
|
@@ -1 +0,0 @@
|
||||
import{_ as t,G as e,t as o}from"./index-Nht8Bi7_.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};
|
BIN
src/static/app/dist/assets/logo-XE_HdY0J.png
vendored
BIN
src/static/app/dist/assets/logo-XE_HdY0J.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
1
src/static/app/dist/assets/message-B2U3Wkg4.js
vendored
Normal file
1
src/static/app/dist/assets/message-B2U3Wkg4.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{L as l}from"./localeText-CJmA8xz4.js";import{d as c}from"./dayjs.min-DZKHFKQc.js";import{_ as h,a as o,c as a,b as e,d as i,w as u,f as p,t as n,j as g,n as f,k as _}from"./index-eyzMkuUX.js";const x={name:"message",methods:{dayjs:c,hide(){this.ct(),this.message.show=!1},show(){this.timeout=setTimeout(()=>{this.message.show=!1},5e3)},ct(){clearTimeout(this.timeout)}},components:{LocaleText:l},props:{message:Object},mounted(){this.show()},data(){return{dismiss:!1,timeout:null}}},v=["id"],b={key:0,class:"d-flex"},w={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},y={class:"ms-auto"},k={key:1},T={class:"card-body d-flex align-items-center gap-3"};function M(j,s,C,L,t,m){const d=_("LocaleText");return o(),a("div",{onMouseenter:s[1]||(s[1]=r=>{t.dismiss=!0,this.ct()}),onMouseleave:s[2]||(s[2]=r=>{t.dismiss=!1,this.show()}),class:"card shadow rounded-3 position-relative message ms-auto",id:this.message.id},[e("div",{class:f([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[i(g,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(o(),a("div",k,[e("small",{onClick:s[0]||(s[0]=r=>m.hide()),class:"d-block mx-auto w-100 text-center",style:{cursor:"pointer"}},[s[3]||(s[3]=e("i",{class:"bi bi-x-lg me-2"},null,-1)),i(d,{t:"Dismiss"})])])):(o(),a("div",b,[e("small",w,[i(d,{t:"FROM "}),p(" "+n(this.message.from),1)]),e("small",y,n(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,n(this.message.content),1)])],40,v)}const z=h(x,[["render",M],["__scopeId","data-v-94c76b54"]]);export{z as M};
|
@@ -1 +0,0 @@
|
||||
import{L as c}from"./localeText-ClObbhxX.js";import{d as n}from"./dayjs.min-DENWFVBv.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-Nht8Bi7_.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};
|
1
src/static/app/dist/assets/message-BaDb-qC9.css
vendored
Normal file
1
src/static/app/dist/assets/message-BaDb-qC9.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.message[data-v-94c76b54]{width:100%}@media screen and (min-width: 576px){.message[data-v-94c76b54]{width:400px}}
|
@@ -1 +0,0 @@
|
||||
.message[data-v-f50b8f0c]{width:100%}@media screen and (min-width: 576px){.message[data-v-f50b8f0c]{width:400px}}
|
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/newConfiguration-bw8DpVTw.css
vendored
Normal file
1
src/static/app/dist/assets/newConfiguration-bw8DpVTw.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.protocolBtnGroup a[data-v-b4bbbc2b]{transition:all .2s ease-in-out}
|
3
src/static/app/dist/assets/newConfiguration-hFnpzxVA.js
vendored
Normal file
3
src/static/app/dist/assets/newConfiguration-hFnpzxVA.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/peerAddModal-CYgseHuO.js
vendored
Normal file
1
src/static/app/dist/assets/peerAddModal-CYgseHuO.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/peerAddModal-s_w1PY7H.css
vendored
Normal file
1
src/static/app/dist/assets/peerAddModal-s_w1PY7H.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.list-move[data-v-ed72944d],.list-enter-active[data-v-ed72944d],.list-leave-active[data-v-ed72944d]{transition:all .3s ease}.list-enter-from[data-v-ed72944d],.list-leave-to[data-v-ed72944d]{opacity:0;transform:translateY(10px)}.list-leave-active[data-v-ed72944d]{position:absolute}
|
1
src/static/app/dist/assets/peerConfigurationFile-BFmmapnE.css
vendored
Normal file
1
src/static/app/dist/assets/peerConfigurationFile-BFmmapnE.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.slide-up-enter-active[data-v-b0ea2d46],.slide-up-leave-active[data-v-b0ea2d46]{transition:all .2s cubic-bezier(.42,0,.22,1)}.slide-up-enter-from[data-v-b0ea2d46],.slide-up-leave-to[data-v-b0ea2d46]{opacity:0;transform:scale(.9)}@keyframes spin-b0ea2d46{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#check[data-v-b0ea2d46]{animation:cubic-bezier(.42,0,.22,1.3) .7s spin-b0ea2d46}
|
@@ -1 +0,0 @@
|
||||
.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}
|
1
src/static/app/dist/assets/peerConfigurationFile-CkJjp1B4.js
vendored
Normal file
1
src/static/app/dist/assets/peerConfigurationFile-CkJjp1B4.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{_ as v,D as g,r as o,o as h,J as x,g as y,a as i,c as n,b as s,d as c,n as w,e as C,w as k,j as F}from"./index-eyzMkuUX.js";import{L as T}from"./localeText-CJmA8xz4.js";import"./browser-CjSdxGTc.js";const M={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},S={class:"container d-flex h-100 w-100"},D={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},P={class:"card rounded-3 shadow w-100"},j={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},B={class:"mb-0"},G={class:"card-body p-4 d-flex flex-column gap-3"},L={style:{height:"300px"},class:"d-flex"},N=["value"],V={key:0,class:"spinner-border m-auto",role:"status"},I={class:"d-flex"},W=["disabled"],$={key:0,class:"d-block"},q={key:1,class:"d-block",id:"check"},z={__name:"peerConfigurationFile",props:{selectedPeer:Object},emits:["close"],setup(u,{emit:p}){const m=p,f=u,r=g(),t=o(!1),l=o(""),a=o(!0);o({error:!1,message:void 0}),h(()=>{const d=x();y("/api/downloadPeer/"+d.params.id,{id:f.selectedPeer.id},e=>{e.status?(l.value=e.data.file,a.value=!1):this.dashboardStore.newMessage("Server",e.message,"danger")})});const b=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(l.value).then(()=>{t.value=!0,setTimeout(()=>{t.value=!1},3e3)}).catch(()=>{r.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(t.value=!0,setTimeout(()=>{t.value=!1},3e3)):r.newMessage("WGDashboard","Failed to copy","danger"))};return(d,e)=>(i(),n("div",M,[s("div",S,[s("div",D,[s("div",P,[s("div",j,[s("h4",B,[c(T,{t:"Peer Configuration File"})]),s("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=_=>m("close"))})]),s("div",G,[s("div",L,[s("textarea",{style:{height:"300px"},class:w(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,N),a.value?(i(),n("div",V,e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)]))):C("",!0)]),s("div",I,[s("button",{onClick:e[1]||(e[1]=_=>b()),disabled:t.value||a.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[c(F,{name:"slide-up",mode:"out-in"},{default:k(()=>[t.value?(i(),n("span",q,e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)]))):(i(),n("span",$,e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])))]),_:1})],8,W)])])])])])]))}},R=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{R as default};
|
@@ -1 +0,0 @@
|
||||
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-Nht8Bi7_.js";import{L as v}from"./localeText-ClObbhxX.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
@@ -1 +0,0 @@
|
||||
.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%}
|
@@ -1 +1 @@
|
||||
import{S as p,a as b}from"./schedulePeerJob-B__8Gari.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-Nht8Bi7_.js";import{L as w}from"./localeText-ClObbhxX.js";import"./vue-datepicker-vEbbWPoH.js";import"./dayjs.min-DENWFVBv.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};
|
||||
import{S as p,a as b}from"./schedulePeerJob-DztXE0VL.js";import{_ as h,W as u,z as m,k as i,a as o,c as a,b as e,d as r,w as _,F as v,h as f,i as J,e as x,T as g}from"./index-eyzMkuUX.js";import{L as w}from"./localeText-CJmA8xz4.js";import"./vue-datepicker-WMIE6vwD.js";import"./dayjs.min-DZKHFKQc.js";const P={name:"peerJobs",setup(){return{store:u()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:p,ScheduleDropdown:b},data(){return{}},methods:{deleteJob(d){this.selectedPeer.jobs=this.selectedPeer.jobs.filter(t=>t.JobID!==d.JobID)},addJob(){this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({JobID:m().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},k={class:"mb-0 fw-normal"},j={class:"card-body px-4 pb-4 pt-2 position-relative"},T={class:"d-flex align-items-center mb-3"},N={class:"card shadow-sm",key:"none",style:{height:"153px"}},I={class:"card-body text-muted text-center d-flex"},L={class:"m-auto"};function O(d,t,B,F,V,A){const n=i("LocaleText"),l=i("SchedulePeerJob");return o(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",k,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=s=>this.$emit("close"))})]),e("div",j,[e("div",T,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow",onClick:t[1]||(t[1]=s=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(g,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:_(()=>[(o(!0),a(v,null,f(this.selectedPeer.jobs,(s,E)=>(o(),J(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(s),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:s.JobID,pjob:s},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(o(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):x("",!0)]),_:1})])])])])])}const q=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{q as default};
|
1
src/static/app/dist/assets/peerJobsAllModal-CfKJP7gU.js
vendored
Normal file
1
src/static/app/dist/assets/peerJobsAllModal-CfKJP7gU.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{S as _}from"./schedulePeerJob-DztXE0VL.js";import{_ as g,W as v,k as c,a as t,c as r,b as e,d as l,F as p,h as b,t as m,e as f,i as y}from"./index-eyzMkuUX.js";import{L as x}from"./localeText-CJmA8xz4.js";import"./vue-datepicker-WMIE6vwD.js";import"./dayjs.min-DZKHFKQc.js";const J={name:"peerJobsAllModal",setup(){return{store:v()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},k={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},w={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},C={class:"card-body px-4 pb-4 pt-2"},P={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},j={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",k,[e("div",w,[e("div",$,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",C,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",P,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",j,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),y(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const U=g(J,[["render",W]]);export{U as default};
|
@@ -1 +0,0 @@
|
||||
import{S as b}from"./schedulePeerJob-B__8Gari.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-Nht8Bi7_.js";import{L as J}from"./localeText-ClObbhxX.js";import"./vue-datepicker-vEbbWPoH.js";import"./dayjs.min-DENWFVBv.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
2
src/static/app/dist/assets/peerList-C15B-sQd.js
vendored
Normal file
2
src/static/app/dist/assets/peerList-C15B-sQd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
19
src/static/app/dist/assets/peerList-Svxsfk2Z.js
vendored
19
src/static/app/dist/assets/peerList-Svxsfk2Z.js
vendored
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{b as a}from"./browser-CjSdxGTc.js";import{L as n}from"./localeText-ClObbhxX.js";import{_ as c,j as r,a as d,c as i,b as e,d as l}from"./index-Nht8Bi7_.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};
|
1
src/static/app/dist/assets/peerQRCode-BhKfmJRr.js
vendored
Normal file
1
src/static/app/dist/assets/peerQRCode-BhKfmJRr.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{b as r}from"./browser-CjSdxGTc.js";import{L as i}from"./localeText-CJmA8xz4.js";import{_ as c,D as l,g as p,k as _,a,c as n,b as e,d as m,n as h,e as u}from"./index-eyzMkuUX.js";const f={name:"peerQRCode",components:{LocaleText:i},props:{selectedPeer:Object},setup(){return{dashboardStore:l()}},data(){return{loading:!0}},mounted(){p("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},t=>{this.loading=!1,t.status?r.toCanvas(document.querySelector("#qrcode"),t.data.file,s=>{s&&console.error(s)}):this.dashboardStore.newMessage("Server",t.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},g={class:"container d-flex h-100 w-100"},v={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},x={class:"card rounded-3 shadow"},C={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},w={class:"mb-0"},y={class:"card-body p-4"},S={style:{width:"292px",height:"292px"},class:"d-flex"},k={key:0,class:"spinner-border m-auto",role:"status"};function L(t,s,$,q,o,B){const d=_("LocaleText");return a(),n("div",b,[e("div",g,[e("div",v,[e("div",x,[e("div",C,[e("h4",w,[m(d,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:s[0]||(s[0]=N=>this.$emit("close"))})]),e("div",y,[e("div",S,[e("canvas",{id:"qrcode",class:h(["rounded-3 shadow animate__animated animate__fadeIn animate__faster",{"d-none":o.loading}])},null,2),o.loading?(a(),n("div",k,s[1]||(s[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)]))):u("",!0)])])])])])])}const T=c(f,[["render",L]]);export{T as default};
|
1
src/static/app/dist/assets/peerSearchBar-BU3mOD38.js
vendored
Normal file
1
src/static/app/dist/assets/peerSearchBar-BU3mOD38.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{_ as u,q as m,G as p,r as b,W as f,a2 as h,o as g,a as v,i as y,w as _,b as e,m as x,y as w,d as S,j as B}from"./index-eyzMkuUX.js";import{L as T}from"./localeText-CJmA8xz4.js";const C={class:"fixed-bottom w-100 bottom-0 z-2",style:{"z-index":"1"}},P={class:"container-fluid"},k={class:"row g-0"},L={class:"col-md-9 col-lg-10 d-flex justify-content-center py-2"},V={class:"rounded-3 p-2 border shadow searchPeersContainer bg-body-tertiary"},j={class:"d-flex gap-1 align-items-center px-2"},z=["placeholder"],D={__name:"peerSearchBar",emits:["close"],setup(G,{emit:n}){const l=m(()=>p("Search Peers..."));let t;const o=b(""),r=f(),i=()=>{t?(clearTimeout(t),t=setTimeout(()=>{r.searchString=o.value},300)):t=setTimeout(()=>{r.searchString=o.value},300)},d=n,c=h("searchBar");return g(()=>{c.value.focus()}),(M,s)=>(v(),y(B,{name:"slideUp",appear:"",type:"animation",style:{"animation-delay":"1s"}},{default:_(()=>[e("div",C,[e("div",P,[e("div",k,[s[5]||(s[5]=e("div",{class:"col-md-3 col-lg-2"},null,-1)),e("div",L,[e("div",V,[e("div",j,[s[4]||(s[4]=e("h6",{class:"mb-0 me-2"},[e("label",{for:"searchPeers"},[e("i",{class:"bi bi-search"})])],-1)),x(e("input",{ref:"searchBar",class:"flex-grow-1 form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:s[0]||(s[0]=a=>i()),"onUpdate:modelValue":s[1]||(s[1]=a=>o.value=a)},null,40,z),[[w,o.value]]),e("button",{onClick:s[2]||(s[2]=a=>d("close")),style:{"white-space":"nowrap"},class:"btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3 d-flex align-items-center"},[e("span",null,[s[3]||(s[3]=e("i",{class:"bi bi-x-circle-fill me-2"},null,-1)),S(T,{t:"Done"})])])])])])])])])]),_:1}))}},W=u(D,[["__scopeId","data-v-b741afe7"]]);export{W as default};
|
1
src/static/app/dist/assets/peerSearchBar-BrbvrjWX.css
vendored
Normal file
1
src/static/app/dist/assets/peerSearchBar-BrbvrjWX.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.searchPeersContainer[data-v-b741afe7]{width:100%}
|
@@ -1 +0,0 @@
|
||||
.toggleShowKey[data-v-a63ae8cb]{position:absolute;top:35px;right:12px}
|
1
src/static/app/dist/assets/peerSettings-D3AcEi5s.js
vendored
Normal file
1
src/static/app/dist/assets/peerSettings-D3AcEi5s.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/peerSettings-oGNRGN1t.css
vendored
Normal file
1
src/static/app/dist/assets/peerSettings-oGNRGN1t.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.toggleShowKey[data-v-2166fcf9]{position:absolute;top:35px;right:12px}
|
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/peerShareLinkModal-B70igrxz.js
vendored
Normal file
1
src/static/app/dist/assets/peerShareLinkModal-B70igrxz.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
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-Nht8Bi7_.js";import{d}from"./dayjs.min-DENWFVBv.js";import{V as y}from"./vue-datepicker-vEbbWPoH.js";import{L as S}from"./localeText-ClObbhxX.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};
|
1
src/static/app/dist/assets/peerShareLinkModal-ouYxVldA.css
vendored
Normal file
1
src/static/app/dist/assets/peerShareLinkModal-ouYxVldA.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.card[data-v-8cfb4d4d]{border-color:var(--bs-border-color)!important}textarea[data-v-6e705c87]:focus,input[data-v-6e705c87]:focus{box-shadow:none;border-color:var(--bs-border-color)!important}textarea[data-v-6e705c87]{padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}
|
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/protocolBadge-ebDPMiwz.js
vendored
Normal file
1
src/static/app/dist/assets/protocolBadge-ebDPMiwz.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{L as r}from"./localeText-CJmA8xz4.js";import{a as t,c as n,f as i,i as s,e as a}from"./index-eyzMkuUX.js";const d={key:0,class:"badge wireguardBg rounded-3 shadow"},c={key:1,class:"badge amneziawgBg rounded-3 shadow"},u={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(e){return(m,o)=>e.protocol==="wg"?(t(),n("span",d,[o[0]||(o[0]=i(" WireGuard ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):e.protocol==="awg"?(t(),n("span",c,[o[1]||(o[1]=i(" AmneziaWG ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):a("",!0)}};export{u as _};
|
4
src/static/app/dist/assets/restoreConfiguration-C2ykCVB5.js
vendored
Normal file
4
src/static/app/dist/assets/restoreConfiguration-C2ykCVB5.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.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
1
src/static/app/dist/assets/restoreConfiguration-VgIx_N7z.css
vendored
Normal file
1
src/static/app/dist/assets/restoreConfiguration-VgIx_N7z.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.dropdownIcon[data-v-ccf48ac7]{transition:all .2s ease-in-out}.dropdownIcon.active[data-v-ccf48ac7]{transform:rotate(180deg)}.steps{&[data-v-324df2b1]{transition:all .3s ease-in-out;opacity:.3}&.active[data-v-324df2b1]{opacity:1}}
|
@@ -1 +0,0 @@
|
||||
.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
1
src/static/app/dist/assets/schedulePeerJob-DPy59wup.css
vendored
Normal file
1
src/static/app/dist/assets/schedulePeerJob-DPy59wup.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.btn.disabled[data-v-6a5aba2a]{opacity:1;background-color:#0d6efd17;border-color:transparent}[data-v-4aa63a3e]{font-size:.875rem}input[data-v-4aa63a3e]{padding:.1rem .4rem}input[data-v-4aa63a3e]:disabled{border-color:transparent;background-color:#0d6efd17;color:#0d6efd}.dp__main[data-v-4aa63a3e]{width:auto;flex-grow:1;--dp-input-padding: 2.5px 30px 2.5px 12px;--dp-border-radius: .5rem}
|
1
src/static/app/dist/assets/schedulePeerJob-DztXE0VL.js
vendored
Normal file
1
src/static/app/dist/assets/schedulePeerJob-DztXE0VL.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/static/app/dist/assets/settings-BfIduOgN.js
vendored
Normal file
1
src/static/app/dist/assets/settings-BfIduOgN.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +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)}}
|
||||
@media screen and (max-width: 992px){.apiKey-card-body{&[data-v-a76253c8]{flex-direction:column!important;align-items:start!important}div.ms-auto[data-v-a76253c8]{margin-left:0!important}div[data-v-a76253c8]{width:100%;align-items:start!important}small[data-v-a76253c8]{margin-right:auto}}}.apiKey-move[data-v-100ee9f9],.apiKey-enter-active[data-v-100ee9f9],.apiKey-leave-active[data-v-100ee9f9]{transition:all .5s ease}.apiKey-enter-from[data-v-100ee9f9],.apiKey-leave-to[data-v-100ee9f9]{opacity:0;transform:translateY(30px) scale(.9)}.apiKey-leave-active[data-v-100ee9f9]{position:absolute;width:100%}.dropdown-menu[data-v-4e34593e]{width:100%}.list-group{&[data-v-4aa2aed9]:first-child{border-top-left-radius:var(--bs-border-radius-lg);border-top-right-radius:var(--bs-border-radius-lg)}&[data-v-4aa2aed9]:last-child{border-bottom-left-radius:var(--bs-border-radius-lg);border-bottom-right-radius:var(--bs-border-radius-lg)}}
|
File diff suppressed because one or more lines are too long
@@ -1 +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-Nht8Bi7_.js";import{L as g}from"./localeText-ClObbhxX.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};
|
||||
import{_ as u,D as m,A as p,c as r,b as e,d as o,f as c,t as h,e as f,m as l,y as d,a as i,k as w}from"./index-eyzMkuUX.js";import{L as g}from"./localeText-CJmA8xz4.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:m()}},data(){return{setup:{username:"",newPassword:"",repeatNewPassword:"",enable_totp:!0},loading:!1,errorMessage:"",done:!1}},computed:{goodToSubmit(){return this.setup.username&&this.setup.newPassword.length>=8&&this.setup.repeatNewPassword.length>=8&&this.setup.newPassword===this.setup.repeatNewPassword}},methods:{submit(){this.loading=!0,p("/api/Welcome_Finish",this.setup,n=>{n.status?(this.done=!0,this.$router.push("/2FASetup")):(document.querySelectorAll("#createAccount input").forEach(s=>s.classList.add("is-invalid")),this.errorMessage=n.message,document.querySelector(".login-container-fluid").scrollTo({top:0,left:0,behavior:"smooth"})),this.loading=!1})}}},_=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},v={class:"dashboardLogo display-4"},y={class:"mb-5"},P={key:0,class:"alert alert-danger"},N={class:"d-flex flex-column gap-3"},k={id:"createAccount",class:"d-flex flex-column gap-2"},S={class:"form-group text-body"},T={for:"username",class:"mb-1 text-muted"},C={class:"form-group text-body"},L={for:"password",class:"mb-1 text-muted"},V={class:"form-group text-body"},A={for:"confirmPassword",class:"mb-1 text-muted"},$=["disabled"],q={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=w("LocaleText");return i(),r("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[e("div",x,[e("span",v,[o(t,{t:"Nice to meet you!"})]),e("p",y,[o(t,{t:"Please fill in the following fields to finish setup"}),s[4]||(s[4]=c(" 😊"))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):f("",!0),e("div",N,[e("form",k,[e("div",S,[e("label",T,[e("small",null,[o(t,{t:"Enter an username you like"})])]),l(e("input",{type:"text",autocomplete:"username","onUpdate:modelValue":s[0]||(s[0]=a=>this.setup.username=a),class:"form-control",id:"username",name:"username",required:""},null,512),[[d,this.setup.username]])]),e("div",C,[e("label",L,[e("small",null,[o(t,{t:"Enter a password"}),e("code",null,[o(t,{t:"(At least 8 characters and make sure is strong enough!)"})])])]),l(e("input",{type:"password",autocomplete:"new-password","onUpdate:modelValue":s[1]||(s[1]=a=>this.setup.newPassword=a),class:"form-control",id:"password",name:"password",required:""},null,512),[[d,this.setup.newPassword]])]),e("div",V,[e("label",A,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",q,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,$)])])])],8,_)}const j=u(b,[["render",B]]);export{j as default};
|
@@ -1 +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-Nht8Bi7_.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-ClObbhxX.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};
|
||||
import{_,r,D as p,g as u,c as m,b as t,d as c,J as h,a as f,k as b}from"./index-eyzMkuUX.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-CJmA8xz4.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=h(),e=r(!1),i=p(),n=r(""),s=r(void 0),l=r(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(s.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(s.value=d.data,l.value=new Blob([s.value.file],{type:"text/plain"})):s.value=void 0,e.value=!0}),{store:i,theme:n,peerConfiguration:s,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),i=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=i,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},w=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},I={class:"m-auto"},L={key:1,class:"d-flex align-items-center flex-column gap-3"},k={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},B={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},D={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},R=["download","href"];function q(o,e,i,n,s,l){const a=b("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",x,[this.peerConfiguration?(f(),m("div",L,[t("div",k,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),c(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",B,null,512),t("p",D,[c(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),c(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)]),8,R)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",I,[c(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,w)}const N=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{N as default};
|
1
src/static/app/dist/assets/signin-BPnIy8wa.js
vendored
Normal file
1
src/static/app/dist/assets/signin-BPnIy8wa.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +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}
|
||||
.dot.inactive[data-v-ed7817c7]{background-color:#dc3545;box-shadow:0 0 0 .2rem #dc354545}.spin[data-v-ed7817c7]{animation:spin-ed7817c7 1s infinite cubic-bezier(.82,.58,.17,.9)}@keyframes spin-ed7817c7{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media screen and (max-width: 768px){.remoteServerContainer[data-v-ed7817c7]{flex-direction:column}.remoteServerContainer .button-group button[data-v-ed7817c7]{width:100%}}@media screen and (max-width: 768px){.login-box[data-v-80e20da4]{width:100%!important}.login-box div[data-v-80e20da4]{width:auto!important}}
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user