Compare commits

..

163 Commits

Author SHA1 Message Date
Donald Zou ae160aef23 Updated ConfigParser to RawConfigParser; Updated version number 2025-08-02 16:54:50 +08:00
Donald Zou 85d1cc8be4 Merge pull request #833 from DaanSelen/hinakumo-patch
Hinakumo patch
2025-07-26 02:18:40 +08:00
Velrino 8cff8d85f6 chore: update documentation links in agentModal and helpModal (#811)
LGTM!
2025-07-24 20:41:00 +02:00
DaanSelen d7a1007f41 Merge branch 'donaldzou:main' into hinakumo-patch 2025-07-24 20:28:20 +02:00
daanselen 0cd2c6864e make stale compliant 2025-07-24 20:27:54 +02:00
daanselen 0cb46e1444 Docker file update 2025-07-24 20:23:42 +02:00
Donald Zou cb9dfa1321 Fixed Docker system status widget issue (#832)
* Fixed Docker system status widget issue

* Build

ref: https://github.com/donaldzou/WGDashboard/issues/798
2025-07-24 19:42:41 +02:00
Donald Zou 43fd2fff2b Merge pull request #821 from NaturGamerYT/main
Update de-de.json
2025-07-17 13:49:10 +08:00
Florian b37c64f5a5 Update de-de.json 2025-07-16 13:55:28 +02:00
hinakumo f1aa064b2d Made CDs more direct 2025-07-14 01:26:01 +03:00
Matias G Henschel 8abadd1070 Added PT-BR language, minor ES fix. (#817) 2025-07-13 21:29:43 +02:00
hinakumo 3f9d9732a0 Added build packages deps to Dockerfile 2025-07-12 09:21:29 +03:00
hinakumo b9dc3c44a8 Change AWG repos in Dockerfile 2025-07-12 09:08:10 +03:00
DaanSelen 1483ef83d9 Added except label (#806) 2025-06-25 10:51:23 +02:00
Donald Zou dbed799e20 Merge pull request #805 from DaanSelen/staleenglish
English fix
2025-06-25 16:32:28 +08:00
daanselen 4602b68425 English fix 2025-06-25 10:27:34 +02:00
Donald Zou 2d3eaedaa7 Update README.md 2025-06-24 17:20:21 +08:00
Donald Zou 4d60b21a5f Update stale.yml 2025-06-24 17:09:56 +08:00
Donald Zou 50ee8374ee Update stale.yml 2025-06-24 16:36:22 +08:00
Donald Zou 65eb23e8ce Update stale.yml 2025-06-24 16:36:13 +08:00
Donald Zou 5c76b18ddd Delete .github/workflows/stale_action 2025-06-24 16:27:05 +08:00
Donald Zou fc6f5d2535 Create stale.yml 2025-06-24 16:26:35 +08:00
Donald Zou 6a0348e9dc Create stale_action 2025-06-24 16:15:36 +08:00
Donald Zou 90e6409b1e Update dashboard.py
Update version number
2025-06-17 13:34:13 +08:00
Donald Zou 96b28a8e9b Update dashboard.py (#791)
Removed `getDashboardConfiguration` from API whitelist
2025-06-16 23:01:04 +02:00
Donald Zou a818e87e96 Merge pull request #793 from DaanSelen/delpr 2025-06-16 22:25:16 +08:00
DaanSelen dc715758a6 Merge branch 'donaldzou:main' into delpr 2025-06-16 14:45:53 +02:00
daanselen 87069329d8 Where do these come from? 2025-06-16 14:45:23 +02:00
daanselen 8a380a4545 Separated tasks (again) and separate builds 2025-06-16 14:42:39 +02:00
daanselen a5e18cb761 del pr running 2025-06-16 14:41:02 +02:00
DaanSelen e9da3e7b6a streamline docker (#792) 2025-06-16 14:33:16 +02:00
daanselen 289fa23728 streamline 2025-06-16 14:27:12 +02:00
Donald Zou c117ee61d5 Merge pull request #780 from donaldzou/releasetagging
Docker release management
2025-06-05 10:55:37 +08:00
daanselen 7385932e52 donald 2025-06-04 19:54:40 +02:00
daanselen cb90b69b3f Looks good! 2025-06-04 19:52:44 +02:00
Donald Zou 8d0e31872a Update README.md
Testing GitHub Action
2025-06-05 00:18:22 +08:00
Donald Zou 881925fd43 Update docker.yml 2025-06-04 23:52:51 +08:00
Donald Zou 3a2f744f0a Merge pull request #779 from DaanSelen/scanfix
Add a login to the scan
2025-06-04 23:29:55 +08:00
daanselen 9dc9e668c5 Add a login to the scan 2025-06-04 16:53:16 +02:00
Donald Zou 39477c8de8 Merge pull request #778 from donaldzou/DaanSelen-patch-1 2025-06-04 22:44:08 +08:00
DaanSelen 1b0bb95e81 Update docker.yml
I hate this.
2025-06-04 16:41:18 +02:00
Donald Zou cd5a4bec52 Merge pull request #776 from donaldzou/DaanSelen-patch-4 2025-06-04 22:33:26 +08:00
daanselen 43070ab809 Syntax fix 2025-06-04 13:14:03 +02:00
daanselen 532fedbb62 Adding file 2025-06-04 13:05:35 +02:00
daanselen 585bf37783 THIS SHOULD BE WORKING 2025-06-04 13:04:17 +02:00
DaanSelen cad364e407 Update docker-build.yml
Pulled out the action docs this time...
2025-06-04 11:01:38 +02:00
Donald Zou 45457c5b38 Merge pull request #775 from donaldzou/DaanSelen-patch-3 2025-06-04 16:57:28 +08:00
DaanSelen 4e9142b5be Update docker-build.yml
Its becoming not fun
2025-06-04 10:56:28 +02:00
Donald Zou 207b365d40 Merge pull request #774 from donaldzou/DaanSelen-patch-2 2025-06-04 16:45:00 +08:00
DaanSelen 1ec95a0d86 Update docker-build.yml 2025-06-04 10:42:54 +02:00
Donald Zou db4b9ccc7a Merge pull request #773 from donaldzou/DaanSelen-patch-1 2025-06-04 16:38:37 +08:00
DaanSelen a86d0c74d3 Update docker-build.yml 2025-06-04 10:36:42 +02:00
Donald Zou 354f4e47df Merge pull request #772 from DaanSelen/workflowclarify 2025-06-04 16:32:52 +08:00
daanselen 84167650b8 hotfix 2025-06-04 10:27:11 +02:00
daanselen 15c12a81f1 Separate stages 2025-06-04 10:12:18 +02:00
DaanSelen 249ae584c3 Merge branch 'donaldzou:main' into workflowclarify 2025-06-04 10:09:57 +02:00
DaanSelen b04f7b2d2c Separated tasks (again) and separate builds (#771)
* Separated tasks (again) and separate builds (#8)

* Update docker-build.yml

Updated `GHCR_TOKEN` to `GITHUB_TOKEN`

---------

Co-authored-by: Donald Zou <donaldzou@live.hk>
2025-06-04 10:01:01 +02:00
Donald Zou 630ce459cb Update docker-build.yml
Updated `GHCR_TOKEN` to `GITHUB_TOKEN`
2025-06-04 15:55:22 +08:00
DaanSelen a7a30fb282 Separated tasks (again) and separate builds (#8) 2025-06-03 15:19:11 +02:00
Donald Zou ab5abe9bcf Merge pull request #767 from donaldzou/potential-fix-#762
Background thread terminated when iterating conf list and list changed
2025-05-31 22:52:12 +08:00
Donald Zou 7834fff541 Update dashboard.py
Potential fix for #762
2025-05-29 16:52:13 +08:00
Donald Zou ef8849e8a9 Update README.md 2025-05-29 00:24:07 +08:00
Donald Zou 78bedf9ad6 Update README.md 2025-05-25 12:58:18 +08:00
Donald Zou 6ec757ab66 Merge pull request #759 from donaldzou/fix-pi-os-installation-issue
Update wgd.sh
2025-05-24 20:43:18 +08:00
Kármán Zsombor 7d71299c51 Add Hungarian language support (#747)
* feat(i18n): add Hungarian (Magyar) language support

* Update active_languages.json

chore: remove extra leading space from line

* Fix: relocate Hungarian (hu-hu) to correct alphabetical position
2025-05-22 23:52:59 +02:00
Donald Zou bea37aee7f Update wgd.sh
Added `raspbian` into installation, thanks @DerPitter bringing this up at #749
2025-05-22 19:52:05 +08:00
Donald Zou 5323687ea5 Update README.md 2025-05-22 17:19:56 +08:00
Donald Zou d1372a4c43 Update README.md 2025-05-22 17:05:25 +08:00
Donald Zou c9249a164a Merge pull request #758 from DaanSelen/main 2025-05-22 10:00:47 +08:00
DaanSelen 6f105f2626 Updated Dutch translations (#7) 2025-05-21 09:59:40 +02:00
DaanSelen e4c08896f4 Merge branch 'donaldzou:main' into main 2025-05-21 09:50:49 +02:00
Donald Zou e85a0df9b7 Update README.md 2025-05-21 13:08:00 +08:00
Donald Zou a5b7eabd97 Update README.md 2025-05-20 23:56:43 +08:00
Donald Zou f3688431a3 Update README.md 2025-05-20 23:55:34 +08:00
Donald Zou 44e714352d Merge pull request #755 from donaldzou/fix-awg-qrcode
Fix AmneziaWG QR Code not workiing
2025-05-19 21:55:28 +08:00
Donald Zou 60da68c994 Build 2025-05-19 21:49:19 +08:00
Donald Zou 11288fac20 Update peerQRCode.vue 2025-05-19 21:44:16 +08:00
Donald Zou fe9d373444 Delete .github/workflows/qodana_code_quality.yml 2025-05-13 20:42:29 +08:00
Donald Zou cce31f9b0b Merge pull request #744 from donaldzou/fix-schedule-job-issue
Update dashboard.py
2025-05-11 00:14:01 +08:00
Donald Zou ca779ed5ad Update dashboard.py
- Update Job list before every run
2025-05-11 00:09:23 +08:00
Donald Zou eb0eaaae2e Merge pull request #733 from donaldzou/v4.2.3-dev
v4.2.3 Merge
2025-05-07 23:18:33 +08:00
Donald Zou 9631b97694 Final UI Build 2025-05-07 23:15:24 +08:00
Donald Zou 6f036876c8 Doing a final check 2025-05-07 23:14:56 +08:00
Donald Zou bd47179ea4 Build UI for v4.2.3 2025-05-07 22:48:43 +08:00
dselen 418c6bd88b Merge branch 'donaldzou:main' into main 2025-05-07 08:41:49 +02:00
Donald Zou ada4c4f816 Update dashboard.py
- Fixed #737
- Removed unnecessary code
2025-05-07 13:00:18 +08:00
Donald Zou 91b499fb14 Update peerQRCode.vue 2025-05-04 17:09:45 +08:00
Donald Zou 1f73adffd6 Fixed issue #698 2025-05-04 01:54:47 +08:00
Donald Zou 82bd313e7a Taking Copilot's suggestion 2025-05-03 17:33:40 +08:00
Donald Zou 14cbfe47b9 Updated theme color 2025-05-03 16:56:20 +08:00
Donald Zou f2d4ff6dc4 Update dashboard.py
Fixed the issue where TOTP Key is not actually reset when reset.
2025-05-03 16:13:30 +08:00
Donald Zou bf33a70727 Updated all language file to latest language template 2025-05-02 23:34:44 +08:00
Donald Zou e1bdcbd581 Merge pull request #708 from Jumala9163/locale/japanese
Updated Japanese translation & Added untranslated parts
2025-05-02 23:00:55 +08:00
Donald Zou 051c1e7622 Merge pull request #722 from reykim7854/locale-indonesia
add Bahasa Indonesia to localization
2025-05-02 22:56:47 +08:00
Donald Zou 3b176474ff Merge pull request #725 from sf0nt/main
add catalan translation
2025-05-02 22:55:14 +08:00
Donald Zou 15f1b33ea6 Merge pull request #727 from DaanSelen/dockerpidclean
Fix: 723 and more
2025-05-02 22:53:05 +08:00
Donald Zou 0603d4076a Merge branch 'v4.2.3-dev' into dockerpidclean 2025-05-02 22:52:52 +08:00
reykim7854 ac94f10dc3 fix deprecated locale key 2025-05-02 21:37:55 +07:00
sf0nt bbb92490e9 order languages alphabetically 2025-05-02 16:03:08 +02:00
Donald Zou 2cb63092c0 Fixed AmneziaWG QR Code out of screen on phone 2025-05-02 21:35:27 +08:00
Donald Zou b9bcb59592 Fixed CPU Core floating label height 2025-05-02 20:51:58 +08:00
Donald Zou e083adc022 Merge pull request #728 from BeppeMarnell/#712-peer-delete-bug
API Peer delete bug #712 fix: fixed issue with delete endpoint return…
2025-05-02 20:33:26 +08:00
Donald Zou c3cd38fe9f Update dashboard.py
- Fixed issue where deleting configuration will delete other configuration with similar name
2025-05-02 20:11:11 +08:00
giuseppe a7c2db5e99 API Peer delete bug #712 fix: fixed issue with delete endpoint returning always 200 2025-05-02 11:52:39 +02:00
daanselen 4926ee5117 Fix https://github.com/donaldzou/WGDashboard/issues/723 and more 2025-05-02 10:02:38 +02:00
Donald Zou e7723ac3db Build and update version number 2025-05-02 14:34:23 +08:00
Donald Zou 8dbfb93e4e Merge pull request #726 from donaldzou/fix-awg-advanced-security
Fix awg advanced security
2025-05-02 14:30:57 +08:00
Donald Zou 6096366756 Merge pull request #724 from DaanSelen/main
AmneziaWG Fix for Docker
2025-05-02 14:27:33 +08:00
sf0nt 8e4cf12512 Update active_languages.json 2025-05-02 04:42:43 +02:00
sf0nt b61fa1f870 Rename es-ca.json to ca.json 2025-05-02 04:41:46 +02:00
sf0nt ac3cf9e4b1 Rename es_ca.json to es-ca.json 2025-05-02 04:38:57 +02:00
sf0nt e18463f059 Update es_ca.json 2025-05-02 04:38:19 +02:00
Donald Zou ee54e08d18 Build and removed advanced_security from UI 2025-05-01 19:59:58 +02:00
Donald Zou 3c07df6496 Build and removed advanced_security from UI 2025-05-01 23:08:40 +08:00
Donald Zou 2117b828c8 Update dashboard.py
Removed `advanced-security` from command line send to AWG
2025-05-01 16:42:37 +02:00
Donald Zou 28d9694432 Update dashboard.py
Removed `advanced-security` from command line send to AWG
2025-05-01 22:40:53 +08:00
daanselen 7d977700e6 typo 2025-05-01 16:38:19 +02:00
Donald Zou 33942945d0 commit 2025-05-01 22:28:43 +08:00
daanselen 8d7d78db46 Not alpine, latest 2025-05-01 16:21:30 +02:00
daanselen 3268cc30ea Donald 2025-05-01 16:20:20 +02:00
Daan Selen 8830ebe34f AmneziaWG Fix for Docker 2025-05-01 16:15:55 +02:00
reykim7854 1d9adba6dd add Bahasa Indonesia to localization 2025-05-01 12:21:29 +07:00
sf0nt 71be73777e Update es_ca.json 2025-05-01 02:51:53 +02:00
sf0nt 7709f70ef1 Update es_ca.json 2025-05-01 02:21:21 +02:00
sf0nt 9b528b84e1 Update es_ca.json 2025-05-01 02:09:04 +02:00
sf0nt c53a4d4861 Update es_ca.json 2025-04-30 05:23:02 +02:00
sf0nt 766173df3d Update es_ca.json 2025-04-30 05:02:43 +02:00
sf0nt 7f65cae891 Update es_ca.json 2025-04-30 04:43:41 +02:00
sf0nt bc56ecb85c Update es_ca.json 2025-04-30 03:59:00 +02:00
sf0nt 50c3151301 Update es_ca.json 2025-04-30 03:41:49 +02:00
sf0nt d49ec0a81e Update es_ca.json 2025-04-30 03:07:00 +02:00
sf0nt 6692028762 Update es_ca.json 2025-04-30 02:49:00 +02:00
sf0nt b71c357958 Create es_ca.json 2025-04-30 02:40:47 +02:00
sf0nt 03b7621f3e Update active_languages.json with catalan 2025-04-30 02:40:01 +02:00
Donald Zou 2bcf24bd84 Merge pull request #710 from reloadlife/feat/route-table
feat: Supporting "table" directive in the configuration
2025-04-27 16:17:17 +08:00
Jumala9163 cc5aa05b12 Fixed where translations were not being done correctly. 2025-04-26 17:26:23 +09:00
Jumala9163 3232c5c4ce update ja-jp & Add new locations that are not yet translated 2025-04-26 16:50:31 +09:00
dselen 72a52f5cd6 Merge pull request #704 from DaanSelen/dockerdoc
Docker files cleanup
2025-04-25 14:58:35 +02:00
daanselen bda48a56e0 Docker files cleanup 2025-04-25 09:27:07 +02:00
Donald Zou 09cdcf8e53 Update version number 2025-04-25 14:23:51 +08:00
Donald Zou a4d5b41ca7 Merge pull request #703 from donaldzou/fix-#702
Fix #702 and #699
2025-04-25 14:15:33 +08:00
Donald Zou 9fa0d91d06 Update Email.py
Fixed #699
2025-04-25 14:08:45 +08:00
Donald Zou 510f60bdeb Update Email.py
Fixed to accomodate SMTP service where `username` is not an email address from #702
2025-04-25 13:39:29 +08:00
Mohammad Mahdi Afshar 30fe827253 feat: Supporting "table" directive in the configuration 2025-04-24 18:51:26 +03:30
Donald Zou 8f0f4b168b Update README.md
Added demo server
2025-04-24 19:13:34 +08:00
Donald Zou cd11c4beb6 Merge branch 'main' of https://github.com/donaldzou/WGDashboard 2025-04-23 21:27:01 +08:00
Donald Zou 4d49cc413a Update README.md 2025-04-23 21:26:21 +08:00
Donald Zou 3d50a58a31 Merge pull request #690 from donaldzou/donaldzou-patch-2
Update README.md
2025-04-23 20:23:03 +08:00
Donald Zou d5701230fa Pushing this for Docker 2025-04-23 20:22:26 +08:00
Donald Zou ab945d6afe Update README.md
Changed the icon!
2025-04-23 20:06:44 +08:00
Donald Zou b4f8a36d43 Merge pull request #689 from donaldzou/fix-#683
Fix #683
2025-04-23 19:31:50 +08:00
Donald Zou 608c1b4eb6 Update version number to v4.2.1 2025-04-23 19:30:41 +08:00
Donald Zou edf3c42157 Update version number 2025-04-23 19:26:31 +08:00
Donald Zou c523cec113 Fixed #683 and Re-build 2025-04-23 19:24:50 +08:00
Donald Zou 6f8b987d42 Merge pull request #688 from donaldzou/fix-welcome-session-issue
Update dashboard.py
2025-04-23 18:06:10 +08:00
Donald Zou d0d0642bdf Update dashboard.py
Fixed issue where new user can't finish welcome session
2025-04-23 18:05:19 +08:00
Donald Zou 924d760e3b Merge pull request #687 from DaanSelen/delarmv6
Remove arm v6 because go image has not been built for it.
2025-04-23 16:29:17 +08:00
Donald Zou f8c207ca2b Merge pull request #685 from Jorropo/fr-fr
locale: Add fr-fr language
2025-04-23 16:22:43 +08:00
daanselen ada1edd0b7 Remove arm v6 because go image has not been built for it. 2025-04-23 10:08:09 +02:00
Donald Zou c79333db61 Merge pull request #681 from DaanSelen/imagebump
Imagebump
2025-04-23 16:00:53 +08:00
Jorropo 13778bed87 locale: Add fr-fr language
This file copies most of the work from @alexp did in af5e7974 when adding fr-ca language.

There a handful of sentences being rephrased.
Typographic changes.
And few corrections that should probably be done in fr-ca too.
2025-04-23 07:33:16 +02:00
daanselen 83b4d96f42 go image bump 2025-04-22 21:36:28 +02:00
daanselen 6cf96de0b4 Moved Docker file around, cleaning. 2025-04-22 21:20:41 +02:00
120 changed files with 3688 additions and 857 deletions
+1
View File
@@ -12,6 +12,7 @@
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
-55
View File
@@ -1,55 +0,0 @@
name: Docker Scan and Build
on:
push:
branches: [ main ]
schedule:
- cron: "0 0 * * *" # Daily at midnight UTC
workflow_dispatch:
inputs:
trigger-build:
description: 'Trigger a manual build and push'
default: 'true'
env:
DOCKER_IMAGE: donaldzou/wgdashboard
jobs:
docker_build_analyze:
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export (multi-arch)
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ env.DOCKER_IMAGE }}:latest
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
- name: Docker Scout
id: docker-scout
uses: docker/scout-action@v1
with:
command: cves
image: ${{ env.DOCKER_IMAGE }}:latest
only-severities: critical,high,medium,low,unspecified
github-token: ${{ secrets.GITHUB_TOKEN }}
+105
View File
@@ -0,0 +1,105 @@
name: Docker Build and Push
on:
workflow_dispatch:
push:
branches:
- 'main'
tags:
- '*'
release:
types: [ published ]
env:
DOCKERHUB_PREFIX: docker.io
GITHUB_CONTAINER_PREFIX: ghcr.io
DOCKER_IMAGE: donaldzou/wgdashboard
jobs:
docker_build:
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:
registry: ${{ env.DOCKERHUB_PREFIX }}
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.GITHUB_CONTAINER_PREFIX }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: |
- linux/amd64
- linux/arm64
- linux/arm/v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta by docs https://github.com/docker/metadata-action
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_PREFIX }}/${{ env.DOCKER_IMAGE }}
${{ env.GITHUB_CONTAINER_PREFIX }}/${{ env.DOCKER_IMAGE }}
tags: |
type=ref,event=branch
type=ref,event=tag
- name: Build and export (multi-arch)
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
docker_scan:
if: ${{ github.event_name != 'pull_request' }}
runs-on: ubuntu-latest
needs: docker_build
steps:
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKERHUB_PREFIX }}
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Docker Scout CVEs
uses: docker/scout-action@v1
with:
command: cves
image: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ env.DOCKER_IMAGE }}:main
only-severities: critical,high
only-fixed: true
write-comment: true
github-token: ${{ secrets.GITHUB_TOKEN }}
exit-code: true
- name: Docker Scout Compare
uses: docker/scout-action@v1
with:
command: compare
# Set to Github for maximum compat
image: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ env.DOCKER_IMAGE }}:main
to: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ env.DOCKER_IMAGE }}:latest
only-severities: critical,high
ignore-unchanged: true
github-token: ${{ secrets.GITHUB_TOKEN }}
-28
View File
@@ -1,28 +0,0 @@
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'
+26
View File
@@ -0,0 +1,26 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
workflow_dispatch:
schedule:
- cron: '00 08 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has not been updated for 20 days'
stale-pr-message: 'This pull request has not been updated for 20 days'
stale-issue-label: 'stale'
exempt-issue-labels: 'enhancement,ongoing'
days-before-stale: 20
+1
View File
@@ -18,6 +18,7 @@ src/db/wgdashboard.db
node_modules/**
*/proxy.js
src/static/app/proxy.js
.secrets
# Logs
logs
+36 -26
View File
@@ -4,27 +4,28 @@
> [!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!
![](https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Posters/Banner.png)
<p align="center">
<img alt="WGDashboard" src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Logos/Logo-2-Rounded-512x512.png" width="128">
</p>
<h1 align="center">WGDashboard</h1>
<h1 align="center">
<a href="https://wgdashboard.dev">WGDashboard</a>
</h1>
<p align="center">
<img src="https://forthebadge.com/images/badges/made-with-python.svg">
<img src="https://forthebadge.com/images/badges/made-with-javascript.svg">
<img src="https://forthebadge.com/images/badges/license-mit.svg">
</p>
<p align="center">
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
<img src="https://img.shields.io/badge/Made_With-Python-blue?style=for-the-badge&logo=python&logoColor=ffffff">
<img src="https://img.shields.io/badge/Made_With-Vue.js-42b883?style=for-the-badge&logo=vuedotjs&logoColor=ffffff">
<img src="https://img.shields.io/badge/License-Apache_License_2.0-D22128?style=for-the-badge&logo=apache&logoColor=ffffff">
</p>
<p align="center">
<a href="https://github.com/donaldzou/wireguard-dashboard/releases/latest"><img src="https://img.shields.io/github/v/release/donaldzou/wireguard-dashboard"></a>
<a href="https://wakatime.com/badge/github/donaldzou/WGDashboard"><img src="https://wakatime.com/badge/github/donaldzou/WGDashboard.svg" alt="wakatime"></a>
<a href="https://hitscounter.dev"><img src="https://hitscounter.dev/api/hit?url=https%3A%2F%2Fgithub.com%2Fdonaldzou%2FWGDashboard&label=Visitor&icon=github&color=%230a58ca"></a>
<img src="https://img.shields.io/docker/pulls/donaldzou/wgdashboard?logo=docker&label=Docker%20Image%20Pulls&labelColor=ffffff">
<a href="https://github.com/donaldzou/wireguard-dashboard/releases/latest"><img src="https://img.shields.io/github/v/release/donaldzou/wireguard-dashboard?style=for-the-badge"></a>
<a href="https://wakatime.com/badge/github/donaldzou/WGDashboard"><img src="https://wakatime.com/badge/github/donaldzou/WGDashboard.svg?style=for-the-badge" alt="wakatime"></a>
<a href="https://hitscounter.dev"><img src="https://hitscounter.dev/api/hit?url=https%3A%2F%2Fgithub.com%2Fdonaldzou%2FWGDashboard&label=Visitor&icon=github&color=%230a58ca&style=for-the-badge"></a>
<img src="https://img.shields.io/docker/pulls/donaldzou/wgdashboard?logo=docker&label=Docker%20Image%20Pulls&labelColor=ffffff&style=for-the-badge">
</p>
<p align="center"><b>This project is supported by</b></p>
<p align="center">
@@ -37,31 +38,40 @@
<p align="center"><b><i>This project is not affiliate to the official WireGuard Project</i></b></p>
<h3 align="center">Looking for help or want to chat about this project?</h4>
<p align="center">
Join our Discord Server for quick help, or you wanna chat about this project!
You can reach out at
</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>
<a align="center" href="https://discord.gg/72TwzjeuWm" target="_blank"><img src="https://img.shields.io/discord/1276818723637956628?labelColor=ffffff&style=for-the-badge&logo=discord&label=Discord"></a>
<a align="center" href="https://www.reddit.com/r/WGDashboard/" target="_blank"><img src="https://img.shields.io/badge/Reddit-r%2FWGDashboard-FF4500?style=for-the-badge&logo=reddit"></a>
<a align="center" href="https://app.element.io/#/room/#wgd:matrix.org" target="_blank"><img src="https://img.shields.io/badge/Matrix_Chatroom-%23WGD-000000?style=for-the-badge&logo=matrix"></a>
</p>
<h3 align="center">Want to support this project?</h4>
<p align="center">
You can support via <br>
</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>
<a align="center" href="https://github.com/sponsors/donaldzou" target="_blank"><img src="https://img.shields.io/badge/GitHub%20Sponsor-2e9a40?style=for-the-badge&logo=github"></a>
<a align="center" href="https://buymeacoffee.com/donaldzou" target="_blank"><img src="https://img.shields.io/badge/Buy%20me%20a%20coffee-ffdd00?style=for-the-badge&logo=buymeacoffee&logoColor=000000"></a>
<a align="center" href="https://patreon.com/c/DonaldDonnyZou/membership" target="_blank"><img src="https://img.shields.io/badge/Patreon-000000?style=for-the-badge&logo=patreon&logoColor=ffffff"></a>
</p>
<p align="center">
<b>or, visit our merch store and support us by purchasing a merch for only $USD 17.00 (Including shipping worldwide & duties)</b>
</p>
<p align="center">
<a align="center" href="https://merch.wgdashboard.dev" target="_blank"><img src="https://img.shields.io/badge/Merch%20from%20WGDashboard-926183?style=for-the-badge"></a>
</p>
<hr>
<h4 align="center">
for more information, visit our
</h4>
<h1 align="center">
<a href="https://wgdashboard.dev">Official Website</a>
</h1>
# [Official Documentation](https://donaldzou.dev/WGDashboard-Documentations)
- [💡 Features](https://donaldzou.github.io/WGDashboard-Documentation/features.html)
- [📝 Requirements](https://donaldzou.github.io/WGDashboard-Documentation/requirements.html)
- [🛠 Install](https://donaldzou.github.io/WGDashboard-Documentation/install.html)
- [🪜 Usage](https://donaldzou.github.io/WGDashboard-Documentation/usage.html)
- [📖 API Documentation](https://donaldzou.github.io/WGDashboard-Documentation/api-documentation.html)
- [And much more...](https://donaldzou.github.io/WGDashboard-Documentation/)
# Screenshots
+27 -41
View File
@@ -1,58 +1,44 @@
FROM golang:1.23 AS compiler
WORKDIR /go
FROM golang:1.24 AS awg-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 https://github.com/WGDashboard/amneziawg-go /awg
WORKDIR /awg
RUN go mod download && \
go mod verify && \
go build -ldflags '-linkmode external -extldflags "-fno-PIC -static"' -v -o /usr/bin
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
FROM alpine:latest AS awg-tools
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"
RUN apk update && apk add --no-cache \
make git build-base linux-headers \
&& git clone https://github.com/WGDashboard/amneziawg-tools \
&& cd amneziawg-tools/src \
&& make \
&& chmod +x wg*
### 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
RUN apk update && apk add --no-cache \
iproute2 iptables bash curl wget unzip procps sudo \
tzdata wireguard-tools python3 py3-psutil py3-bcrypt openresolv
COPY --from=awg-go /usr/bin/amneziawg-go /usr/bin/amneziawg-go
COPY --from=awg-tools /amneziawg-tools/src/wg /usr/bin/awg
COPY --from=awg-tools /amneziawg-tools/src/wg-quick/linux.bash /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"
ARG wg_net="10.0.0.1" \
wg_port="51820"
# Following ENV variables are changable on container runtime because /entrypoint.sh handles that. See compose.yaml for more info.
ENV TZ="Europe/Amsterdam"
ENV global_dns="1.1.1.1"
ENV isolate="none"
ENV public_ip=""
ENV wgd_port="10086"
# Doing package management operations, such as upgrading
RUN apk update \
&& apk add --no-cache bash git tzdata \
iptables ip6tables openrc curl wireguard-tools \
sudo py3-psutil py3-bcrypt \
&& apk upgrade
ENV TZ="Europe/Amsterdam" \
global_dns="9.9.9.9" \
wgd_port="10086" \
public_ip=""
# Using WGDASH -- like wg_net functionally as a ARG command. But it is needed in entrypoint.sh so it needs to be exported as environment variable.
ENV WGDASH=/opt/wgdashboard
# Removing the Linux Image package to preserve space on the image, for this reason also deleting apt lists, to be able to install packages: run apt update.
# Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example.
RUN mkdir /data \
&& mkdir /configs \
@@ -81,7 +67,7 @@ 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
+136 -48
View File
@@ -1,39 +1,59 @@
# WGDashboard Docker Explanation:
Author: DaanSelen<br>
Author: @DaanSelen<br>
This document delves into how the WGDashboard Docker container has been built.<br>
Of course there are two stages, one before run-time and one at/after run-time.<br>
Of course there are two stages (simply said), one before run-time and one at/after run-time.<br>
The `Dockerfile` describes how the container image is made, and the `entrypoint.sh` is executed after running the container. <br>
In this example, WireGuard is integrated into the container itself, so it should be a run-and-go/out-of-the-box.<br>
In this example, WireGuard is integrated into the container itself, so it should be a run-and-go(/out-of-the-box).<br>
For more details on the source-code specific to this Docker image, refer to the source files, they have lots of comments.
I have tried to embed some new features such as `isolate` and interface startup on container-start (through `enable`). I hope you enjoy!
<br>
<img
src="https://wgdashboard-resources.tor1.cdn.digitaloceanspaces.com/Logos/Logo-2-Rounded-512x512.png"
alt="WG-Dashboard Logo"
title="WG-Dashboard Logo"
style="display: block; margin: 0 auto;"
width="150"
height="150"
/>
<br>
<img src="https://raw.githubusercontent.com/donaldzou/WGDashboard/main/src/static/img/logo.png" alt="WG-Dashboard Logo" title="WG-Dashboard Logo" width="150" height="150" />
## Getting the container running:
To get the container running you either pull the image from the repository, `donaldzou/wgdashboard:latest`.<br>
To get the container running you either pull the image from the repository, (docker.io)`donaldzou/wgdashboard:latest`.<br>
From there either use the environment variables describe below as parameters or use the Docker Compose file: `compose.yaml`.<br>
Be careful, the default generated WireGuard configuration file uses port 51820/udp. So use this port if you want to use it out of the box.<br>
Otherwise edit the configuration file in `/etc/wireguard/wg0.conf`.
An example of a simple command to get the container running is show below:<br>
# WGDashboard: 🐳 Docker Deployment Guide
```shell
To run the container, you can either pull the image from Docker Hub or build it yourself. The image is available at:
```
docker.io/donaldzou/wgdashboard:latest
```
> `docker.io` is in most cases automatically resolved by the Docker application.
### 🔧 Quick Docker Run Command
Here's an example to get it up and running quickly:
```bash
docker run -d \
--name wgdashboard \
--restart unless-stopped \
-e enable=wg0 \
-e isolate=wg0 \
-p 10086:10086/tcp \
-p 51820:51820/udp \
--cap-add NET_ADMIN \
donaldzou/wgdashboard:latest
```
<br>
If you want to use Compose instead of a raw Docker command, refer to the example in the `compose.yaml` or the one pasted below:
<br><br>
> ⚠️ The default WireGuard port is `51820/udp`. If you change this, update the `/etc/wireguard/wg0.conf` accordingly.
---
### 📦 Docker Compose Alternative
You can also use Docker Compose for easier configuration:
```yaml
services:
@@ -42,11 +62,9 @@ services:
restart: unless-stopped
container_name: wgdashboard
environment:
#- tz=
#- global_dns=
#- enable=
#- isolate=
#- public_ip=
# - tz=Europe/Amsterdam
# - global_dns=1.1.1.1
# - public_ip=YOUR_PUBLIC_IP
ports:
- 10086:10086/tcp
- 51820:51820/udp
@@ -59,51 +77,121 @@ services:
volumes:
conf:
data:
```
If you want to customize the yaml, make sure the core stays the same, but for example volume PATHs (ON THE HOST) can be freely changed.<br>
This setup is just generic and will use the Docker volumes.
> 📁 You can customize the **volume paths** on the host to fit your needs. The example above uses Docker volumes.
## Updating the container:
---
Updating is right now in Alpha stage. I have got it to work, testing methods.
## 🔄 Updating the Container
## Working with the container and environment variables:
Updating WGDashboard is currently in **alpha** stage. While the update process may work, it's still under testing.
Once the container is running, the installation process is essentially the same as running it on bare-metal.<br>
So go to the assign TCP port in this case HTTP, like the default 10086 one in the example and log into the WEB-GUI.<br>
---
| Environment variable | Accepted arguments | Default value | Example value | Verbose |
| -------------- | ------- | ------- | ------- | ------- |
| tz | Europe/Amsterdam or any confirming timezone notation. | `Europe/Amsterdam` | `America/New_York` | Sets the timezone of the Docker container. This is to timesync the container to any other processes which would need it. |
| global_dns | Any IPv4 address, such as my personal recommendation: 9.9.9.9 (QUAD9). | `1.1.1.1` | `8.8.8.8` or any IP-Address that resolves DNS-names, and of course is reachable | Set the default DNS given to clients once they connect to the WireGuard tunnel, and for new peers, set to Cloudflare DNS for reliability.
| enable | Anything, preferably an existing WireGuard interface name. | `none` | `wg0,wg2,wg13` | Enables or disables the starting of the WireGuard interface on container 'boot-up'.
| isolate | Anything, preferably an existing WireGuard interface name. | `none` | `wg1,wg0` | The Wireguard interface itself IS able to reach the peers (Done through the `iptables` package).
| public_ip | Any IPv4 (public recommended) address, such as the one returned by default | Default uses the return of `curl ifconfig.me` | `89.20.83.118` | To reach your VPN from outside your own network, you need WG-Dashboard to know what your public IP-address is, otherwise it will generate faulty config files for clients. This happends because it is inside a Docker/Kubernetes container. In or outside of NAT is not relevant as long as the given IP-address is reachable from the internet or the target network.
## ⚙️ Environment Variables
## Be careful with:
| Variable | Accepted Values | Default | Example | Description |
|---------------|------------------------------------------|-------------------------|------------------------|-----------------------------------------------------------------------------|
| `tz` | Timezone | `Europe/Amsterdam` | `America/New_York` | Sets the container's timezone. Useful for accurate logs and scheduling. |
| `global_dns` | IPv4 and IPv6 addresses | `9.9.9.9` | `8.8.8.8`, `1.1.1.1` | Default DNS for WireGuard clients. |
| `public_ip` | Public IP address | Retrieved automatically | `253.162.134.73` | Used to generate accurate client configs. Needed if container is NATd. |
| `wgd_port` | Any port that is allowed for the process | `10086` | `443` | This port is used to set the WGDashboard web port. |
When you are going to work with multiple WireGuard interfaces, you need to also open them up to the Docker host. This done by either adding the port mappings like: `51821:51821/udp` in the Docker Compose file, or to open a range like: `51820-51830:51820-51830/udp`<br>
The latter opens up UDP ports from 51820 to 51830, so all ports in between as well! Be careful, it is good security practise to open only needed ports!
---
## Building the image yourself:
## 🔐 Port Forwarding Note
To build the image yourself, you need to do a couple things:<br>
1. Clone the Github repository containing the source code of WGDashboard including the docker directory. For example do: `git clone https://github.com/donaldzou/WGDashboard.git`
1. Navigate into the cloned repository.
1. (Make sure you have Docker correctly installed, if not: [Click here](https://docs.docker.com/engine/install/)) and run: `docker build . -t <Image name>:<Image tag>` as an example: `docker build . -t dselen/wgdashboard:latest`.<br>
When using multiple WireGuard interfaces, remember to **open their respective ports** on the host.
This will make Docker compile the image from the resources in the directory you mention, in this case the source/root one. Let it compile, it takes only a couple seconds with a minute at most.
Examples:
```yaml
# Individual mapping
- 51821:51821/udp
1. If all went well, see your image with `docker images`. Example below:
# Or port range
- 51820-51830:51820-51830/udp
```
> 🚨 **Security Tip:** Only expose ports you actually use.
---
## 🛠️ Building the Image Yourself
To build from source:
```bash
git clone https://github.com/donaldzou/WGDashboard.git
cd WGDashboard
docker build . -f docker/Dockerfile -t yourname/wgdashboard:latest
```
Example output:
```shell
dselen@dev-mach:~/development/WGDashboard/docker$ docker images
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dselen/wgdashboard latest c96fd96ee3b3 42 minutes ago 314MB
yourname/wgdashboard latest c96fd96ee3b3 42 minutes ago 314MB
```
---
## 🧱 Dockerfile Overview
Here's a brief overview of the Dockerfile stages used in the image build:
### 1. **Build Tools & Go Compilation**
```Dockerfile
FROM golang:1.24 AS compiler
WORKDIR /go
RUN apt-get update && apt-get install -y ...
RUN git clone ... && make
...
```
### 2. **Binary Copy to Scratch**
```Dockerfile
FROM scratch AS bins
COPY --from=compiler /go/amneziawg-go/amneziawg-go /amneziawg-go
...
```
### 3. **Final Alpine Container Setup**
```Dockerfile
FROM alpine:latest
COPY --from=bins ...
RUN apk update && apk add --no-cache ...
COPY ./src ${WGDASH}/src
COPY ./docker/entrypoint.sh /entrypoint.sh
...
EXPOSE 10086
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
```
---
## 🚀 Entrypoint Overview
### Major Functions:
- **`ensure_installation`**: Sets up the app, database, and Python environment.
- **`set_envvars`**: Writes `wg-dashboard.ini` and applies environment variables.
- **`start_core`**: Starts the main WGDashboard service.
- **`ensure_blocking`**: Tails the error log to keep the container process alive.
---
## ✅ Final Notes
- Use `docker logs wgdashboard` for troubleshooting.
- Access the web interface via `http://your-ip:10086` (or whichever port you specified in the compose).
- The first time run will auto-generate WireGuard keys and configs (configs are generated from the template).
## Closing remarks:
For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.
+2 -2
View File
@@ -5,19 +5,19 @@ services:
container_name: wgdashboard
#environment:
#- tz= # <--- Set container timezone, default: Europe/Amsterdam.
#- global_dns= # <--- Set global DNS address, default: 1.1.1.1.
#- isolate= # <--- Set the interfaces that will disallow peer communication, default: 'none'.
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
#- wgd_port= # <--- Set the port WGDashboard will use for its web-server.
ports:
- 10086:10086/tcp
- 51820:51820/udp
volumes:
- aconf:/etc/amnezia/amneziawg
- conf:/etc/wireguard
- data:/data
cap_add:
- NET_ADMIN
volumes:
aconf:
conf:
data:
+34 -5
View File
@@ -7,7 +7,7 @@ trap 'stop_service' SIGTERM
stop_service() {
echo "[WGDashboard] Stopping WGDashboard..."
bash ./wgd.sh stop
/bin/bash ./wgd.sh stop
exit 0
}
@@ -18,51 +18,68 @@ ensure_installation() {
# When using a custom directory to store the files, this part moves over and makes sure the installation continues.
echo "Quick-installing..."
# Make the wgd.sh script executable.
chmod +x "${WGDASH}"/src/wgd.sh
cd "${WGDASH}"/src || exit
# Github issue: https://github.com/donaldzou/WGDashboard/issues/723
echo "Checking for stale pids..."
if [[ -f ${WGDASH}/src/gunicorn.pid ]]; then
echo "Found stale pid, removing..."
rm ${WGDASH}/src/gunicorn.pid
fi
# Removing clear shell command from the wgd.sh script to enhance docker logging.
echo "Removing clear command from wgd.sh for better Docker logging."
sed -i '/clear/d' ./wgd.sh
# Create the databases directory if it does not exist yet.
if [ ! -d "/data/db" ]; then
echo "Creating database dir"
mkdir /data/db
fi
# Linking the database on the persistent directory location to where WGDashboard expects.
if [ ! -d "${WGDASH}/src/db" ]; then
ln -s /data/db "${WGDASH}/src/db"
fi
# Create the wg-dashboard.ini file if it does not exist yet.
if [ ! -f "${config_file}" ]; then
echo "Creating wg-dashboard.ini file"
touch "${config_file}"
fi
# Link the wg-dashboard.ini file from the persistent directory to where WGDashboard expects it.
if [ ! -f "${WGDASH}/src/wg-dashboard.ini" ]; then
ln -s "${config_file}" "${WGDASH}/src/wg-dashboard.ini"
fi
# Create the Python virtual environment.
python3 -m venv "${WGDASH}"/src/venv
. "${WGDASH}/src/venv/bin/activate"
# Due to this pip dependency being available as a system package we can just move it to the venv.
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
# Due to this pip dependency being available as a system package we can just move it to the venv.
echo "Moving PIP dependency from ephemerality to runtime environment: bcrypt"
mv /usr/lib/python3.12/site-packages/bcrypt* "${WGDASH}"/src/venv/lib/python3.12/site-packages
./wgd.sh install
# Use the bash interpreter to install WGDashboard according to the wgd.sh script.
/bin/bash ./wgd.sh install
echo "Looks like the installation succeeded. Moving on."
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage.
# This is done so WGDashboard it works out of the box
# This is done so WGDashboard it works out of the box, it also sets a randomly generated private key.
if [ ! -f "/etc/wireguard/wg0.conf" ]; then
echo "Standard wg0 Configuration file not found, grabbing template."
cp -a "/configs/wg0.conf.template" "/etc/wireguard/wg0.conf"
echo "Setting a secure private key." # SORRY 4 BE4 - Daan
echo "Setting a secure private key."
local privateKey
privateKey=$(wg genkey)
@@ -106,6 +123,7 @@ set_envvars() {
sed -i "s/^peer_global_dns = .*/peer_global_dns = ${global_dns}/" "${config_file}"
fi
# Checking the current set public IP and changing it if it has changed.
current_public_ip=$(grep "remote_endpoint = " "${config_file}" | awk '{print $NF}')
if [ "${public_ip}" == "" ]; then
default_ip=$(curl -s ifconfig.me)
@@ -118,6 +136,7 @@ set_envvars() {
echo "Public-IP is correct, moving on."
fi
# Checking the current WGDashboard web port and changing if needed.
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."
@@ -131,11 +150,18 @@ set_envvars() {
start_core() {
printf "\n---------------------- STARTING CORE -----------------------\n"
# Due to some instances complaining about this, making sure its there every time.
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
chmod 600 /dev/net/tun
# Actually starting WGDashboard
echo "Activating Python venv and executing the WireGuard Dashboard service."
bash ./wgd.sh start
/bin/bash ./wgd.sh start
}
ensure_blocking() {
# Wait a second before continuing, to give the python program some time to get ready.
sleep 1s
echo -e "\nEnsuring container continuation."
@@ -147,9 +173,12 @@ ensure_blocking() {
# Only tail the logs if they are found
if [ -n "$latestErrLog" ]; then
tail -f "$latestErrLog" &
# Wait for the tail process to end.
wait $!
else
echo "No log files found to tail. Something went wrong, exiting..."
exit 1
fi
}
+43 -31
View File
@@ -25,7 +25,7 @@ from modules.PeerJob import PeerJob
from modules.SystemStatus import SystemStatus
SystemStatus = SystemStatus()
DASHBOARD_VERSION = 'v4.2.0'
DASHBOARD_VERSION = 'v4.2.5'
CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
DB_PATH = os.path.join(CONFIGURATION_PATH, 'db')
@@ -180,6 +180,7 @@ class PeerJobs:
def runJob(self):
needToDelete = []
self.__getJobs()
for job in self.Jobs:
c = WireguardConfigurations.get(job.Configuration)
if c is not None:
@@ -432,7 +433,6 @@ class WireguardConfiguration:
original = [l.rstrip("\n") for l in f.readlines()]
try:
start = original.index("[Interface]")
# Clean
for i in range(start, len(original)):
if original[i] == "[Peer]":
@@ -459,7 +459,10 @@ class WireguardConfiguration:
setattr(self, key, StringToBoolean(value))
else:
if len(getattr(self, key)) > 0:
if key not in ["PostUp", "PostDown", "PreUp", "PreDown"]:
setattr(self, key, f"{getattr(self, key)}, {value}")
else:
setattr(self, key, f"{getattr(self, key)}; {value}")
else:
setattr(self, key, value)
except ValueError as e:
@@ -470,11 +473,12 @@ class WireguardConfiguration:
self.Status = self.getStatus()
def __dropDatabase(self):
existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
existingTables = [self.Name, f'{self.Name}_restrict_access', f'{self.Name}_transfer', f'{self.Name}_deleted']
# existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
for t in existingTables:
sqlUpdate("DROP TABLE '%s'" % t['name'])
sqlUpdate("DROP TABLE '%s'" % t)
existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
# existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
def createDatabase(self, dbName = None):
if dbName is None:
@@ -805,6 +809,9 @@ class WireguardConfiguration:
self.getPeers()
if numOfDeletedPeers == 0 and numOfFailedToDeletePeers == 0:
return ResponseObject(False, "No peer(s) to delete found", responseCode=404)
if numOfDeletedPeers == len(listOfPublicKeys):
return ResponseObject(True, f"Deleted {numOfDeletedPeers} peer(s)")
return ResponseObject(False,
@@ -945,7 +952,8 @@ class WireguardConfiguration:
},
"ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))),
"TotalPeers": len(self.Peers),
"Protocol": self.Protocol
"Protocol": self.Protocol,
"Table": self.Table,
}
def backupConfigurationFile(self) -> tuple[bool, dict[str, str]]:
@@ -1047,7 +1055,7 @@ class WireguardConfiguration:
dataChanged = False
with open(self.configPath, 'r') as f:
original = [l.rstrip("\n") for l in f.readlines()]
allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort"]
allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort", "Table"]
if self.Protocol == 'awg':
allowEdit += ["Jc", "Jmin", "Jmax", "S1", "S2", "H1", "H2", "H3", "H4"]
start = original.index("[Interface]")
@@ -1204,15 +1212,15 @@ AmneziaWG Configuration
"""
class AmneziaWireguardConfiguration(WireguardConfiguration):
def __init__(self, name: str = None, data: dict = None, backup: dict = None, startup: bool = False):
self.Jc = 0
self.Jmin = 0
self.Jmax = 0
self.S1 = 0
self.S2 = 0
self.H1 = 1
self.H2 = 2
self.H3 = 3
self.H4 = 4
self.Jc = ""
self.Jmin = ""
self.Jmax = ""
self.S1 = ""
self.S2 = ""
self.H1 = ""
self.H2 = ""
self.H3 = ""
self.H4 = ""
super().__init__(name, data, backup, startup, wg=False)
@@ -1237,6 +1245,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
},
"ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))),
"TotalPeers": len(self.Peers),
"Table": self.Table,
"Protocol": self.Protocol,
"Jc": self.Jc,
"Jmin": self.Jmin,
@@ -1434,7 +1443,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
f.write(p['preshared_key'])
subprocess.check_output(
f"{self.Protocol} set {self.Name} peer {p['id']} allowed-ips {p['allowed_ip'].replace(' ', '')}{f' preshared-key {uid}' if presharedKeyExist else ''} advanced-security {p['advanced_security']}",
f"{self.Protocol} set {self.Name} peer {p['id']} allowed-ips {p['allowed_ip'].replace(' ', '')}{f' preshared-key {uid}' if presharedKeyExist else ''}",
shell=True, stderr=subprocess.STDOUT)
if presharedKeyExist:
os.remove(uid)
@@ -1713,7 +1722,7 @@ PersistentKeepalive = {str(self.keepalive)}
f.write(preshared_key)
newAllowedIPs = allowed_ip.replace(" ", "")
updateAllowedIp = subprocess.check_output(
f"{self.configuration.Protocol} set {self.configuration.Name} peer {self.id} allowed-ips {newAllowedIPs} {f'preshared-key {uid}' if pskExist else 'preshared-key /dev/null'} advanced-security {advanced_security}",
f"{self.configuration.Protocol} set {self.configuration.Name} peer {self.id} allowed-ips {newAllowedIPs} {f'preshared-key {uid}' if pskExist else 'preshared-key /dev/null'}",
shell=True, stderr=subprocess.STDOUT)
if pskExist: os.remove(uid)
@@ -1756,7 +1765,7 @@ class DashboardConfig:
def __init__(self):
if not os.path.exists(DASHBOARD_CONF):
open(DASHBOARD_CONF, "x")
self.__config = configparser.ConfigParser(strict=False)
self.__config = configparser.RawConfigParser(strict=False)
self.__config.read_file(open(DASHBOARD_CONF, "r+"))
self.hiddenAttribute = ["totp_key", "auth_req"]
self.__default = {
@@ -1905,7 +1914,7 @@ class DashboardConfig:
return False, "Section does not exist"
if ((key not in self.__config[section].keys() and init) or
(key in self.__config[section].keys() and value != self.__config[section][key] and not init)):
(key in self.__config[section].keys())):
if type(value) is bool:
if value:
self.__config[section][key] = "true"
@@ -2042,7 +2051,7 @@ def auth_req():
else:
DashboardConfig.APIAccessed = False
whiteList = [
'/static/', 'validateAuthentication', 'authenticate', 'getDashboardConfiguration',
'/static/', 'validateAuthentication', 'authenticate',
'getDashboardTheme', 'getDashboardVersion', 'sharePeer/get', 'isTotpEnabled', 'locale',
'/fileDownload'
]
@@ -2180,7 +2189,7 @@ def API_addWireguardConfiguration():
WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data) if data.get('Protocol') == 'wg' else AmneziaWireguardConfiguration(data=data)
return ResponseObject()
@app.get(f'{APP_PREFIX}/api/toggleWireguardConfiguration/')
@app.get(f'{APP_PREFIX}/api/toggleWireguardConfiguration')
def API_toggleWireguardConfiguration():
configurationName = request.args.get('configurationName')
if configurationName is None or len(
@@ -2373,7 +2382,7 @@ def API_updateDashboardConfigurationItem():
valid, msg = DashboardConfig.SetConfig(
data["section"], data["key"], data['value'])
if not valid:
return ResponseObject(False, msg, status_code=404)
return ResponseObject(False, msg)
if data['section'] == "Server":
if data['key'] == 'wg_conf_path':
WireguardConfigurations.clear()
@@ -2434,7 +2443,7 @@ def API_updatePeerSettings(configName):
allowed_ip, endpoint_allowed_ip, mtu, keepalive)
return peer.updatePeer(name, private_key, preshared_key, dns_addresses,
allowed_ip, endpoint_allowed_ip, mtu, keepalive, data.get('advanced_security', 'off'))
allowed_ip, endpoint_allowed_ip, mtu, keepalive, "off")
return ResponseObject(False, "Peer does not exist")
@@ -2463,11 +2472,11 @@ def API_deletePeers(configName: str) -> ResponseObject:
peers = data['peers']
if configName in WireguardConfigurations.keys():
if len(peers) == 0:
return ResponseObject(False, "Please specify one or more peers")
return ResponseObject(False, "Please specify one or more peers", status_code=400)
configuration = WireguardConfigurations.get(configName)
return configuration.deletePeers(peers)
return ResponseObject(False, "Configuration does not exist")
return ResponseObject(False, "Configuration does not exist", status_code=404)
@app.post(f'{APP_PREFIX}/api/restrictPeers/<configName>')
def API_restrictPeers(configName: str) -> ResponseObject:
@@ -2604,7 +2613,7 @@ def API_addPeers(configName):
"endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": mtu,
"keepalive": keep_alive,
"advanced_security": data.get("advanced_security", "off")
"advanced_security": "off"
})
if addedCount == bulkAddAmount:
break
@@ -2674,7 +2683,7 @@ def API_addPeers(configName):
"DNS": dns_addresses,
"mtu": mtu,
"keepalive": keep_alive,
"advanced_security": data.get("advanced_security", "off")
"advanced_security": "off"
}]
)
return ResponseObject(status=status, message=result['message'], data=result['peers'])
@@ -2952,7 +2961,7 @@ def API_isTotpEnabled():
@app.get(f'{APP_PREFIX}/api/Welcome_GetTotpLink')
def API_Welcome_GetTotpLink():
if not DashboardConfig.GetConfig("Account", "totp_verified")[1]:
DashboardConfig.SetConfig("Account", "totp_key", pyotp.random_base32())
DashboardConfig.SetConfig("Account", "totp_key", pyotp.random_base32(), True)
return ResponseObject(
data=pyotp.totp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).provisioning_uri(
issuer_name="WGDashboard"))
@@ -3106,9 +3115,12 @@ def peerInformationBackgroundThread():
time.sleep(10)
while True:
with app.app_context():
for c in WireguardConfigurations.values():
if c.getStatus():
try:
curKeys = list(WireguardConfigurations.keys())
for name in curKeys:
if name in WireguardConfigurations.keys() and WireguardConfigurations.get(name) is not None:
c = WireguardConfigurations.get(name)
if c.getStatus():
c.getPeersTransfer()
c.getPeersLatestHandshake()
c.getPeersEndpoint()
+5 -6
View File
@@ -11,8 +11,8 @@ class EmailSender:
def __init__(self, DashboardConfig):
self.smtp = None
self.DashboardConfig = DashboardConfig
if not os.path.exists('../attachments'):
os.mkdir('../attachments')
if not os.path.exists('./attachments'):
os.mkdir('./attachments')
def Server(self):
return self.DashboardConfig.GetConfig("Email", "server")[1]
@@ -33,8 +33,7 @@ class EmailSender:
return self.DashboardConfig.GetConfig("Email", "send_from")[1]
def ready(self):
print(self.Server())
return len(self.Server()) > 0 and len(self.Port()) > 0 and len(self.Encryption()) > 0 and len(self.Username()) > 0 and len(self.Password()) > 0
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():
@@ -46,7 +45,7 @@ class EmailSender:
self.smtp.login(self.Username(), self.Password())
message = MIMEMultipart()
message['Subject'] = subject
message['From'] = formataddr((Header(self.SendFrom()).encode(), self.Username()))
message['From'] = self.SendFrom()
message["To"] = receiver
message.attach(MIMEText(body, "plain"))
@@ -62,7 +61,7 @@ class EmailSender:
else:
self.smtp.close()
return False, "Attachment does not exist"
self.smtp.sendmail(self.Username(), receiver, message.as_string())
self.smtp.sendmail(self.SendFrom(), receiver, message.as_string())
self.smtp.close()
return True, None
except Exception as e:
@@ -1 +1 @@
import{_ as r,c as i,d as o,w as e,k as l,a as t,j as _,i as a,l as d,S as u}from"./index-CUmHRwBw.js";const m={name:"configuration"},p={class:"mt-md-5 mt-3 text-body"};function f(k,x,h,w,$,v){const n=l("RouterView");return t(),i("div",p,[o(n,null,{default:e(({Component:s,route:c})=>[o(_,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(d(s),{key:c.path}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",f]]);export{B as default};
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-oBQzjt8-.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 @@
.fade-enter-active[data-v-6451623a]{transition-delay:var(--d75b06ae)!important}.progress-bar[data-v-c7f6d1a1]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.filter a[data-v-ea61b607]{text-decoration:none}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.fade-enter-active[data-v-dafd6275]{transition-delay:var(--7d032b58)!important}.progress-bar[data-v-851170e4]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.filter a[data-v-ea61b607]{text-decoration:none}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.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)}}}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.agentContainer[data-v-44ff028e]{--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),#F9464752 100%)}.agentContainer.enabled[data-v-44ff028e]{height:calc(var(--agentHeight) - 1rem)}@media screen and (max-width: 768px){.agentContainer[data-v-44ff028e]{--agentHeight: 100vh !important;top:0;left:0;max-height:calc(var(--agentHeight) - 58px - 1rem);width:calc(100% - 1rem)}}.agentChatroomBody[data-v-44ff028e]{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,4 +1,4 @@
import{P as Ws,Q as Vs,R as Ue,U as Hn,r as Wn,o as Vn,V as Nn,H as jn,X as Xe,Y as $n,Z as Ns}from"./index-CUmHRwBw.js";/*!
import{P as Ws,Q as Vs,R as Ue,U as Hn,r as Wn,o as Vn,V as Nn,H as jn,X as Xe,Y as $n,Z as Ns}from"./index-oBQzjt8-.js";/*!
* @kurkle/color v0.3.2
* https://github.com/kurkle/color#readme
* (c) 2023 Jukka Kurkela
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as e,G as t,a as o,c as a,t as c}from"./index-CUmHRwBw.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return o(),a("span",null,c(this.getLocaleText),1)}const u=e(s,[["render",n]]);export{u as L};
import{_ as e,G as t,a as o,c as a,t as c}from"./index-oBQzjt8-.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 +1 @@
import{L as l}from"./localeText-DvaqSAco.js";import{d as c}from"./dayjs.min-C3XPfvH9.js";import{_ as h,a as o,c as a,b as e,d as i,w as u,f as p,t as n,j as g,n as f,k as _}from"./index-CUmHRwBw.js";const x={name:"message",methods:{dayjs:c,hide(){this.ct(),this.message.show=!1},show(){this.timeout=setTimeout(()=>{this.message.show=!1},5e3)},ct(){clearTimeout(this.timeout)}},components:{LocaleText:l},props:{message:Object},mounted(){this.show()},data(){return{dismiss:!1,timeout:null}}},v=["id"],b={key:0,class:"d-flex"},w={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},y={class:"ms-auto"},k={key:1},T={class:"card-body d-flex align-items-center gap-3"};function M(j,s,C,L,t,m){const d=_("LocaleText");return o(),a("div",{onMouseenter:s[1]||(s[1]=r=>{t.dismiss=!0,this.ct()}),onMouseleave:s[2]||(s[2]=r=>{t.dismiss=!1,this.show()}),class:"card shadow rounded-3 position-relative message ms-auto",id:this.message.id},[e("div",{class:f([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[i(g,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(o(),a("div",k,[e("small",{onClick:s[0]||(s[0]=r=>m.hide()),class:"d-block mx-auto w-100 text-center",style:{cursor:"pointer"}},[s[3]||(s[3]=e("i",{class:"bi bi-x-lg me-2"},null,-1)),i(d,{t:"Dismiss"})])])):(o(),a("div",b,[e("small",w,[i(d,{t:"FROM "}),p(" "+n(this.message.from),1)]),e("small",y,n(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,n(this.message.content),1)])],40,v)}const z=h(x,[["render",M],["__scopeId","data-v-94c76b54"]]);export{z as M};
import{L as l}from"./localeText-CuybU_0U.js";import{d as c}from"./dayjs.min-BHDUvWAB.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-oBQzjt8-.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};
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.protocolBtnGroup a[data-v-b97242f3]{transition:all .2s ease-in-out}
@@ -1 +0,0 @@
.protocolBtnGroup a[data-v-b4bbbc2b]{transition:all .2s ease-in-out}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as v,D as g,r as o,o as h,J as x,g as y,a as i,c as n,b as s,d as c,n as w,e as C,w as k,j as F}from"./index-CUmHRwBw.js";import{L as T}from"./localeText-DvaqSAco.js";import"./browser-CjSdxGTc.js";const M={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},S={class:"container d-flex h-100 w-100"},D={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},P={class:"card rounded-3 shadow w-100"},j={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},B={class:"mb-0"},G={class:"card-body p-4 d-flex flex-column gap-3"},L={style:{height:"300px"},class:"d-flex"},N=["value"],V={key:0,class:"spinner-border m-auto",role:"status"},I={class:"d-flex"},W=["disabled"],$={key:0,class:"d-block"},q={key:1,class:"d-block",id:"check"},z={__name:"peerConfigurationFile",props:{selectedPeer:Object},emits:["close"],setup(u,{emit:p}){const m=p,f=u,r=g(),t=o(!1),l=o(""),a=o(!0);o({error:!1,message:void 0}),h(()=>{const d=x();y("/api/downloadPeer/"+d.params.id,{id:f.selectedPeer.id},e=>{e.status?(l.value=e.data.file,a.value=!1):this.dashboardStore.newMessage("Server",e.message,"danger")})});const b=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(l.value).then(()=>{t.value=!0,setTimeout(()=>{t.value=!1},3e3)}).catch(()=>{r.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(t.value=!0,setTimeout(()=>{t.value=!1},3e3)):r.newMessage("WGDashboard","Failed to copy","danger"))};return(d,e)=>(i(),n("div",M,[s("div",S,[s("div",D,[s("div",P,[s("div",j,[s("h4",B,[c(T,{t:"Peer Configuration File"})]),s("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=_=>m("close"))})]),s("div",G,[s("div",L,[s("textarea",{style:{height:"300px"},class:w(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,N),a.value?(i(),n("div",V,e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)]))):C("",!0)]),s("div",I,[s("button",{onClick:e[1]||(e[1]=_=>b()),disabled:t.value||a.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[c(F,{name:"slide-up",mode:"out-in"},{default:k(()=>[t.value?(i(),n("span",q,e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)]))):(i(),n("span",$,e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])))]),_:1})],8,W)])])])])])]))}},R=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{R as default};
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-oBQzjt8-.js";import{L as T}from"./localeText-CuybU_0U.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 +1 @@
import{S as p,a as b}from"./schedulePeerJob-Rx5QXWIx.js";import{_ as h,W as u,z as m,k as i,a as o,c as a,b as e,d as r,w as _,F as v,h as f,i as J,e as x,T as g}from"./index-CUmHRwBw.js";import{L as w}from"./localeText-DvaqSAco.js";import"./vue-datepicker-CUbRHf9G.js";import"./dayjs.min-C3XPfvH9.js";const P={name:"peerJobs",setup(){return{store:u()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:p,ScheduleDropdown:b},data(){return{}},methods:{deleteJob(d){this.selectedPeer.jobs=this.selectedPeer.jobs.filter(t=>t.JobID!==d.JobID)},addJob(){this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({JobID:m().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},k={class:"mb-0 fw-normal"},j={class:"card-body px-4 pb-4 pt-2 position-relative"},T={class:"d-flex align-items-center mb-3"},N={class:"card shadow-sm",key:"none",style:{height:"153px"}},I={class:"card-body text-muted text-center d-flex"},L={class:"m-auto"};function O(d,t,B,F,V,A){const n=i("LocaleText"),l=i("SchedulePeerJob");return o(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",k,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=s=>this.$emit("close"))})]),e("div",j,[e("div",T,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow",onClick:t[1]||(t[1]=s=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(g,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:_(()=>[(o(!0),a(v,null,f(this.selectedPeer.jobs,(s,E)=>(o(),J(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(s),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:s.JobID,pjob:s},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(o(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):x("",!0)]),_:1})])])])])])}const q=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{q as default};
import{S as p,a as b}from"./schedulePeerJob-D7M0MV7j.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-oBQzjt8-.js";import{L as w}from"./localeText-CuybU_0U.js";import"./vue-datepicker-DZRPqFzF.js";import"./dayjs.min-BHDUvWAB.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 +1 @@
import{S as _}from"./schedulePeerJob-Rx5QXWIx.js";import{_ as g,W as v,k as c,a as t,c as r,b as e,d as l,F as p,h as b,t as m,e as f,i as y}from"./index-CUmHRwBw.js";import{L as x}from"./localeText-DvaqSAco.js";import"./vue-datepicker-CUbRHf9G.js";import"./dayjs.min-C3XPfvH9.js";const J={name:"peerJobsAllModal",setup(){return{store:v()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},k={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},w={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},C={class:"card-body px-4 pb-4 pt-2"},P={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},j={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",k,[e("div",w,[e("div",$,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",C,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",P,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",j,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),y(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const U=g(J,[["render",W]]);export{U as default};
import{S as _}from"./schedulePeerJob-D7M0MV7j.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-oBQzjt8-.js";import{L as x}from"./localeText-CuybU_0U.js";import"./vue-datepicker-DZRPqFzF.js";import"./dayjs.min-BHDUvWAB.js";const J={name:"peerJobsAllModal",setup(){return{store:v()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},k={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},w={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},C={class:"card-body px-4 pb-4 pt-2"},P={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},j={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",k,[e("div",w,[e("div",$,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",C,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",P,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",j,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),y(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const U=g(J,[["render",W]]);export{U as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
@media screen and (max-width: 768px){#qrcode[data-v-7c287bf3]{width:100%!important;height:auto!important;aspect-ratio:1/1}}
+1
View File
@@ -0,0 +1 @@
import{b as i}from"./browser-CjSdxGTc.js";import{L as c}from"./localeText-CuybU_0U.js";import{_ as l,D as p,g as _,k as m,a as n,c as r,b as e,d as u,n as h,e as f}from"./index-oBQzjt8-.js";const g={name:"peerQRCode",components:{LocaleText:c},props:{selectedPeer:Object},setup(){return{dashboardStore:p()}},data(){return{loading:!0}},mounted(){_("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},o=>{if(this.loading=!1,o.status){let t="";if(this.selectedPeer.configuration.Protocol==="awg"){let a={containers:[{awg:{isThirdPartyConfig:!0,last_config:o.data.file,port:this.selectedPeer.configuration.ListenPort,transport_proto:"udp"},container:"amnezia-awg"}],defaultContainer:"amnezia-awg",description:this.selectedPeer.name,hostName:this.dashboardStore.Configuration.Peers.remote_endpoint};t=btoa(JSON.stringify(a))}else t=o.data.file;i.toCanvas(document.querySelector("#qrcode"),t,a=>{a&&console.error(a)})}else this.dashboardStore.newMessage("Server",o.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},v={class:"container d-flex h-100 w-100"},C={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},w={class:"card rounded-3 shadow"},P={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},x={class:"mb-0"},S={class:"card-body p-4"},y={class:"d-flex"},L={key:0,class:"spinner-border m-auto",role:"status"};function k(o,t,a,N,s,$){const d=m("LocaleText");return n(),r("div",b,[e("div",v,[e("div",C,[e("div",w,[e("div",P,[e("h4",x,[u(d,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=Q=>this.$emit("close"))})]),e("div",S,[e("div",y,[e("canvas",{id:"qrcode",class:h(["rounded-3 shadow animate__animated animate__fadeIn animate__faster",{"d-none":s.loading}])},null,2),s.loading?(n(),r("div",L,t[1]||(t[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)]))):f("",!0)])])])])])])}const q=l(g,[["render",k],["__scopeId","data-v-7c287bf3"]]);export{q as default};
-1
View File
@@ -1 +0,0 @@
import{b as r}from"./browser-CjSdxGTc.js";import{L as i}from"./localeText-DvaqSAco.js";import{_ as c,D as l,g as p,k as _,a,c as n,b as e,d as m,n as h,e as u}from"./index-CUmHRwBw.js";const f={name:"peerQRCode",components:{LocaleText:i},props:{selectedPeer:Object},setup(){return{dashboardStore:l()}},data(){return{loading:!0}},mounted(){p("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},t=>{this.loading=!1,t.status?r.toCanvas(document.querySelector("#qrcode"),t.data.file,s=>{s&&console.error(s)}):this.dashboardStore.newMessage("Server",t.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},g={class:"container d-flex h-100 w-100"},v={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},x={class:"card rounded-3 shadow"},C={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},w={class:"mb-0"},y={class:"card-body p-4"},S={style:{width:"292px",height:"292px"},class:"d-flex"},k={key:0,class:"spinner-border m-auto",role:"status"};function L(t,s,$,q,o,B){const d=_("LocaleText");return a(),n("div",b,[e("div",g,[e("div",v,[e("div",x,[e("div",C,[e("h4",w,[m(d,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:s[0]||(s[0]=N=>this.$emit("close"))})]),e("div",y,[e("div",S,[e("canvas",{id:"qrcode",class:h(["rounded-3 shadow animate__animated animate__fadeIn animate__faster",{"d-none":o.loading}])},null,2),o.loading?(a(),n("div",k,s[1]||(s[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)]))):u("",!0)])])])])])])}const T=c(f,[["render",L]]);export{T as default};
@@ -1 +1 @@
import{_ as u,q as m,G as p,r as b,W as f,a2 as h,o as g,a as v,i as y,w as _,b as e,m as x,y as w,d as S,j as B}from"./index-CUmHRwBw.js";import{L as T}from"./localeText-DvaqSAco.js";const C={class:"fixed-bottom w-100 bottom-0 z-2",style:{"z-index":"1"}},P={class:"container-fluid"},k={class:"row g-0"},L={class:"col-md-9 col-lg-10 d-flex justify-content-center py-2"},V={class:"rounded-3 p-2 border shadow searchPeersContainer bg-body-tertiary"},j={class:"d-flex gap-1 align-items-center px-2"},z=["placeholder"],D={__name:"peerSearchBar",emits:["close"],setup(G,{emit:n}){const l=m(()=>p("Search Peers..."));let t;const o=b(""),r=f(),i=()=>{t?(clearTimeout(t),t=setTimeout(()=>{r.searchString=o.value},300)):t=setTimeout(()=>{r.searchString=o.value},300)},d=n,c=h("searchBar");return g(()=>{c.value.focus()}),(M,s)=>(v(),y(B,{name:"slideUp",appear:"",type:"animation",style:{"animation-delay":"1s"}},{default:_(()=>[e("div",C,[e("div",P,[e("div",k,[s[5]||(s[5]=e("div",{class:"col-md-3 col-lg-2"},null,-1)),e("div",L,[e("div",V,[e("div",j,[s[4]||(s[4]=e("h6",{class:"mb-0 me-2"},[e("label",{for:"searchPeers"},[e("i",{class:"bi bi-search"})])],-1)),x(e("input",{ref:"searchBar",class:"flex-grow-1 form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:s[0]||(s[0]=a=>i()),"onUpdate:modelValue":s[1]||(s[1]=a=>o.value=a)},null,40,z),[[w,o.value]]),e("button",{onClick:s[2]||(s[2]=a=>d("close")),style:{"white-space":"nowrap"},class:"btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3 d-flex align-items-center"},[e("span",null,[s[3]||(s[3]=e("i",{class:"bi bi-x-circle-fill me-2"},null,-1)),S(T,{t:"Done"})])])])])])])])])]),_:1}))}},W=u(D,[["__scopeId","data-v-b741afe7"]]);export{W as default};
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-oBQzjt8-.js";import{L as T}from"./localeText-CuybU_0U.js";const C={class:"fixed-bottom w-100 bottom-0 z-2",style:{"z-index":"1"}},P={class:"container-fluid"},k={class:"row g-0"},L={class:"col-md-9 col-lg-10 d-flex justify-content-center py-2"},V={class:"rounded-3 p-2 border shadow searchPeersContainer bg-body-tertiary"},j={class:"d-flex gap-1 align-items-center px-2"},z=["placeholder"],D={__name:"peerSearchBar",emits:["close"],setup(G,{emit:n}){const l=m(()=>p("Search Peers..."));let t;const o=b(""),r=f(),i=()=>{t?(clearTimeout(t),t=setTimeout(()=>{r.searchString=o.value},300)):t=setTimeout(()=>{r.searchString=o.value},300)},d=n,c=h("searchBar");return g(()=>{c.value.focus()}),(M,s)=>(v(),y(B,{name:"slideUp",appear:"",type:"animation",style:{"animation-delay":"1s"}},{default:_(()=>[e("div",C,[e("div",P,[e("div",k,[s[5]||(s[5]=e("div",{class:"col-md-3 col-lg-2"},null,-1)),e("div",L,[e("div",V,[e("div",j,[s[4]||(s[4]=e("h6",{class:"mb-0 me-2"},[e("label",{for:"searchPeers"},[e("i",{class:"bi bi-search"})])],-1)),x(e("input",{ref:"searchBar",class:"flex-grow-1 form-control rounded-3 bg-secondary-subtle border-1 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:s[0]||(s[0]=a=>i()),"onUpdate:modelValue":s[1]||(s[1]=a=>o.value=a)},null,40,z),[[w,o.value]]),e("button",{onClick:s[2]||(s[2]=a=>d("close")),style:{"white-space":"nowrap"},class:"btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3 d-flex align-items-center"},[e("span",null,[s[3]||(s[3]=e("i",{class:"bi bi-x-circle-fill me-2"},null,-1)),S(T,{t:"Done"})])])])])])])])])]),_:1}))}},W=u(D,[["__scopeId","data-v-b741afe7"]]);export{W as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.toggleShowKey[data-v-12b3ae8e]{position:absolute;top:35px;right:12px}
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
.toggleShowKey[data-v-2166fcf9]{position:absolute;top:35px;right:12px}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{L as r}from"./localeText-DvaqSAco.js";import{a as t,c as n,f as i,i as s,e as a}from"./index-CUmHRwBw.js";const d={key:0,class:"badge wireguardBg rounded-3 shadow"},c={key:1,class:"badge amneziawgBg rounded-3 shadow"},u={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(e){return(m,o)=>e.protocol==="wg"?(t(),n("span",d,[o[0]||(o[0]=i(" WireGuard ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):e.protocol==="awg"?(t(),n("span",c,[o[1]||(o[1]=i(" AmneziaWG ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):a("",!0)}};export{u as _};
import{L as r}from"./localeText-CuybU_0U.js";import{a as t,c as n,f as i,i as s,e as a}from"./index-oBQzjt8-.js";const d={key:0,class:"badge wireguardBg rounded-3 shadow"},c={key:1,class:"badge amneziawgBg rounded-3 shadow"},u={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(e){return(m,o)=>e.protocol==="wg"?(t(),n("span",d,[o[0]||(o[0]=i(" WireGuard ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):e.protocol==="awg"?(t(),n("span",c,[o[1]||(o[1]=i(" AmneziaWG ")),e.mini?a("",!0):(t(),s(r,{key:0,t:"Configuration"}))])):a("",!0)}};export{u as _};
File diff suppressed because one or more lines are too long
@@ -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
@@ -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}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as u,D as m,A as p,c as r,b as e,d as o,f as c,t as h,e as f,m as l,y as d,a as i,k as w}from"./index-CUmHRwBw.js";import{L as g}from"./localeText-DvaqSAco.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:m()}},data(){return{setup:{username:"",newPassword:"",repeatNewPassword:"",enable_totp:!0},loading:!1,errorMessage:"",done:!1}},computed:{goodToSubmit(){return this.setup.username&&this.setup.newPassword.length>=8&&this.setup.repeatNewPassword.length>=8&&this.setup.newPassword===this.setup.repeatNewPassword}},methods:{submit(){this.loading=!0,p("/api/Welcome_Finish",this.setup,n=>{n.status?(this.done=!0,this.$router.push("/2FASetup")):(document.querySelectorAll("#createAccount input").forEach(s=>s.classList.add("is-invalid")),this.errorMessage=n.message,document.querySelector(".login-container-fluid").scrollTo({top:0,left:0,behavior:"smooth"})),this.loading=!1})}}},_=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},v={class:"dashboardLogo display-4"},y={class:"mb-5"},P={key:0,class:"alert alert-danger"},N={class:"d-flex flex-column gap-3"},k={id:"createAccount",class:"d-flex flex-column gap-2"},S={class:"form-group text-body"},T={for:"username",class:"mb-1 text-muted"},C={class:"form-group text-body"},L={for:"password",class:"mb-1 text-muted"},V={class:"form-group text-body"},A={for:"confirmPassword",class:"mb-1 text-muted"},$=["disabled"],q={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=w("LocaleText");return i(),r("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[e("div",x,[e("span",v,[o(t,{t:"Nice to meet you!"})]),e("p",y,[o(t,{t:"Please fill in the following fields to finish setup"}),s[4]||(s[4]=c(" 😊"))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):f("",!0),e("div",N,[e("form",k,[e("div",S,[e("label",T,[e("small",null,[o(t,{t:"Enter an username you like"})])]),l(e("input",{type:"text",autocomplete:"username","onUpdate:modelValue":s[0]||(s[0]=a=>this.setup.username=a),class:"form-control",id:"username",name:"username",required:""},null,512),[[d,this.setup.username]])]),e("div",C,[e("label",L,[e("small",null,[o(t,{t:"Enter a password"}),e("code",null,[o(t,{t:"(At least 8 characters and make sure is strong enough!)"})])])]),l(e("input",{type:"password",autocomplete:"new-password","onUpdate:modelValue":s[1]||(s[1]=a=>this.setup.newPassword=a),class:"form-control",id:"password",name:"password",required:""},null,512),[[d,this.setup.newPassword]])]),e("div",V,[e("label",A,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",q,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,$)])])])],8,_)}const j=u(b,[["render",B]]);export{j as default};
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-oBQzjt8-.js";import{L as g}from"./localeText-CuybU_0U.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,J as h,a as f,k as b}from"./index-CUmHRwBw.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-DvaqSAco.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=h(),e=r(!1),i=p(),n=r(""),s=r(void 0),l=r(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(s.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(s.value=d.data,l.value=new Blob([s.value.file],{type:"text/plain"})):s.value=void 0,e.value=!0}),{store:i,theme:n,peerConfiguration:s,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),i=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=i,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},w=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},I={class:"m-auto"},L={key:1,class:"d-flex align-items-center flex-column gap-3"},k={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},B={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},D={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},R=["download","href"];function q(o,e,i,n,s,l){const a=b("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",x,[this.peerConfiguration?(f(),m("div",L,[t("div",k,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),c(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",B,null,512),t("p",D,[c(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),c(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)]),8,R)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",I,[c(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,w)}const N=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{N as default};
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-oBQzjt8-.js";import{b as v}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-CuybU_0U.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=h(),e=r(!1),i=p(),n=r(""),s=r(void 0),l=r(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(s.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(s.value=d.data,l.value=new Blob([s.value.file],{type:"text/plain"})):s.value=void 0,e.value=!0}),{store:i,theme:n,peerConfiguration:s,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),i=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=i,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},w=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},I={class:"m-auto"},L={key:1,class:"d-flex align-items-center flex-column gap-3"},k={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},B={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},D={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},R=["download","href"];function q(o,e,i,n,s,l){const a=b("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",x,[this.peerConfiguration?(f(),m("div",L,[t("div",k,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),c(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",B,null,512),t("p",D,[c(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),c(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)]),8,R)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",I,[c(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,w)}const N=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{N as default};
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
.square[data-v-2ad535bb]{height:var(--2ec4d3bc);transition:background-color .5s cubic-bezier(.42,0,.22,1)}.square[data-v-9509d7a0]{height:var(--2dc8ab7e);transition:background-color .5s cubic-bezier(.42,0,.22,1)}
-1
View File
@@ -1 +0,0 @@
.square[data-v-70102637]{height:var(--e901480c);transition:background-color .5s cubic-bezier(.42,0,.22,1)}.floatingLabel[data-v-70102637]{top:40px}.square[data-v-a382214a]{height:var(--38705f32);transition:background-color .5s cubic-bezier(.42,0,.22,1)}.floatingLabel[data-v-a382214a]{top:var(--38705f32)}
@@ -0,0 +1 @@
import{_ as b,p as m,r as p,q as v,a as t,c as r,d as g,w as x,s as n,n as f,b as l,t as d,e as C,j as w}from"./index-oBQzjt8-.js";const y={class:"text-muted me-2"},_={class:"fw-bold"},k={__name:"cpuCore",props:{core_number:Number,percentage:Number,align:Boolean,square:Boolean},setup(e){m(c=>({"2ec4d3bc":o.value}));const u=e,s=p(!1),o=v(()=>u.square?"40px":"25px");return(c,a)=>(t(),r("div",{class:"flex-grow-1 square rounded-3 border position-relative p-2",onMouseenter:a[0]||(a[0]=i=>s.value=!0),onMouseleave:a[1]||(a[1]=i=>s.value=!1),style:n({"background-color":`rgb(13 110 253 / ${e.percentage*10}%)`})},[g(w,{name:"zoomReversed"},{default:x(()=>[s.value?(t(),r("div",{key:0,style:n([{"white-space":"nowrap"},{top:o.value}]),class:f(["floatingLabel z-3 border position-absolute d-block p-1 px-2 bg-body text-body rounded-3 border shadow d-flex",[e.align?"end-0":"start-0"]])},[l("small",y," Core #"+d(e.core_number+1),1),l("small",_,d(e.percentage)+"% ",1)],6)):C("",!0)]),_:1})],36))}},B=b(k,[["__scopeId","data-v-2ad535bb"]]);export{B as C};
@@ -1 +0,0 @@
import{_ as i,p as m,r as p,q as b,a as o,c as t,d as g,w as v,n as x,b as r,t as n,e as f,j as C,s as w}from"./index-CUmHRwBw.js";const y={class:"text-muted me-2"},_={class:"fw-bold"},k={__name:"cpuCore",props:{core_number:Number,percentage:Number,align:Boolean,square:Boolean},setup(e){m(c=>({e901480c:u.value}));const l=e,a=p(!1),u=b(()=>l.square?"40px":"25px");return(c,s)=>(o(),t("div",{class:"flex-grow-1 square rounded-3 border position-relative p-2",onMouseenter:s[0]||(s[0]=d=>a.value=!0),onMouseleave:s[1]||(s[1]=d=>a.value=!1),style:w({"background-color":`rgb(13 110 253 / ${e.percentage*10}%)`})},[g(C,{name:"zoomReversed"},{default:v(()=>[a.value?(o(),t("div",{key:0,style:{"white-space":"nowrap"},class:x(["floatingLabel z-3 border position-absolute d-block p-1 px-2 bg-body text-body rounded-3 border shadow d-flex",[e.align?"end-0":"start-0"]])},[r("small",y," Core #"+n(e.core_number+1),1),r("small",_,n(e.percentage)+"% ",1)],2)):f("",!0)]),_:1})],36))}},B=i(k,[["__scopeId","data-v-70102637"]]);export{B as C};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as h,D as m,g as p,A as f,c as b,b as t,d as i,t as _,m as v,y as g,i as d,w as r,k as c,a as n}from"./index-CUmHRwBw.js";import{b as x}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-DvaqSAco.js";const T={name:"totp",components:{LocaleText:y},async setup(){const s=m();let e="";return await p("/api/Welcome_GetTotpLink",{},a=>{a.status&&(e=a.data)}),{l:e,store:s}},mounted(){this.l&&x.toCanvas(document.getElementById("qrcode"),this.l,function(s){})},data(){return{totp:"",totpInvalidMessage:"",verified:!1}},methods:{validateTotp(){}},watch:{totp(s){const e=document.querySelector("#totp");e.classList.remove("is-invalid","is-valid"),s.length===6&&(console.log(s),/[0-9]{6}/.test(s)?f("/api/Welcome_VerifyTotpLink",{totp:s},a=>{a.status?(this.verified=!0,e.classList.add("is-valid"),this.$emit("verified")):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP does not match.")}):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP can only contain numbers"))}}},k=["data-bs-theme"],w={class:"m-auto text-body",style:{width:"500px"}},L={class:"d-flex flex-column"},M={class:"dashboardLogo display-4"},C={class:"mb-2"},P={class:"text-muted"},I={class:"p-3 bg-body-secondary rounded-3 border mb-3"},O={class:"text-muted mb-0"},B=["href"],$={style:{"line-break":"anywhere"}},A={for:"totp",class:"mb-2"},D={class:"text-muted"},S={class:"form-group mb-2"},q=["disabled"],E={class:"invalid-feedback"},F={class:"valid-feedback"},R={class:"d-flex gap-3 mt-5 flex-column"};function G(s,e,a,N,W,Q){const o=c("LocaleText"),l=c("RouterLink");return n(),b("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[t("div",w,[t("div",L,[t("div",null,[t("h1",M,[i(o,{t:"Multi-Factor Authentication (MFA)"})]),t("p",C,[t("small",P,[i(o,{t:"1. Please scan the following QR Code to generate TOTP with your choice of authenticator"})])]),e[1]||(e[1]=t("canvas",{id:"qrcode",class:"rounded-3 mb-2"},null,-1)),t("div",I,[t("p",O,[t("small",null,[i(o,{t:"Or you can click the link below:"})])]),t("a",{href:this.l},[t("code",$,_(this.l),1)],8,B)]),t("label",A,[t("small",D,[i(o,{t:"2. Enter the TOTP generated by your authenticator to verify"})])]),t("div",S,[v(t("input",{class:"form-control text-center totp",id:"totp",maxlength:"6",type:"text",inputmode:"numeric",autocomplete:"one-time-code","onUpdate:modelValue":e[0]||(e[0]=u=>this.totp=u),disabled:this.verified},null,8,q),[[g,this.totp]]),t("div",E,[i(o,{t:this.totpInvalidMessage},null,8,["t"])]),t("div",F,[i(o,{t:"TOTP verified!"})])])]),e[4]||(e[4]=t("hr",null,null,-1)),t("div",R,[this.verified?(n(),d(l,{key:1,to:"/",class:"btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3"},{default:r(()=>[i(o,{t:"Complete"}),e[3]||(e[3]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1})):(n(),d(l,{key:0,to:"/",class:"btn bg-secondary-subtle text-secondary-emphasis rounded-3 flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex"},{default:r(()=>[i(o,{t:"I don't need MFA"}),e[2]||(e[2]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1}))])])])],8,k)}const z=h(T,[["render",G]]);export{z as default};
import{_ as h,D as m,g as p,A as f,c as b,b as t,d as i,t as _,m as v,y as g,i as d,w as r,k as c,a as n}from"./index-oBQzjt8-.js";import{b as x}from"./browser-CjSdxGTc.js";import{L as y}from"./localeText-CuybU_0U.js";const T={name:"totp",components:{LocaleText:y},async setup(){const s=m();let e="";return await p("/api/Welcome_GetTotpLink",{},a=>{a.status&&(e=a.data)}),{l:e,store:s}},mounted(){this.l&&x.toCanvas(document.getElementById("qrcode"),this.l,function(s){})},data(){return{totp:"",totpInvalidMessage:"",verified:!1}},methods:{validateTotp(){}},watch:{totp(s){const e=document.querySelector("#totp");e.classList.remove("is-invalid","is-valid"),s.length===6&&(console.log(s),/[0-9]{6}/.test(s)?f("/api/Welcome_VerifyTotpLink",{totp:s},a=>{a.status?(this.verified=!0,e.classList.add("is-valid"),this.$emit("verified")):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP does not match.")}):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP can only contain numbers"))}}},k=["data-bs-theme"],w={class:"m-auto text-body",style:{width:"500px"}},L={class:"d-flex flex-column"},M={class:"dashboardLogo display-4"},C={class:"mb-2"},P={class:"text-muted"},I={class:"p-3 bg-body-secondary rounded-3 border mb-3"},O={class:"text-muted mb-0"},B=["href"],$={style:{"line-break":"anywhere"}},A={for:"totp",class:"mb-2"},D={class:"text-muted"},S={class:"form-group mb-2"},q=["disabled"],E={class:"invalid-feedback"},F={class:"valid-feedback"},R={class:"d-flex gap-3 mt-5 flex-column"};function G(s,e,a,N,W,Q){const o=c("LocaleText"),l=c("RouterLink");return n(),b("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[t("div",w,[t("div",L,[t("div",null,[t("h1",M,[i(o,{t:"Multi-Factor Authentication (MFA)"})]),t("p",C,[t("small",P,[i(o,{t:"1. Please scan the following QR Code to generate TOTP with your choice of authenticator"})])]),e[1]||(e[1]=t("canvas",{id:"qrcode",class:"rounded-3 mb-2"},null,-1)),t("div",I,[t("p",O,[t("small",null,[i(o,{t:"Or you can click the link below:"})])]),t("a",{href:this.l},[t("code",$,_(this.l),1)],8,B)]),t("label",A,[t("small",D,[i(o,{t:"2. Enter the TOTP generated by your authenticator to verify"})])]),t("div",S,[v(t("input",{class:"form-control text-center totp",id:"totp",maxlength:"6",type:"text",inputmode:"numeric",autocomplete:"one-time-code","onUpdate:modelValue":e[0]||(e[0]=u=>this.totp=u),disabled:this.verified},null,8,q),[[g,this.totp]]),t("div",E,[i(o,{t:this.totpInvalidMessage},null,8,["t"])]),t("div",F,[i(o,{t:"TOTP verified!"})])])]),e[4]||(e[4]=t("hr",null,null,-1)),t("div",R,[this.verified?(n(),d(l,{key:1,to:"/",class:"btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3"},{default:r(()=>[i(o,{t:"Complete"}),e[3]||(e[3]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1})):(n(),d(l,{key:0,to:"/",class:"btn bg-secondary-subtle text-secondary-emphasis rounded-3 flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex"},{default:r(()=>[i(o,{t:"I don't need MFA"}),e[2]||(e[2]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1}))])])])],8,k)}const z=h(T,[["render",G]]);export{z as default};
@@ -1 +1 @@
import{_ as h,W as g,g as b,c as o,b as t,d as n,m as y,y as f,C as x,w as r,j as c,a as l,f as v,F as u,h as m,n as k,s as T,t as i,k as _}from"./index-CUmHRwBw.js";import{O as A}from"./osmap-C861OkPV.js";import{L as w}from"./localeText-DvaqSAco.js";const R={name:"traceroute",components:{LocaleText:w,OSMap:A},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:g()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,b("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},M={class:"mt-md-5 mt-3 text-body"},S={class:"container-md"},$={class:"mb-3 text-body"},C={class:"d-flex gap-2 mb-3 flex-column"},L={class:"flex-grow-1"},P={class:"mb-1 text-muted",for:"ipAddress"},O=["disabled"],V=["disabled"],B={key:0,class:"d-block"},I={key:1,class:"d-block"},N={class:"position-relative"},z={key:"pingPlaceholder"},D={key:1},E={key:"table",class:"w-100 mt-2"},F={class:"table table-sm rounded-3 w-100"},G={scope:"col"},H={scope:"col"},K={scope:"col"},W={scope:"col"},j={scope:"col"},U={scope:"col"},q={key:0},J={key:1};function Q(d,s,X,Y,Z,tt){const a=_("LocaleText"),p=_("OSMap");return l(),o("div",M,[t("div",S,[t("h3",$,[n(a,{t:"Traceroute"})]),t("div",C,[t("div",L,[t("label",P,[t("small",null,[n(a,{t:"Enter IP Address / Hostname"})])]),y(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control rounded-3","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=x(e=>this.execute(),["enter"])),type:"text"},null,40,O),[[f,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 position-relative flex-grow-1",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(c,{name:"slide"},{default:r(()=>[this.tracing?(l(),o("span",I,s[4]||(s[4]=[t("span",{class:"spinner-border spinner-border-sm","aria-hidden":"true"},null,-1),t("span",{class:"visually-hidden",role:"status"},"Loading...",-1)]))):(l(),o("span",B,s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),v("Trace! ")])))]),_:1})],8,V)]),t("div",N,[n(c,{name:"ping"},{default:r(()=>[this.tracerouteResult?(l(),o("div",D,[n(p,{d:this.tracerouteResult,type:"traceroute"},null,8,["d"]),t("div",E,[t("table",F,[t("thead",null,[t("tr",null,[t("th",G,[n(a,{t:"Hop"})]),t("th",H,[n(a,{t:"IP Address"})]),t("th",K,[n(a,{t:"Average RTT (ms)"})]),t("th",W,[n(a,{t:"Min RTT (ms)"})]),t("th",j,[n(a,{t:"Max RTT (ms)"})]),t("th",U,[n(a,{t:"Geolocation"})])])]),t("tbody",null,[(l(!0),o(u,null,m(this.tracerouteResult,(e,et)=>(l(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,[t("samp",null,i(e.ip),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.avg_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.min_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.max_rtt),1)])]),t("td",null,[e.geo.city&&e.geo.country?(l(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):(l(),o("span",J," - "))])]))),256))])])])])):(l(),o("div",z,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(l(),o(u,null,m(5,e=>t("div",{class:k(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:T({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const lt=h(R,[["render",Q],["__scopeId","data-v-3e75b4d4"]]);export{lt as default};
import{_ as h,W as g,g as b,c as o,b as t,d as n,m as y,y as f,C as x,w as r,j as c,a as l,f as v,F as u,h as m,n as k,s as T,t as i,k as _}from"./index-oBQzjt8-.js";import{O as A}from"./osmap-DL0KYfmh.js";import{L as w}from"./localeText-CuybU_0U.js";const R={name:"traceroute",components:{LocaleText:w,OSMap:A},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:g()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,b("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},M={class:"mt-md-5 mt-3 text-body"},S={class:"container-md"},$={class:"mb-3 text-body"},C={class:"d-flex gap-2 mb-3 flex-column"},L={class:"flex-grow-1"},P={class:"mb-1 text-muted",for:"ipAddress"},O=["disabled"],V=["disabled"],B={key:0,class:"d-block"},I={key:1,class:"d-block"},N={class:"position-relative"},z={key:"pingPlaceholder"},D={key:1},E={key:"table",class:"w-100 mt-2"},F={class:"table table-sm rounded-3 w-100"},G={scope:"col"},H={scope:"col"},K={scope:"col"},W={scope:"col"},j={scope:"col"},U={scope:"col"},q={key:0},J={key:1};function Q(d,s,X,Y,Z,tt){const a=_("LocaleText"),p=_("OSMap");return l(),o("div",M,[t("div",S,[t("h3",$,[n(a,{t:"Traceroute"})]),t("div",C,[t("div",L,[t("label",P,[t("small",null,[n(a,{t:"Enter IP Address / Hostname"})])]),y(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control rounded-3","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=x(e=>this.execute(),["enter"])),type:"text"},null,40,O),[[f,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 position-relative flex-grow-1",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(c,{name:"slide"},{default:r(()=>[this.tracing?(l(),o("span",I,s[4]||(s[4]=[t("span",{class:"spinner-border spinner-border-sm","aria-hidden":"true"},null,-1),t("span",{class:"visually-hidden",role:"status"},"Loading...",-1)]))):(l(),o("span",B,s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),v("Trace! ")])))]),_:1})],8,V)]),t("div",N,[n(c,{name:"ping"},{default:r(()=>[this.tracerouteResult?(l(),o("div",D,[n(p,{d:this.tracerouteResult,type:"traceroute"},null,8,["d"]),t("div",E,[t("table",F,[t("thead",null,[t("tr",null,[t("th",G,[n(a,{t:"Hop"})]),t("th",H,[n(a,{t:"IP Address"})]),t("th",K,[n(a,{t:"Average RTT (ms)"})]),t("th",W,[n(a,{t:"Min RTT (ms)"})]),t("th",j,[n(a,{t:"Max RTT (ms)"})]),t("th",U,[n(a,{t:"Geolocation"})])])]),t("tbody",null,[(l(!0),o(u,null,m(this.tracerouteResult,(e,et)=>(l(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,[t("samp",null,i(e.ip),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.avg_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.min_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.max_rtt),1)])]),t("td",null,[e.geo.city&&e.geo.country?(l(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):(l(),o("span",J," - "))])]))),256))])])])])):(l(),o("div",z,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(l(),o(u,null,m(5,e=>t("div",{class:k(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:T({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const lt=h(R,[["render",Q],["__scopeId","data-v-3e75b4d4"]]);export{lt as default};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -10,7 +10,7 @@
<link rel="icon" href="/static/app/dist/img/Logo-2-512x512.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WGDashboard</title>
<script type="module" crossorigin src="/static/app/dist/assets/index-CUmHRwBw.js"></script>
<script type="module" crossorigin src="/static/app/dist/assets/index-oBQzjt8-.js"></script>
<link rel="stylesheet" crossorigin href="/static/app/dist/assets/index-DFl-XeJT.css">
</head>
<body>
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "app",
"version": "4.2.0",
"version": "4.2.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "app",
"version": "4.2.0",
"version": "4.2.3",
"dependencies": {
"@vue/language-server": "^2.1.10",
"@vuepic/vue-datepicker": "^9.0.1",
+2 -2
View File
@@ -1,13 +1,13 @@
{
"name": "app",
"version": "4.2.0",
"version": "4.2.5",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"buildcommitpush": "./build.sh",
"build electron": "vite build && vite build --mode electron && cd ../../../../WGDashboard-Desktop && electron-builder --mac --win",
"build electron": "vite build && vite build --mode electron && cd ../../../../WGDashboard-Desktop && /opt/homebrew/bin/npm run \"electron dist\"",
"preview": "vite preview"
},
"dependencies": {
@@ -36,7 +36,7 @@ const resetForm = () => {
dataChanged.value = false;
Object.assign(data, JSON.parse(JSON.stringify(props.configurationInfo)))
}
const emit = defineEmits(["changed", "close", "refresh"])
const emit = defineEmits(["changed", "close", "refresh", "dataChanged"])
const saveForm = () => {
saving.value = true
fetchPost("/api/updateWireguardConfiguration", data, (res) => {
@@ -63,10 +63,12 @@ const editRawConfigurationFileModal = ref(false)
const backupRestoreModal = ref(false)
const deleteConfigurationModal = ref(false)
</script>
<template>
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll" ref="editConfigurationContainer">
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0" ref="editConfigurationContainer">
<div class="w-100 h-100 overflow-y-scroll">
<TransitionGroup name="zoom">
<EditRawConfigurationFile
name="EditRawConfigurationFile"
@@ -171,7 +173,19 @@ const deleteConfigurationModal = ref(false)
id="configuration_listen_port">
</div>
<div v-for="key in ['PreUp', 'PreDown', 'PostUp', 'PostDown']">
<div class="accordion mt-2" id="editConfigurationOptionalAccordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed px-3 py-2" type="button" data-bs-toggle="collapse" data-bs-target="#editOptionalAccordionCollapse">
<small class="text-muted">
<LocaleText t="Optional Settings"></LocaleText>
</small>
</button>
</h2>
<div id="editOptionalAccordionCollapse"
class="accordion-collapse collapse" data-bs-parent="#editConfigurationOptionalAccordion">
<div class="accordion-body d-flex flex-column gap-3">
<div v-for="key in ['Table', 'PreUp', 'PreDown', 'PostUp', 'PostDown']">
<label :for="'configuration_' + key" class="form-label">
<small class="text-muted">
<LocaleText :t="key"></LocaleText>
@@ -194,6 +208,13 @@ const deleteConfigurationModal = ref(false)
v-model="data[key]"
:id="'configuration_' + key">
</div>
</div>
</div>
</div>
</div>
<div class="d-flex align-items-center gap-2 mt-4">
<button class="btn bg-secondary-subtle border-secondary-subtle text-secondary-emphasis rounded-3 shadow ms-auto"
@click="resetForm()"
@@ -242,6 +263,7 @@ const deleteConfigurationModal = ref(false)
</div>
</div>
</div>
</div>
</template>
<style scoped>
@@ -98,15 +98,6 @@ export default {
<samp>{{Peer.allowed_ip}}</samp>
</small>
</div>
<div v-if="Peer.advanced_security"
:class="{'d-flex gap-2 align-items-center' : dashboardStore.Configuration.Server.dashboard_peer_list_display === 'list'}">
<small class="text-muted">
<LocaleText t="Advanced Security"></LocaleText>
</small>
<small class="d-block">
<samp>{{Peer.advanced_security}}</samp>
</small>
</div>
<div class="d-flex align-items-end ms-auto">
<div class="ms-auto px-2 rounded-3 subMenuBtn"
:class="{active: this.subMenuOpened}"
@@ -102,11 +102,12 @@ watch(() => {
<div class="card-body px-4 pb-4">
<div class="d-flex flex-column gap-2">
<BulkAdd :saving="saving" :data="peerData" :availableIp="availableIp"></BulkAdd>
<template v-if="!peerData.bulkAdd">
<hr class="mb-0 mt-2">
<NameInput :saving="saving" :data="peerData" v-if="!peerData.bulkAdd"></NameInput>
<PrivatePublicKeyInput :saving="saving" :data="peerData" v-if="!peerData.bulkAdd"></PrivatePublicKeyInput>
<AllowedIPsInput :availableIp="availableIp" :saving="saving" :data="peerData" v-if="!peerData.bulkAdd"></AllowedIPsInput>
<NameInput :saving="saving" :data="peerData"></NameInput>
<PrivatePublicKeyInput :saving="saving" :data="peerData"></PrivatePublicKeyInput>
<AllowedIPsInput :availableIp="availableIp" :saving="saving" :data="peerData"></AllowedIPsInput>
</template>
</div>
<hr>
<div class="accordion mb-3" id="peerAddModalAccordion">
@@ -155,36 +156,6 @@ watch(() => {
</div>
<div v-if="getProtocol === 'awg'">
<h5>
<LocaleText t="AmneziaWG Peer Setting"></LocaleText>
</h5>
<div >
<label class="form-label d-block"><small class="text-muted">
<LocaleText t="Advanced Security"></LocaleText>
</small></label>
<div class="btn-group" role="group">
<input type="radio" class="btn-check"
v-model="peerData.advanced_security"
value="on"
name="advanced_security_radio" id="advanced_security_on" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_on">
<LocaleText t="On"></LocaleText>
</label>
<input type="radio"
v-model="peerData.advanced_security"
value="off"
class="btn-check" name="advanced_security_radio" id="advanced_security_off" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_off">
<LocaleText t="Off"></LocaleText>
</label>
</div>
</div>
</div>
<div class="d-flex mt-2">
<button class="ms-auto btn btn-dark btn-brand rounded-3 px-3 py-2 shadow"
:disabled="!allRequireFieldsFilled || saving"
@@ -157,35 +157,6 @@ export default {
</div>
</div>
<hr>
<div v-if="this.getProtocol === 'awg'">
<h5>
<LocaleText t="AmneziaWG Peer Setting"></LocaleText>
</h5>
<div >
<label class="form-label d-block"><small class="text-muted">
<LocaleText t="Advanced Security"></LocaleText>
</small></label>
<div class="btn-group" role="group">
<input type="radio" class="btn-check"
v-model="this.data.advanced_security"
value="on"
name="advanced_security_radio" id="advanced_security_on" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_on">
<LocaleText t="On"></LocaleText>
</label>
<input type="radio"
v-model="this.data.advanced_security"
value="off"
class="btn-check" name="advanced_security_radio" id="advanced_security_off" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_off">
<LocaleText t="Off"></LocaleText>
</label>
</div>
</div>
</div>
<hr>
<div class="d-flex mt-2">
<button class="ms-auto btn btn-dark btn-brand rounded-3 px-3 py-2 shadow"
:disabled="!this.allRequireFieldsFilled || this.saving"
@@ -197,7 +197,7 @@ export default {
methods:{
toggle(){
this.configurationToggling = true;
fetchGet("/api/toggleWireguardConfiguration/", {
fetchGet("/api/toggleWireguardConfiguration", {
configurationName: this.configurationInfo.Name
}, (res) => {
if (res.status){
@@ -118,7 +118,7 @@ watch(() => {
// Toggle Configuration Method =====================================
const toggleConfiguration = async () => {
configurationToggling.value = true;
await fetchGet("/api/toggleWireguardConfiguration/", {
await fetchGet("/api/toggleWireguardConfiguration", {
configurationName: configurationInfo.value.Name
}, (res) => {
if (res.status){
@@ -24,7 +24,29 @@ export default {
}, (res) => {
this.loading = false;
if (res.status){
QRCode.toCanvas(document.querySelector("#qrcode"), res.data.file, (error) => {
let data = ""
if (this.selectedPeer.configuration.Protocol === "awg"){
let awgQRCodeObject = {
containers: [
{
awg: {
isThirdPartyConfig: true,
last_config: res.data.file,
port: this.selectedPeer.configuration.ListenPort,
transport_proto: "udp"
},
container: "amnezia-awg",
}
],
defaultContainer: "amnezia-awg",
description: this.selectedPeer.name,
hostName: this.dashboardStore.Configuration.Peers.remote_endpoint
}
data = btoa(JSON.stringify(awgQRCodeObject))
}else{
data = res.data.file
}
QRCode.toCanvas(document.querySelector("#qrcode"), data, (error) => {
if (error) console.error(error)
})
}else{
@@ -47,8 +69,10 @@ export default {
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
</div>
<div class="card-body p-4">
<div style="width: 292px; height: 292px;" class="d-flex">
<canvas id="qrcode" class="rounded-3 shadow animate__animated animate__fadeIn animate__faster" :class="{'d-none': loading}"></canvas>
<div class="d-flex">
<canvas id="qrcode" class="rounded-3 shadow animate__animated animate__fadeIn animate__faster"
:class="{'d-none': loading}"></canvas>
<div class="spinner-border m-auto" role="status" v-if="loading">
<span class="visually-hidden">Loading...</span>
</div>
@@ -61,4 +85,11 @@ export default {
</template>
<style scoped>
@media screen and (max-width: 768px) {
#qrcode{
width: 100% !important;
height: auto !important;
aspect-ratio: 1/1;
}
}
</style>
@@ -46,7 +46,7 @@ export default {
methods: {
save(){
if (this.job.Field && this.job.Operator && this.job.Action && this.job.Value){
fetchPost(`/api/savePeerScheduleJob/`, {
fetchPost(`/api/savePeerScheduleJob`, {
Job: this.job
}, (res) => {
if (res.status){
@@ -84,7 +84,7 @@ export default {
},
delete(){
if(this.job.CreationDate){
fetchPost(`/api/deletePeerScheduleJob/`, {
fetchPost(`/api/deletePeerScheduleJob`, {
Job: this.job
}, (res) => {
if (!res.status){
@@ -198,30 +198,6 @@ export default {
v-model="this.data.keepalive"
id="peer_keep_alive">
</div>
<div v-if="this.data.advanced_security">
<label for="peer_advance_security" class="form-label d-block">
<small class="text-muted">
<LocaleText t="Advanced Security"></LocaleText>
</small>
</label>
<div class="btn-group" role="group">
<input type="radio" class="btn-check"
v-model="this.data.advanced_security"
value="on"
name="advanced_security_radio" id="advanced_security_on" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_on">
<LocaleText t="On"></LocaleText>
</label>
<input type="radio"
v-model="this.data.advanced_security"
value="off"
class="btn-check" name="advanced_security_radio" id="advanced_security_off" autocomplete="off">
<label class="btn btn-outline-primary btn-sm" for="advanced_security_off">
<LocaleText t="Off"></LocaleText>
</label>
</div>
</div>
</div>
</div>
</div>
@@ -29,7 +29,7 @@ export default {
methods: {
toggle(){
this.configurationToggling = true;
fetchGet("/api/toggleWireguardConfiguration/", {
fetchGet("/api/toggleWireguardConfiguration", {
configurationName: this.c.Name
}, (res) => {
if (res.status){
@@ -1,6 +1,5 @@
<script setup>
import LocaleText from "@/components/text/localeText.vue";
import AgentContainer from "@/components/navbarComponents/agentContainer.vue";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
const emits = defineEmits(['close'])
@@ -29,7 +28,7 @@ const store = DashboardConfigurationStore()
<LocaleText t="You can visit our: "></LocaleText>
</p>
<div class="list-group">
<a href="https://donaldzou.github.io/WGDashboard-Documentation/"
<a href="https://docs.wgdashboard.dev/"
target="_blank" class="list-group-item list-group-item-action d-flex align-items-center">
<i class="bi bi-book-fill"></i>
<LocaleText class="ms-auto" t="Official Documentation"></LocaleText>
@@ -75,7 +74,7 @@ const store = DashboardConfigurationStore()
width: 450px;
box-shadow: 0px 10px 30px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(8px);
background: linear-gradient(var(--degree), #009dff52 var(--distance2), #ff4a0052 100%);
background: linear-gradient(var(--degree), #009dff52 var(--distance2), #F9464752 100%);
}
.agentContainer.enabled{
@@ -52,7 +52,7 @@ onMounted(() => {
</div>
</div>
</a>
<a class="card text-decoration-none" href="https://donaldzou.github.io/WGDashboard-Documentation/" target="_blank">
<a class="card text-decoration-none" href="https://docs.wgdashboard.dev/" target="_blank">
<div class="card-body d-flex gap-4 align-items-center">
<h1 class="mb-0">
<i class="bi bi-hash"></i>
@@ -27,6 +27,7 @@ const squareHeight = computed(() => {
<div
v-if="show"
style="white-space: nowrap;"
:style="{'top': squareHeight}"
class="floatingLabel z-3 border position-absolute d-block p-1 px-2
bg-body text-body rounded-3 border shadow d-flex"
:class="[align ? 'end-0':'start-0']"
@@ -48,7 +49,4 @@ const squareHeight = computed(() => {
transition: background-color 0.5s cubic-bezier(0.42, 0, 0.22, 1.0);
}
.floatingLabel{
top: 40px;
}
</style>
@@ -23,6 +23,7 @@ const squareHeight = computed(() => {
<div
v-if="show"
style="white-space: nowrap;"
:style="{'top': squareHeight}"
class="floatingLabel z-3 border position-absolute d-block p-1 px-2
bg-body text-body rounded-3 border shadow d-flex"
:class="[align ? 'end-0':'start-0']"
@@ -43,8 +44,4 @@ const squareHeight = computed(() => {
height: v-bind(squareHeight);
transition: background-color 0.5s cubic-bezier(0.42, 0, 0.22, 1.0);
}
.floatingLabel{
top: v-bind(squareHeight);
}
</style>
@@ -66,13 +66,13 @@ const data = computed(() => {
</h6>
<h6 class="ms-auto">
<span v-if="data">
{{ data?.Disks.find(x => x.mountPoint === '/').percent }}%
{{ data.Disks.find(x => x.mountPoint === '/') ? data?.Disks.find(x => x.mountPoint === '/').percent : data?.Disks[0].percent }}%
</span>
<span v-else class="spinner-border spinner-border-sm"></span>
</h6>
</div>
<div class="progress" role="progressbar" style="height: 6px">
<div class="progress-bar bg-success" :style="{width: `${data?.Disks.find(x => x.mountPoint === '/').percent}%` }"></div>
<div class="progress-bar bg-success" :style="{width: `${data?.Disks.find(x => x.mountPoint === '/') ? data?.Disks.find(x => x.mountPoint === '/').percent : data?.Disks[0].percent}%` }"></div>
</div>
<div class="d-flex mt-2 gap-1">
<StorageMount v-for="(disk, count) in data?.Disks"
-34
View File
@@ -35,39 +35,6 @@
}
}
/*
* Sidebar
*/
/*.sidebar {*/
/* position: fixed;*/
/* top: 0;*/
/* bottom: 0;*/
/* left: 0;*/
/* z-index: 100;*/
/* !* Behind the navbar *!*/
/* padding: 48px 0 0;*/
/* !* Height of navbar *!*/
/* box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);*/
/*}*/
/*.sidebar-sticky {*/
/* position: relative;*/
/* top: 0;*/
/* height: calc(100vh - 48px);*/
/* padding-top: .5rem;*/
/* overflow-x: hidden;*/
/* overflow-y: auto;*/
/* !* Scrollable contents if viewport is shorter than content. *!*/
/*}*/
/*@supports ((position: -webkit-sticky) or (position: sticky)) {*/
/* .sidebar-sticky {*/
/* position: -webkit-sticky;*/
/* position: sticky;*/
/* }*/
/*}*/
@property --brandColor1 {
syntax: '<color>';
initial-value: #009dff;
@@ -1273,7 +1240,6 @@ samp{
}
.wireguardBg{
background: rgb(125,32,32);
background: linear-gradient(90deg, rgba(125,32,32,1) 0%, rgba(255,56,56,1) 100%);
}
-2
View File
@@ -9,7 +9,6 @@ import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router/router.js'
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
let Locale;
await fetch("/api/locale")
.then(res => res.json())
@@ -24,7 +23,6 @@ const pinia = createPinia();
pinia.use(({ store }) => {
store.$router = markRaw(router)
})
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
const store = DashboardConfigurationStore()
@@ -34,6 +34,7 @@ export default {
PreDown: "",
PostUp: "",
PostDown: "",
Table: "",
Protocol: "wg",
Jc: 5,
Jmin: 49,
@@ -342,6 +343,7 @@ export default {
</div>
</div>
</div>
<hr>
<div class="accordion" id="newConfigurationOptionalAccordion">
<div class="accordion-item">
@@ -353,7 +355,7 @@ export default {
<div id="newConfigurationOptionalAccordionCollapse"
class="accordion-collapse collapse" data-bs-parent="#newConfigurationOptionalAccordion">
<div class="accordion-body d-flex flex-column gap-3">
<div class="card rounded-3" v-for="key in ['PreUp', 'PreDown', 'PostUp', 'PostDown']">
<div class="card rounded-3" v-for="key in ['Table', 'PreUp', 'PreDown', 'PostUp', 'PostDown']">
<div class="card-header">{{ key }}</div>
<div class="card-body">
<input type="text"
+25
View File
@@ -1,4 +1,9 @@
[
{
"lang_id": "id",
"lang_name": "Bahasa Indonesia",
"lang_name_localized": "Bahasa Indonesia"
},
{
"lang_id": "zh-cn",
"lang_name": "Chinese (Simplified)",
@@ -9,6 +14,11 @@
"lang_name": "Belarusian",
"lang_name_localized": "Беларуская"
},
{
"lang_id": "ca",
"lang_name": "Catalan",
"lang_name_localized": "Català"
},
{
"lang_id": "zh-hk",
"lang_name": "Chinese (Traditional)",
@@ -44,11 +54,21 @@
"lang_name": "French (Quebec)",
"lang_name_localized": "Français (Québec)"
},
{
"lang_id": "fr-fr",
"lang_name": "French (France)",
"lang_name_localized": "Français (France)"
},
{
"lang_id": "de-de",
"lang_name": "German",
"lang_name_localized": "Deutsch"
},
{
"lang_id": "hu-hu",
"lang_name": "Hungarian",
"lang_name_localized": "Magyar"
},
{
"lang_id": "it-it",
"lang_name": "Italian",
@@ -69,6 +89,11 @@
"lang_name": "Polish",
"lang_name_localized": "Polski"
},
{
"lang_id": "pt-br",
"lang_name": "Portuguese (Brazil)",
"lang_name_localized": "Português (Brasil)"
},
{
"lang_id": "ru",
"lang_name": "Russian",
+59 -2
View File
@@ -278,7 +278,6 @@
"Create Backup": "إنشاء نسخة احتياطية",
"No backup yet, click the button above to create backup\\.": "لا توجد نسخة احتياطية حتى الآن، انقر على الزر أعلاه لإنشاء نسخة احتياطية",
"Are you sure to delete this backup\\?": "هل أنت متأكد من حذف هذه النسخة الاحتياطية؟",
"Are you sure to restore this backup?\\": "هل أنت متأكد من استعادة هذه النسخة الاحتياطية؟",
"Backup Date": "تاريخ النسخة الاحتياطية",
"File": "الملف",
"Are you sure to delete this configuration\\?": "هل أنت متأكد من حذف هذا الإعداد؟",
@@ -308,5 +307,63 @@
"Deleted ([0-9]{1,}) peer\\(s\\)": "تم حذف $1 قرين(قرين)",
"Deleted ([0-9]{1,}) peer\\(s\\) successfully. Failed to delete ([0-9]{1,}) peer\\(s\\)": "تم حذف $1 قرين(قرين) بنجاح. فشل في حذف $2 قرين(قرين)",
"Restricted ([0-9]{1,}) peer\\(s\\)": "تم تقييد $1 قرين(قرين).",
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "تم تقييد $1 قرين(قرين) بنجاح. فشل في تقييد $2 قرين(قرين)."
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "تم تقييد $1 قرين(قرين) بنجاح. فشل في تقييد $2 قرين(قرين).",
"Table": "",
"Search": "",
"Hop": "",
"Average RTT \\(ms\\)": "",
"Min RTT \\(ms\\)": "",
"Max RTT \\(ms\\)": "",
"You can visit our: ": "",
"Official Documentation": "",
"Discord Server": "",
"Are you sure to restore this backup\\?": "",
"Download": "",
"Display As": "",
"List": "",
"Grid": "",
"Protocol": "",
"Open File": "",
"Advanced Options": "",
"Allowed IPs Validation": "",
"Update Name": "",
"To update this configuration's name, WGDashboard will execute the following operations:": "",
"Duplicate current configuration's database table and \\.conf file with the new name": "",
"Delete current configuration's database table and \\.conf file": "",
"Danger Zone": "",
"Configuration File": "",
"Edit Raw Configuration File": "",
"Peer Configuration File": "",
"Share with Email": "",
"Email Account": "",
"Ready": "",
"Port": "",
"Encryption": "",
"No Encryption": "",
"Send From": "",
"Send Test Email": "",
"Email Body Template": "",
"Live Preview": "",
"Include configuration file as an attachment": "",
"Send": "",
"Sending\\.\\.\\.": "",
"Email sent successfully!": "",
"AmneziaWG Peer Setting": "",
"System Status": "",
"CPU": "",
"Memory": "",
"Swap Memory": "",
"Processes": "",
"CPU Usage": "",
"Memory Usage": "",
"Swap Memory Usage": "",
"Network": "",
"([0-9]{1,}) Interfaces": "",
"Storage": "",
"([0-9]{1,}) Partitions": "",
"(.*) Used": "",
"Untitled Peer": "",
"Who are you sending to\\?": "",
"What\\'s the subject\\?": "",
"What\\'s the body\\?": ""
}
+59 -2
View File
@@ -278,7 +278,6 @@
"Create Backup": "Стварыць рэзервовую копію",
"No backup yet, click the button above to create backup\\.": "Рэзервовых копій яшчэ няма, націсніце кнопку вышэй, каб стварыць рэзервовую копію.",
"Are you sure to delete this backup\\?": "Вы ўпэўнены, што хочаце выдаліць гэтую рэзервовую копію?",
"Are you sure to restore this backup?\\": "Вы ўпэўнены, што хочаце аднавіць гэтую рэзервовую копію?",
"Backup Date": "Дата рэзервовай копіі",
"File": "Файл",
"Are you sure to delete this configuration\\?": "Вы ўпэўнены, што хочаце выдаліць гэтую канфігурацыю?",
@@ -308,5 +307,63 @@
"Deleted ([0-9]{1,}) peer\\(s\\)": "Выдалена $1 кліент(аў)",
"Deleted ([0-9]{1,}) peer\\(s\\) successfully. Failed to delete ([0-9]{1,}) peer\\(s\\)": "Выдалена $1 кліент(аў) паспяхова. Не ўдалося выдаліць $2 кліент(аў)",
"Restricted ([0-9]{1,}) peer\\(s\\)": "Абмежавана $1 кліент(аў)",
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "Абмежавана $1 кліент(аў) паспяхова. Не ўдалося абмежаваць $2 кліент(аў)"
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "Абмежавана $1 кліент(аў) паспяхова. Не ўдалося абмежаваць $2 кліент(аў)",
"Table": "",
"Search": "",
"Hop": "",
"Average RTT \\(ms\\)": "",
"Min RTT \\(ms\\)": "",
"Max RTT \\(ms\\)": "",
"You can visit our: ": "",
"Official Documentation": "",
"Discord Server": "",
"Are you sure to restore this backup\\?": "",
"Download": "",
"Display As": "",
"List": "",
"Grid": "",
"Protocol": "",
"Open File": "",
"Advanced Options": "",
"Allowed IPs Validation": "",
"Update Name": "",
"To update this configuration's name, WGDashboard will execute the following operations:": "",
"Duplicate current configuration's database table and \\.conf file with the new name": "",
"Delete current configuration's database table and \\.conf file": "",
"Danger Zone": "",
"Configuration File": "",
"Edit Raw Configuration File": "",
"Peer Configuration File": "",
"Share with Email": "",
"Email Account": "",
"Ready": "",
"Port": "",
"Encryption": "",
"No Encryption": "",
"Send From": "",
"Send Test Email": "",
"Email Body Template": "",
"Live Preview": "",
"Include configuration file as an attachment": "",
"Send": "",
"Sending\\.\\.\\.": "",
"Email sent successfully!": "",
"AmneziaWG Peer Setting": "",
"System Status": "",
"CPU": "",
"Memory": "",
"Swap Memory": "",
"Processes": "",
"CPU Usage": "",
"Memory Usage": "",
"Swap Memory Usage": "",
"Network": "",
"([0-9]{1,}) Interfaces": "",
"Storage": "",
"([0-9]{1,}) Partitions": "",
"(.*) Used": "",
"Untitled Peer": "",
"Who are you sending to\\?": "",
"What\\'s the subject\\?": "",
"What\\'s the body\\?": ""
}
+369
View File
@@ -0,0 +1,369 @@
{
"Welcome to": "Benvingut",
"Username": "Usuari",
"Password": "Contrasenya",
"OTP from your authenticator": "OTP del seu autenticador",
"Sign In": "Iniciar sessió",
"Signing In\\.\\.\\.": "Iniciant sessió\\.\\.\\.",
"Access Remote Server": "Accedir al servidor remot",
"Server": "Servidor",
"Click": "Clic",
"Pinging...": "S'està fent ping...",
"to add your server": "per afegir el vostre servidor",
"Server List": "Llista de servidors:",
"Sorry, your username or password is incorrect.": "Ho sentim, el seu nom d'usuari o contrasenya són incorrectes",
"Home": "Inici",
"Settings": "Paràmetres",
"Tools": "Eines",
"Sign Out": "Tancar sessió",
"Checking for update...": "Comprovant actualitzacions...",
"You're on the latest version": "Està a l'última versió",
"WireGuard Configurations": "Configuració de WireGuard",
"You don't have any WireGuard configurations yet. Please check the configuration folder or change it in Settings. By default the folder is /etc/wireguard.": "Encara no teniu cap configuració de WireGuard. Si us plau, comproveu la carpeta de configuració o canvieu-la a Configuració. Per defecte, la carpeta és /etc/wireguard.",
"Configuration": "Configuració",
"Configurations": "Configuracions",
"Peers Default Settings": "Paràmetres per defecte de Peers",
"Dashboard Theme": "Tema del tauler",
"Light": "Clar",
"Dark": "Fosc",
"This will be changed globally, and will be apply to all peer's QR code and configuration file.": "Això es canviarà globalment i s'aplicarà a tots els codis QR i fitxers de configuració dels peer.",
"WireGuard Configurations Settings": "Paràmetres de Configuració del WireGuard",
"Configurations Directory": "Carpeta de configuracions",
"Remember to remove / at the end of your path. e.g /etc/wireguard": "Recordi eliminar / al final de la vostra ruta. p. ex. /etc/wireguard",
"WGDashboard Account Settings": "Paràmetres el Compte WGDashboard",
"Current Password": "Contrasenya Actual",
"New Password": "Nova Contrasenya",
"Repeat New Password": "Repeteixi la Nova Contrasenya",
"Update Password": "Actualitzar Contrasenya",
"Multi-Factor Authentication \\(MFA\\)": "Autenticació Multifactor \\(MFA\\)",
"Reset": "Restablir",
"Setup": "Configuració",
"API Keys": "Claus API",
"API Key": "Clau API",
"Key": "Clau",
"Enabled": "Habilitat",
"Disabled": "Deshabilitat",
"No WGDashboard API Key": "No hi ha clau API de WGDashboard",
"Expire At": "Caduca al",
"Are you sure to delete this API key\\?": "Està segur que vol eliminar aquesta clau API\\?",
"Create API Key": "Crear clau d'API",
"When should this API Key expire\\?": "Quan hauria de caducar aquesta clau API\\?",
"Never Expire": "Mai Expira",
"Don't think that's a good idea": "No crec que sigui una bona idea",
"Creating\\.\\.\\.": "Creant\\.\\.\\.",
"Create": "Crear",
"Status": "Estatus",
"On": "Iniciar",
"Off": "Parar",
"Turning On\\.\\.\\.": "S'està encenent\\.\\.\\.",
"Turning Off\\.\\.\\.": "S'estat apagant\\.\\.\\.",
"Address": "Adreça",
"Listen Port": "Port d'escolta",
"Public Key": "Clau Pública",
"Connected Peers": "Peers Connectats",
"Total Usage": "Total usat",
"Total Received": "Total Rebut",
"Total Sent": "Total Enviat",
"Peers Data Usage": "Ús de dades dels Peers",
"Real Time Received Data Usage": "Ús de Dades Rebudes en Temps Real",
"Real Time Sent Data Usage": "Úsde Dades Eviades en Temps Real",
"Peer": "Peer",
"Peers": "Peers",
"Peer Settings": "Paràmetres del Peer",
"Download All": "Descarregar Tot",
"Search": "Cercar",
"Search Peers\\.\\.\\.": "Cercar Peers\\.\\.\\.",
"Display": "Mostrar",
"Sort By": "Ordenar Per",
"Refresh Interval": "Interval de Refresc",
"Name": "Nom",
"Allowed IPs": "IPs Permeses",
"Restricted": "Restringit",
"(.*) Seconds": "(.*) Segons",
"(.*) Minutes": "(.*) Minuts",
"Configuration Settings": "Paràmetres de Configuracio",
"Peer Jobs": "Feines Peer",
"Active Jobs": "Feines Actives",
"All Active Jobs": "Totes les Feines Actives",
"Logs": "Registres",
"Private Key": "Clau Privada",
"\\(Required for QR Code and Download\\)": "\\(Obligatori pel Codi QR i la Descàrrega\\)",
"\\(Required\\)": "\\(Obligatori\\)",
"Endpoint Allowed IPs": "IPs Permeses del Punt Final",
"DNS": "DNS",
"Optional Settings": "Paràmetres Opcionals",
"Pre-Shared Key": "Clau Precompartida",
"MTU": "MTU",
"Persistent Keepalive": "Keepalive Persistent",
"Reset Data Usage": "Restablir l'Ús de Dades",
"Total": "Total",
"Sent": "Enviat",
"Received": "Rebut",
"Revert": "Desfer",
"Save Peer": "Desar Peer",
"QR Code": "Codi QR",
"Schedule Jobs": "Feines Programades",
"Job": "Feina",
"Job ID": "Feina ID",
"Unsaved Job": "Feina no desada",
"This peer does not have any job yet\\.": "Aquest peer encara no te cap feina\\.",
"if": "si",
"is": "és",
"then": "aleshores",
"larger than": "més llarg que",
"Date": "Data",
"Restrict Peer": "Restringir Peer",
"Delete Peer": "Eliminar Peer",
"Edit": "Editar",
"Delete": "Eliminar",
"Deleting...": "Eliminant...",
"Cancel": "Cancel·lar",
"Save": "Desar",
"No active job at the moment\\.": "No hi ha cap feina activa ara mateix\\.",
"Jobs Logs": "Registres de Feines",
"Updated at": "Actualitzat a",
"Refresh": "Refrescar",
"Filter": "Filtrar",
"Success": "Èxit",
"Failed": "Fallat",
"Log ID": "ID Registre",
"Message": "Missatge",
"Share Peer": "Compartir Peer",
"Currently the peer is not sharing": "Actualment el peer no s'està compartint",
"Sharing\\.\\.\\.": "Compartint\\.\\.\\.",
"Start Sharing": "Començar a Compartir",
"Stop Sharing\\.\\.\\.": "Parar de Compartir\\.\\.\\.",
"Stop Sharing": "Para de Compartir",
"Access Restricted": "Accés Restringit",
"Restrict Access": "Àrea Restringida",
"Restricting\\.\\.\\.": "Restringint\\.\\.\\.",
"Allow Access": "Permetre Accés",
"Allowing Access\\.\\.\\.": "Permetent Accés\\.\\.\\.",
"Download \\& QR Code is not available due to no private key set for this peer": "La descàrrega del codi QR \\& no està disponible perquè no s'ha establert cap clau privada per a aquest peer",
"Add Peers": "Afegir Peers",
"Bulk Add": "Afegir en Massa",
"By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP\\.": "En afegir peers en massa, el nom de cada peer es generarà automàticament i la IP permesa s'assignarà a la següent IP disponible\\.",
"How many peers you want to add\\?": "Quants peers voleu afegir\\?",
"You can add up to (.*) peers": "Pot afegir fins a (.*) peers",
"Use your own Private and Public Key": "Utilitzi la seva pròpia Clau Privada i Pública",
"Enter IP Address/CIDR": "Introdueixi l'adreça IP/CIDR",
"IP Address/CIDR": "Adreça IP/CDIR",
"or": "o",
"Pick Available IP": "Seleccioni una IP disponible",
"No available IP containing": "No conté cap IP disponible",
"Add": "Afegir",
"Adding\\.\\.\\.": "Afegint\\.\\.\\.",
"Failed to check available update": "No s'ha pogut comprovar l'actualització disponible",
"Nice to meet you!": "Encantat de conèixer-lo",
"Please fill in the following fields to finish setup": "Si us plau, ompli els següets camps per finalitzar la configuració",
"Create an account": "Crear un compte",
"Enter an username you like": "Introdueixi un nom d'usuari que li agradi",
"Enter a password": "Introduir una contrasenya",
"\\(At least 8 characters and make sure is strong enough!\\)": "\\(Com a mínim 8 caràcters i asseguri's que és suficietment forta!\\)",
"Confirm password": "Confirmar contrasenya",
"Next": "Seguent",
"Saving\\.\\.\\.": "Desant\\.\\.\\.",
"1\\. Please scan the following QR Code to generate TOTP with your choice of authenticator": "1\\. Si us plau, escanegi el següent codi QR per generar TOTP amb l'autenticador que triï",
"Or you can click the link below:": "O bé pot clicar l'enllaç següent:",
"2\\. Enter the TOTP generated by your authenticator to verify": "2\\. Introdueixi el TOTP generat pel seu autentitador per feriricar",
"TOTP verified!": "TOTP verificat!",
"I don't need MFA": "No necessito MFA",
"Complete": "Completat",
"(v[0-9.]{1,}) is now available for update!": "(v[0-9.]{1,}) ara està disponible per actualitzar!",
"Current Version:": "Versió Actual",
"Oh no\\.\\.\\. This link is either expired or invalid\\.": "Oh no\\.\\.\\. Aquest enllaç ha caducat o no és vàlid",
"Scan QR Code with the WireGuard App to add peer": "Escanegi el codi QR amb l'aplicació WireGuard per afegir el peer",
"or click the button below to download the ": "o faci clic al botó següent per descarrer el ",
" file": " fitxer",
"FROM ": "DE",
"(.*) is on": "(.*) està encès",
"(.*) is off": "(.*) està parat",
"Allowed IPs is invalid": "Les IPs Permeses no són vàlides",
"Peer created successfully": "Pere creat satisfactoriament",
"Please fill in all required box": "Si us plau, empleni tots els espais necessaris",
"Please specify amount of peers you want to add": "Si us plau, especifiqueu la quantitat de persones del mateix nivell que vol afegir",
"No more available IP can assign": "No hi ha cap més IP disponible per assignar",
"The maximum number of peers can add is (.*)": "El màxim nombre de peers que es poden afegir és (.*)",
"Generating key pairs by bulk failed": "No s'ha pogut generar parells de claus de manera massiva",
"Failed to add peers in bulk": "No s'ha pogut afegir peers de manera massiva",
"This peer already exist": "Aquest peer ja existeix",
"This IP is not available: (.*)": "Aquesta IP no està disponible: (.*)",
"Configuration does not exist": "La configuració no existeix",
"Peer does not exist": "El Pere no existeix",
"Please provide a valid configuration name": "Si us plau, proporcioneu un nom de configuració vàlid",
"Peer saved": "Peter desat",
"Allowed IPs already taken by another peer": "Les IPs permeses ja estan ocupades per un altre peer",
"Endpoint Allowed IPs format is incorrect": "El format de les IPs permeses del punt final és incorrecte",
"DNS format is incorrect": "El DNS és incorrecte",
"MTU format is not correct": "El format MTU no és correcte",
"Persistent Keepalive format is not correct": "El format de Keepalive persistent no és correcte",
"Private key does not match with the public key": "La clau privada no coincideix amb la clau pública",
"Update peer failed when updating Pre-Shared Key": "L'actualització del peer ha fallat en actualitzar la clau precompartida",
"Update peer failed when updating Allowed IPs": "L'actualització del peer ha fallat en actualitzar les IP permeses",
"Update peer failed when saving the configuration": "L'actualització del peer ha fallat en desar la configuració",
"Peer data usage reset successfully": "L'ús de dades del peer s'ha reiniciat correctament",
"Peer download started": "La descàrrega del peer s'ha iniciat",
"Please specify one or more peers": "Si us plau, especifiqueu un o més peers",
"Share link failed to create. Reason: (.*)": "No s'ha pogut crear l'enllaç de compartició. Motiu: (.*)",
"Link expire date updated": "La data de caducitat de l'enllaç s'ha actualitzat",
"Link expire date failed to update. Reason: (.*)": "No s'ha pogut actualitzar la data de caducitat de l'enllaç. Mtoiu: (.*)",
"Peer job saved": "Feina del peer desat",
"Please specify job": "Si us plau, especifiqui la tasca",
"Please specify peer and configuration": "Si us plau, esficiqui el peer i la configuració",
"Peer job deleted": "Feina del peer suprimida",
"API Keys function is successfully enabled": "La funció de claus API s'ha activat correctament",
"API Keys function is successfully disabled": "La funció de claus API s'ha descativat correctament",
"API Keys function is failed to enable": "No s'ha pogut habilitar la funció de claus API",
"API Keys function is failed to disable": "No s'ha pogut desactivar la funció de claus API",
"WGDashboard API Keys function is disabled": "La funció de claus API de WGDashboard està desactivada",
"WireGuard configuration path saved": "Ruta de configuracio del WireGuard desada",
"API Key deleted": "Clau API eliminada",
"API Key created": "Clau API creada",
"Sign in session ended, please sign in again": "La sessió d'inici ha finalitzat. Si us plau, torni a iniciar",
"Please specify an IP Address (v4/v6)": "Si us plau, espqcifiqui una adreça IP (v4/v6)",
"Please provide ipAddress and count": "Si us plau, proporcioni l'adreça IP i el recompte",
"Please provide ipAddress": "Si us plau, proporcioni l'adreça IP",
"Dashboard Language": "Idioma del tauler de control",
"Dashboard language update failed": "Error d'actualització de l'idioma del tauler de control",
"Peer Remote Endpoint": "Punt Final Remot del Peer",
"New Configuration": "Nova Configuració",
"Configuration Name": "Nom de Configuració",
"Configuration name is invalid. Possible reasons:": "Nom de configuració no vàlid. Possibles raons:",
"Configuration name already exist\\.": "El nom de configuració ja existeix\\.",
"Configuration name can only contain 15 lower/uppercase alphabet, numbers, underscore, equal sign, plus sign, period and hyphen\\.": "El nom de configuració només pot contenir 15 caràcters en majúsucules/minúscules, números, subratllat, signe igual, signe més, punt i guionet\\.",
"Invalid Port": "Port Invàlid",
"Save Configuration": "Desar Configuració",
"IP Address/CIDR is invalid": "L'adreça IP/CIDR no és vàlida",
"IP Address": "Adreça IP",
"Enter IP Address / Hostname": "Introdueixi l'adreça IP / nom de l'amfitrió",
"IP Address / Hostname": "Adreça IP / Hostname",
"Dashboard IP Address \\& Listen Port": "L'adreça IP del tauler de control\\& Port d'Escolta",
"Count": "Comptar",
"Geolocation": "Geolocalització",
"Is Alive": "Estpa Viu",
"Average / Min / Max Round Trip Time": "Temps mitjà / Min / Max d'anada i tornada",
"Sent / Received / Lost Package": "Enviat / Rebut / Paquets Perduts",
"Manual restart of WGDashboard is needed to apply changes on IP Address and Listen Port": "Cal reiniciar manualment WGDashboard per aplicar els canvis a l'adreça IP i al Port d'Escolta",
"Restore Configuration": "Restaurar Configuració",
"Step (.*)": "Pas (.*)",
"Select a backup you want to restore": "Seleccioni una còpia de seguretat que vulgui restaurar",
"Click to change a backup": "Faci clic per canviar una còpia de seguretat",
"Selected Backup": "Còpia de seguretat seleccionada",
"You don't have any configuration to restore": "No té cap configuració per restaurar",
"Help": "Ajuda",
"Backup": "Còpia de Seguretat",
"([0-9].*) Backups?": "([0-9].*) Còpia de Seguretat?",
"Yes": "Sí",
"No": "No",
"Backup not selected": "Còpia de seguretat no seleccionada",
"Confirm \\& edit restore information": "Confirmar \\& editar restaurar informació?",
"(.*) Available IP Address": "(.*) Adreces IP Disponibles",
"Database File": "Fitxer de Base de Dades",
"Contain": "Conté",
"Restricted Peers?": "Peers restringuits?",
"Restore": "Restaurar",
"Restoring": "Restaurant",
"WGDashboard Settings": "Paràmetres del WGDashboard",
"Peers Settings": "Paràmetres de Peers",
"WireGuard Configuration Settings": "Paràmetres de Configuració de WireGuard",
"Appearance": "Aparença",
"Theme": "Tema",
"Language": "Idioma",
"Account Settings": "Paràmetres del Compte",
"Peer Default Settings": "Paràmetres per Defecte del Peer",
"Toggle When Start Up": "Canviar Quan s'Iniciï",
"Other Settings": "Altres Paràmetres",
"Select Peers": "Seleccioni Peers",
"Backup & Restore": "Còpia de seguretat & Restaurar",
"Delete Configuration": "Eliminar Configuració",
"Create Backup": "Crear Còpia de Seguretat",
"No backup yet, click the button above to create backup\\.": "Encara no hi ha cap còpia de seguretat, faci clic al botó de dalt per crear una còpia de seguretat\\.",
"Are you sure to delete this backup\\?": "Està segur que vol suprimir aquesta còpia de seguretat\\?",
"Backup Date": "Data de la Còpia de Seguretat",
"File": "Fitxer",
"Are you sure to delete this configuration\\?": "Segur que vol suprimir aquesta configuració?",
"Once you deleted this configuration\\:": "Un cop hagi suprimit aquesta configuració\\:",
"All connected peers will get disconnected": "Tots els Peers connectats es desconnectaran",
"Both configuration file \\(\\.conf\\) and database table related to this configuration will get deleted": "Tant el fitxer de configuració \\(\\.conf\\) com la taula de la base de dades relacionada amb aquesta configuració s'eliminarà",
"Checking backups...": "Comprovant còpies de seguretat",
"This configuration have ([0-9].*) backups": "Aquesta configuració té ([0-9].*) còpies de seguretat",
"This configuration have no backup": "Aquesta configuració no té cap còpia de seguretat",
"If you're sure, please type in the configuration name below and click Delete": "Si està segur, escrigui el nom de la configuració qa continuació i faci clic a Eliminar",
"Select All": "Seleccionar Tot",
"Clear Selection": "Netejar Selecció",
"([0-9].*) Peers?": "([0-9].*) Peers?",
"Download": "Descarregar",
"Downloading": "Descarregant",
"Download Finished": "Descàrrega Finalitzada",
"Done": "Fet",
"Are you sure to delete": "Està segur que vol eliminar",
"Are you sure to delete this peer\\?": "Està segur que vol eliminar aquest peer\\?",
"Configuration deleted": "Configuració eliminada",
"Configuration saved": "Configuració desada",
"WGDashboard language update failed": "L'actualització de l'idioma de WGDashboard ha fallat",
"Configuration restored": "Configuració restaurada",
"Allowed IP already taken by another peer": "IP permesa ja ocupada per un altre peer",
"Failed to allow access of peer (.*)": "No s'ha pogut permetre l'accés al peer (.*)",
"Failed to save configuration through WireGuard": "No s'ha pogut desar la configuració mitjançant WireGuard",
"Allow access successfully": "Accés permès correctament",
"Deleted ([0-9]{1,}) peer\\(s\\)": "Els ([0-9]{1,}) peer\\(s\\) s'han suprimit",
"Deleted ([0-9]{1,}) peer\\(s\\) successfully. Failed to delete ([0-9]{1,}) peer\\(s\\)": "Els ([0-9]{1,}) peer\\(s\\) s'han suprimit correctament. No s'ha pgout suprimir els ([0-9]{1,}) peer\\(s\\)",
"Restricted ([0-9]{1,}) peer\\(s\\)": "Els ([0-9]{1,}) peer\\(s\\) s'han restringit",
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "Els ([0-9]{1,}) peer\\(s\\) s'han restringit correctament. No s'ha pogut restringuir els ([0-9]{1,}) peer\\(s\\)",
"Display As": "Mostrar com a",
"List": "Llista",
"Grid": "Graella",
"Protocol": "Protocol",
"Open File": "Obrir Fitxer",
"Advanced Options": "Opcions Avançades",
"Allowed IPs Validation": "Validació d'IPs permeses",
"Update Name": "Actualitzar Nom",
"To update this configuration's name, WGDashboard will execute the following operations:": "Per actualitzar el nom d'aquesta configuració, WGDashboard executarà les operacions següents:",
"Duplicate current configuration's database table and \\.conf file with the new name": "Duplicar la taula de base de dades i el fitxer \\.conf amb el nou nom",
"Delete current configuration's database table and \\.conf file": "Eliminarla taula de base de dades i el fitxer \\.conf de la configuració actual",
"Danger Zone": "Zona de Perill",
"Configuration File": "Fitxer de Configuració",
"Edit Raw Configuration File": "Editar el fitxer de configuració en brut",
"Peer Configuration File": "Fitxer de Configuració del Peer",
"Share with Email": "Compartir per correu electrònic",
"Email Account": "Compte de correu electrònic",
"Ready": "Preparat",
"Port": "Port",
"Encryption": "Encriptació",
"No Encryption": "No encriptació",
"Send From": "Enviar des de",
"Send Test Email": "Enviar correu electrònic de prova",
"Email Body Template": "Plantilla del cos del correu electrònic",
"Live Preview": "Vista prèvia en directe",
"Include configuration file as an attachment": "Inclogui el fitxer de configuració com a fitxer adjunt",
"Send": "Enviar",
"Sending\\.\\.\\.": "Enviant\\.\\.\\.",
"Email sent successfully!": "Correu elctrònic enviat correctament!",
"AmneziaWG Peer Setting": "Paràmetre del Peer d'AmneziaQG",
"System Status": "Estat del sistema",
"CPU": "CPU",
"Memory": "Memòria",
"Swap Memory": "Memòria Swap",
"Processes": "Processos",
"CPU Usage": "Ús de CPU",
"Memory Usage": "Memòria Utilitzada",
"Swap Memory Usage": "Ús de Memoria Swap",
"Network": "Xarxa",
"([0-9]{1,}) Interfaces": "([0-9]{1,}) Interfícies",
"Storage": "Emmagatzematge",
"([0-9]{1,}) Partitions": "([0-9]{1,}) Particions",
"(.*) Used": "(.*) Utilitzat",
"Untitled Peer": "Peer sense títol",
"Table": "",
"Hop": "",
"Average RTT \\(ms\\)": "",
"Min RTT \\(ms\\)": "",
"Max RTT \\(ms\\)": "",
"You can visit our: ": "",
"Official Documentation": "",
"Discord Server": "",
"Are you sure to restore this backup\\?": "",
"Who are you sending to\\?": "",
"What\\'s the subject\\?": "",
"What\\'s the body\\?": ""
}
+59 -2
View File
@@ -257,7 +257,6 @@
"Create Backup": "Vytvořit zálohu",
"No backup yet, click the button above to create backup\\.": "Žádná dostupná záloha, klikněte na tlačítko výše pro vytvoření",
"Are you sure to delete this backup\\?": "Určitě chcete smazat tuto zálohu?",
"Are you sure to restore this backup?\\": "Určitě chcete obnovit tuto zálohu?",
"Backup Date": "Datum zálohy",
"File": "Soubor",
"Are you sure to delete this configuration\\?": "Určitě chcete smazat tuto konfiguraci?",
@@ -308,5 +307,63 @@
"By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP\\.": "Při hromadném importu bude jméno každého peera vygenerované automaticky, a povolená IP adresa bude nastavena na další v pořadí",
"How many peers you want to add\\?": "Kolik peerů chcete přidat?",
"Adding\\.\\.\\.": "Přidávám...",
"Dashboard IP Address \\& Listen Port": "Dashboard IP adresa a otevřený port"
"Dashboard IP Address \\& Listen Port": "Dashboard IP adresa a otevřený port",
"Table": "",
"Search": "",
"Hop": "",
"Average RTT \\(ms\\)": "",
"Min RTT \\(ms\\)": "",
"Max RTT \\(ms\\)": "",
"You can visit our: ": "",
"Official Documentation": "",
"Discord Server": "",
"Are you sure to restore this backup\\?": "",
"Download": "",
"Display As": "",
"List": "",
"Grid": "",
"Protocol": "",
"Open File": "",
"Advanced Options": "",
"Allowed IPs Validation": "",
"Update Name": "",
"To update this configuration's name, WGDashboard will execute the following operations:": "",
"Duplicate current configuration's database table and \\.conf file with the new name": "",
"Delete current configuration's database table and \\.conf file": "",
"Danger Zone": "",
"Configuration File": "",
"Edit Raw Configuration File": "",
"Peer Configuration File": "",
"Share with Email": "",
"Email Account": "",
"Ready": "",
"Port": "",
"Encryption": "",
"No Encryption": "",
"Send From": "",
"Send Test Email": "",
"Email Body Template": "",
"Live Preview": "",
"Include configuration file as an attachment": "",
"Send": "",
"Sending\\.\\.\\.": "",
"Email sent successfully!": "",
"AmneziaWG Peer Setting": "",
"System Status": "",
"CPU": "",
"Memory": "",
"Swap Memory": "",
"Processes": "",
"CPU Usage": "",
"Memory Usage": "",
"Swap Memory Usage": "",
"Network": "",
"([0-9]{1,}) Interfaces": "",
"Storage": "",
"([0-9]{1,}) Partitions": "",
"(.*) Used": "",
"Untitled Peer": "",
"Who are you sending to\\?": "",
"What\\'s the subject\\?": "",
"What\\'s the body\\?": ""
}
+59 -2
View File
@@ -307,6 +307,63 @@
"By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP\\.": "Bei der Massenerstellung wird der Name jedes Peers automatisch generiert, und die erlaubte IP wird der nächsten verfügbaren IP zugewiesen.",
"How many peers you want to add\\?": "Wie viele Peers möchtest du hinzufügen?",
"Adding\\.\\.\\.": "Füge hinzu...",
"Dashboard IP Address \\& Listen Port": "",
"Are you sure to restore this backup?\\": "Sind Sie sicher, dass Sie dieses Backup wiederherstellen möchten?"
"Dashboard IP Address \\& Listen Port": "Dashboard IP-Adresse & Empfangsport",
"Table": "Tabelle",
"Search": "Suchen",
"Hop": "Hop",
"Average RTT \\(ms\\)": "Durchschnittliche RTT ($1ms)",
"Min RTT \\(ms\\)": "Min RTT ($1ms)",
"Max RTT \\(ms\\)": "Max RTT ($1ms)",
"You can visit our: ": "Besuche unsere:",
"Official Documentation": "Offizielle Dokumentation",
"Discord Server": "Discord Server",
"Are you sure to restore this backup\\?": "Bist du sicher, dass du dieses Backup wiederherstellen möchtest?",
"Download": "Herunterladen",
"Display As": "Anzeigen als",
"List": "Liste",
"Grid": "Netz",
"Protocol": "Protokoll",
"Open File": "Datei öffnen",
"Advanced Options": "Erweiterte Optionen",
"Allowed IPs Validation": "Erlaubte IP\\'s Validierung",
"Update Name": "Name ändern",
"To update this configuration's name, WGDashboard will execute the following operations:": "",
"Duplicate current configuration's database table and \\.conf file with the new name": "",
"Delete current configuration's database table and \\.conf file": "",
"Danger Zone": "Gefahrenzone",
"Configuration File": "Konfigurationsdatei",
"Edit Raw Configuration File": "Bearbeiten der Konfigurationsdatei",
"Peer Configuration File": "Peer Konfigurationsdatei",
"Share with Email": "Per E-Mail teilen",
"Email Account": "E-Mail Konto",
"Ready": "Bereit",
"Port": "Port",
"Encryption": "Verschlüsselung",
"No Encryption": "Keine Verschlüsselung",
"Send From": "Gesendet von",
"Send Test Email": "Sende Test E-Mail",
"Email Body Template": "E-Mail Textvorlage",
"Live Preview": "Vorschau",
"Include configuration file as an attachment": "Konfigurationsdatei als Anhang beifügen",
"Send": "Senden",
"Sending\\.\\.\\.": "Senden\\.\\.\\.",
"Email sent successfully!": "E-Mail erfolgreich gesendet!",
"AmneziaWG Peer Setting": "AmneziaWG Peer-Einstellungen",
"System Status": "System Status",
"CPU": "CPU",
"Memory": "Arbeitsspeicher",
"Swap Memory": "",
"Processes": "Prozesse",
"CPU Usage": "Auslastung",
"Memory Usage": "Auslastung",
"Swap Memory Usage": "Auslastung",
"Network": "Netzwerk",
"([0-9]{1,}) Interfaces": "$1 Interfaces",
"Storage": "Speicher",
"([0-9]{1,}) Partitions": "$1 Partionen",
"(.*) Used": "genutzt",
"Untitled Peer": "Unbenannter Peer",
"Who are you sending to\\?": "",
"What\\'s the subject\\?": "Betreff",
"What\\'s the body\\?": "Inhalt"
}
+4 -4
View File
@@ -305,8 +305,8 @@
"Failed to allow access of peer (.*)": "Fallo de habilitar acceso del peer $1",
"Failed to save configuration through WireGuard": "Fallo de salvar configuración a través de WireGuard",
"Allow access successfully": "Acceso permitido con éxito",
"Deleted ([0-9]{1,}) peer\\(s\\)": "Eliminados $1 peer(s)",
"Deleted ([0-9]{1,}) peer\\(s\\) successfully. Failed to delete ([0-9]{1,}) peer\\(s\\)": "Eliminados $1 peer(s) con éxito. Fallo al eliminar $2 peer(s)",
"Restricted ([0-9]{1,}) peer\\(s\\)": "Restringidos $1 peer(s)",
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "Restringidos $1 peer(s) con éxito. Fallo al restringir $2 peer(s)"
"Deleted ([0-9]{1,}) peer\\(s\\)": "$1 peer(s) eliminado(s)",
"Deleted ([0-9]{1,}) peer\\(s\\) successfully. Failed to delete ([0-9]{1,}) peer\\(s\\)": "$1 peer(s) eliminado(s) con éxito. Fallo al eliminar $2 peer(s)",
"Restricted ([0-9]{1,}) peer\\(s\\)": "$1 peer(s) restringido(s)",
"Restricted ([0-9]{1,}) peer\\(s\\) successfully. Failed to restrict ([0-9]{1,}) peer\\(s\\)": "$1 peer(s) restringido(s) con éxito. Fallo al restringir $2 peer(s)"
}

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