mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2026-10-30 01:12:07 +00:00
merge Development into main to bring it up (#1326)
* build(deps): bump sqlalchemy from 2.0.46 to 2.0.49 in /src
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.46 to 2.0.49.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)
---
updated-dependencies:
- dependency-name: sqlalchemy
dependency-version: 2.0.49
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump ol from 10.7.0 to 10.8.0 in /src/static/app
Bumps [ol](https://github.com/openlayers/openlayers) from 10.7.0 to 10.8.0.
- [Release notes](https://github.com/openlayers/openlayers/releases)
- [Commits](https://github.com/openlayers/openlayers/compare/v10.7.0...v10.8.0)
---
updated-dependencies:
- dependency-name: ol
dependency-version: 10.8.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump vue from 3.5.31 to 3.5.32 in /src/static/app
Bumps [vue](https://github.com/vuejs/core) from 3.5.31 to 3.5.32.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.31...v3.5.32)
---
updated-dependencies:
- dependency-name: vue
dependency-version: 3.5.32
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump fuse.js from 7.1.0 to 7.3.0 in /src/static/app
Bumps [fuse.js](https://github.com/krisk/Fuse) from 7.1.0 to 7.3.0.
- [Release notes](https://github.com/krisk/Fuse/releases)
- [Changelog](https://github.com/krisk/Fuse/blob/main/CHANGELOG.md)
- [Commits](https://github.com/krisk/Fuse/compare/v7.1.0...v7.3.0)
---
updated-dependencies:
- dependency-name: fuse.js
dependency-version: 7.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 7.3.1 to 8.0.8 in /src/static/app
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 8.0.8.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.8/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.8
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 6.4.1 to 8.0.8 in /src/static/client
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 8.0.8.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.8/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.8
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump cidr-tools from 11.3.2 to 11.3.3 in /src/static/app
Bumps [cidr-tools](https://github.com/silverwind/cidr-tools) from 11.3.2 to 11.3.3.
- [Release notes](https://github.com/silverwind/cidr-tools/releases)
- [Commits](https://github.com/silverwind/cidr-tools/compare/11.3.2...11.3.3)
---
updated-dependencies:
- dependency-name: cidr-tools
dependency-version: 11.3.3
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump uuid from 11.1.0 to 13.0.0 in /src/static/client
Bumps [uuid](https://github.com/uuidjs/uuid) from 11.1.0 to 13.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v11.1.0...v13.0.0)
---
updated-dependencies:
- dependency-name: uuid
dependency-version: 13.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump oidc-client-ts in /src/static/client
Bumps [oidc-client-ts](https://github.com/authts/oidc-client-ts) from 3.2.1 to 3.5.0.
- [Release notes](https://github.com/authts/oidc-client-ts/releases)
- [Commits](https://github.com/authts/oidc-client-ts/compare/v3.2.1...v3.5.0)
---
updated-dependencies:
- dependency-name: oidc-client-ts
dependency-version: 3.5.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pydantic from 2.12.5 to 2.13.0 in /src
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.12.5 to 2.13.0.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.12.5...v2.13.0)
---
updated-dependencies:
- dependency-name: pydantic
dependency-version: 2.13.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump vue from 3.5.16 to 3.5.32 in /src/static/client
Bumps [vue](https://github.com/vuejs/core) from 3.5.16 to 3.5.32.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.16...v3.5.32)
---
updated-dependencies:
- dependency-name: vue
dependency-version: 3.5.32
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* fix: misspell (#1231)
* build(deps-dev): bump vite-plugin-vue-devtools in /src/static/client
Bumps [vite-plugin-vue-devtools](https://github.com/vuejs/devtools/tree/HEAD/packages/vite) from 7.7.6 to 8.1.1.
- [Release notes](https://github.com/vuejs/devtools/releases)
- [Commits](https://github.com/vuejs/devtools/commits/v8.1.1/packages/vite)
---
updated-dependencies:
- dependency-name: vite-plugin-vue-devtools
dependency-version: 8.1.1
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite-plugin-vue-devtools in /src/static/client
Bumps [vite-plugin-vue-devtools](https://github.com/vuejs/devtools/tree/HEAD/packages/vite) from 7.7.6 to 8.1.1.
- [Release notes](https://github.com/vuejs/devtools/releases)
- [Commits](https://github.com/vuejs/devtools/commits/v8.1.1/packages/vite)
---
updated-dependencies:
- dependency-name: vite-plugin-vue-devtools
dependency-version: 8.1.1
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump vue from 3.5.16 to 3.5.32 in /src/static/client
Bumps [vue](https://github.com/vuejs/core) from 3.5.16 to 3.5.32.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.16...v3.5.32)
---
updated-dependencies:
- dependency-name: vue
dependency-version: 3.5.32
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pydantic from 2.12.5 to 2.13.0 in /src
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.12.5 to 2.13.0.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.12.5...v2.13.0)
---
updated-dependencies:
- dependency-name: pydantic
dependency-version: 2.13.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump sqlalchemy from 2.0.46 to 2.0.49 in /src
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.46 to 2.0.49.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)
---
updated-dependencies:
- dependency-name: sqlalchemy
dependency-version: 2.0.49
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* feat: commit PR 1237 to development
* Add preshared key default toggle (#1207)
* Add previous PR changes
* Import lowercase dayjs
* Build dist
* Revert "Build dist"
This reverts commit 152da2ca10
Dist not to be built at @DaanSelen request
* build(deps): bump pydantic from 2.13.0 to 2.13.3 in /src
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.13.0 to 2.13.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.13.0...v2.13.3)
---
updated-dependencies:
- dependency-name: pydantic
dependency-version: 2.13.3
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump uuid from 13.0.0 to 14.0.0 in /src/static/app
Bumps [uuid](https://github.com/uuidjs/uuid) from 13.0.0 to 14.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v13.0.0...v14.0.0)
---
updated-dependencies:
- dependency-name: uuid
dependency-version: 14.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 8.0.8 to 8.0.9 in /src/static/app
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.8 to 8.0.9.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.9/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.9
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump @vue/language-server in /src/static/app
Bumps [@vue/language-server](https://github.com/vuejs/language-tools/tree/HEAD/packages/language-server) from 3.2.4 to 3.2.7.
- [Release notes](https://github.com/vuejs/language-tools/releases)
- [Changelog](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vuejs/language-tools/commits/v3.2.7/packages/language-server)
---
updated-dependencies:
- dependency-name: "@vue/language-server"
dependency-version: 3.2.7
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump ol from 10.8.0 to 10.9.0 in /src/static/app
Bumps [ol](https://github.com/openlayers/openlayers) from 10.8.0 to 10.9.0.
- [Release notes](https://github.com/openlayers/openlayers/releases)
- [Commits](https://github.com/openlayers/openlayers/compare/v10.8.0...v10.9.0)
---
updated-dependencies:
- dependency-name: ol
dependency-version: 10.9.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump @vitejs/plugin-vue in /src/static/client
Bumps [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) from 5.2.4 to 6.0.6.
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@6.0.6/packages/plugin-vue)
---
updated-dependencies:
- dependency-name: "@vitejs/plugin-vue"
dependency-version: 6.0.6
dependency-type: direct:development
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump axios from 1.14.0 to 1.15.1 in /src/static/client
Bumps [axios](https://github.com/axios/axios) from 1.14.0 to 1.15.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.14.0...v1.15.1)
---
updated-dependencies:
- dependency-name: axios
dependency-version: 1.15.1
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump uuid from 13.0.0 to 14.0.0 in /src/static/client
Bumps [uuid](https://github.com/uuidjs/uuid) from 13.0.0 to 14.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v13.0.0...v14.0.0)
---
updated-dependencies:
- dependency-name: uuid
dependency-version: 14.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pinia from 3.0.2 to 3.0.4 in /src/static/client
Bumps [pinia](https://github.com/vuejs/pinia) from 3.0.2 to 3.0.4.
- [Release notes](https://github.com/vuejs/pinia/releases)
- [Commits](https://github.com/vuejs/pinia/compare/v3.0.2...v3.0.4)
---
updated-dependencies:
- dependency-name: pinia
dependency-version: 3.0.4
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* Refactor peer schedule job API to use proper REST verbs (#1239)
* Fixed quotation marks
* Update wgd.sh
* Refactor peer schedule job API to use proper REST verbs
Replace single POST endpoints with POST/PUT/DELETE for peer schedule jobs.
Add require_fields decorator for request validation. Add fetchPut and
fetchDelete helpers in the frontend.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add local development with Docker section to docker/README.md
Explains how to mount src/ as a volume for live code editing
using a compose-local.yaml setup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update README dev section with frontend build instructions
Replace Vite dev server tip with npm install/build workflow
and docker restart step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Donald Zou <donaldzou@live.hk>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* A patch to support a wide range of AmneziaWG versions. (#1210)
Support for all keys ever used in AmneziaWG has been added. Setting an empty value to a key will prevent it from being used or rendered in the configuration. This ensures flexible support for all versions and specific configurations.
* Fix config info loss when renaming a tunnel. (#1254)
This migrates data to the new tunnel when renaming, such as: Description, OverridePeerSettings, PeerGroups, PeerHistoricalEndpointTracking, PeerTrafficTracking.
* build(deps-dev): bump @vitejs/plugin-vue in /src/static/app
Bumps [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) from 6.0.4 to 6.0.6.
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@6.0.6/packages/plugin-vue)
---
updated-dependencies:
- dependency-name: "@vitejs/plugin-vue"
dependency-version: 6.0.6
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump bootstrap from 5.3.6 to 5.3.8 in /src/static/client
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 5.3.6 to 5.3.8.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v5.3.6...v5.3.8)
---
updated-dependencies:
- dependency-name: bootstrap
dependency-version: 5.3.8
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* Fix TOTP verification with valid window
* build(deps): bump pymysql from 1.1.2 to 1.1.3 in /src
Bumps [pymysql](https://github.com/PyMySQL/PyMySQL) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/PyMySQL/PyMySQL/releases)
- [Changelog](https://github.com/PyMySQL/PyMySQL/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PyMySQL/PyMySQL/compare/v1.1.2...v1.1.3)
---
updated-dependencies:
- dependency-name: pymysql
dependency-version: 1.1.3
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump psycopg from 3.3.3 to 3.3.4 in /src
Bumps [psycopg](https://github.com/psycopg/psycopg) from 3.3.3 to 3.3.4.
- [Changelog](https://github.com/psycopg/psycopg/blob/master/docs/news.rst)
- [Commits](https://github.com/psycopg/psycopg/compare/3.3.3...3.3.4)
---
updated-dependencies:
- dependency-name: psycopg
dependency-version: 3.3.4
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump npm from 11.12.1 to 11.13.0 in /src/static/app
Bumps [npm](https://github.com/npm/cli) from 11.12.1 to 11.13.0.
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/v11.13.0/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v11.12.1...v11.13.0)
---
updated-dependencies:
- dependency-name: npm
dependency-version: 11.13.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump @vueuse/shared in /src/static/app
Bumps [@vueuse/shared](https://github.com/vueuse/vueuse/tree/HEAD/packages/shared) from 14.2.1 to 14.3.0.
- [Release notes](https://github.com/vueuse/vueuse/releases)
- [Commits](https://github.com/vueuse/vueuse/commits/v14.3.0/packages/shared)
---
updated-dependencies:
- dependency-name: "@vueuse/shared"
dependency-version: 14.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump vue-router from 5.0.4 to 5.0.6 in /src/static/app
Bumps [vue-router](https://github.com/vuejs/router) from 5.0.4 to 5.0.6.
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/compare/v5.0.4...v5.0.6)
---
updated-dependencies:
- dependency-name: vue-router
dependency-version: 5.0.6
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 8.0.9 to 8.0.10 in /src/static/app
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.9 to 8.0.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.10/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.10
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump cidr-tools from 11.3.3 to 11.3.5 in /src/static/app
Bumps [cidr-tools](https://github.com/silverwind/cidr-tools) from 11.3.3 to 11.3.5.
- [Release notes](https://github.com/silverwind/cidr-tools/releases)
- [Commits](https://github.com/silverwind/cidr-tools/compare/11.3.3...11.3.5)
---
updated-dependencies:
- dependency-name: cidr-tools
dependency-version: 11.3.5
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump axios from 1.15.1 to 1.16.0 in /src/static/client
Bumps [axios](https://github.com/axios/axios) from 1.15.1 to 1.16.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.15.1...v1.16.0)
---
updated-dependencies:
- dependency-name: axios
dependency-version: 1.16.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* change email attachmentname to peerName if not empty
* Use network_address for single-address IPs
When parsing allowed_ip entries in API_ping_getAllPeersIpAddress(), detect networks with a single address (ip.num_addresses == 1) and append ip.network_address directly to the parsed list. This replaces the previous host-list construction (list(ip.hosts()) / host[0]) to simplify logic and avoid iterating hosts for /32 or single-address ranges while keeping existing error logging for invalid addresses.
* build(deps): bump requests from 2.32.5 to 2.34.0 in /src
Bumps [requests](https://github.com/psf/requests) from 2.32.5 to 2.34.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.5...v2.34.0)
---
updated-dependencies:
- dependency-name: requests
dependency-version: 2.34.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump gunicorn from 25.0.3 to 26.0.0 in /src
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 25.0.3 to 26.0.0.
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](https://github.com/benoitc/gunicorn/compare/25.0.3...26.0.0)
---
updated-dependencies:
- dependency-name: gunicorn
dependency-version: 26.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pydantic from 2.13.3 to 2.13.4 in /src
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.13.3 to 2.13.4.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/v2.13.4/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.13.3...v2.13.4)
---
updated-dependencies:
- dependency-name: pydantic
dependency-version: 2.13.4
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 8.0.8 to 8.0.12 in /src/static/client
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.8 to 8.0.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.12/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.12
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* Fix Python 3.11 SyntaxError in AmneziaPeer.py (#1290)
Python 3.11 raises 'f-string expression part cannot include a backslash'
on line 91, where strip('\n') sits inside an f-string {...}. PEP 701
lifted this restriction in 3.12.
Bind the decoded output to a local so the strip call happens outside
the f-string, which also removes the duplicate decode+strip already
performed on the preceding length check.
Closes #1289
Signed-off-by: Truffle <truffleagent@gmail.com>
* build(deps): bump vue from 3.5.32 to 3.5.35 in /src/static/client
Bumps [vue](https://github.com/vuejs/core) from 3.5.32 to 3.5.35.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.32...v3.5.35)
---
updated-dependencies:
- dependency-name: vue
dependency-version: 3.5.34
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite-plugin-vue-devtools in /src/static/client
Bumps [vite-plugin-vue-devtools](https://github.com/vuejs/devtools/tree/HEAD/packages/vite) from 8.1.1 to 8.1.2.
- [Release notes](https://github.com/vuejs/devtools/releases)
- [Commits](https://github.com/vuejs/devtools/commits/v8.1.2/packages/vite)
---
updated-dependencies:
- dependency-name: vite-plugin-vue-devtools
dependency-version: 8.1.2
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump vue-router from 4.5.1 to 5.1.0 in /src/static/client
Bumps [vue-router](https://github.com/vuejs/router) from 4.5.1 to 5.1.0.
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/compare/v4.5.1...v5.1.0)
---
updated-dependencies:
- dependency-name: vue-router
dependency-version: 5.0.6
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump requests from 2.34.0 to 2.34.2 in /src
Bumps [requests](https://github.com/psf/requests) from 2.34.0 to 2.34.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.34.0...v2.34.2)
---
updated-dependencies:
- dependency-name: requests
dependency-version: 2.34.2
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump @vuepic/vue-datepicker in /src/static/app
Bumps [@vuepic/vue-datepicker](https://github.com/Vuepic/vue-datepicker) from 12.1.0 to 14.0.0.
- [Release notes](https://github.com/Vuepic/vue-datepicker/releases)
- [Changelog](https://github.com/Vuepic/vue-datepicker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Vuepic/vue-datepicker/compare/v12.1.0...v14.0.0)
---
updated-dependencies:
- dependency-name: "@vuepic/vue-datepicker"
dependency-version: 14.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump flask-cors from 6.0.2 to 6.0.5 in /src
Bumps [flask-cors](https://github.com/corydolphin/flask-cors) from 6.0.2 to 6.0.5.
- [Release notes](https://github.com/corydolphin/flask-cors/releases)
- [Changelog](https://github.com/corydolphin/flask-cors/blob/main/CHANGELOG.md)
- [Commits](https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.5)
---
updated-dependencies:
- dependency-name: flask-cors
dependency-version: 6.0.5
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pymysql from 1.1.3 to 1.2.0 in /src
Bumps [pymysql](https://github.com/PyMySQL/PyMySQL) from 1.1.3 to 1.2.0.
- [Release notes](https://github.com/PyMySQL/PyMySQL/releases)
- [Changelog](https://github.com/PyMySQL/PyMySQL/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PyMySQL/PyMySQL/compare/v1.1.3...v1.2.0)
---
updated-dependencies:
- dependency-name: pymysql
dependency-version: 1.2.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 8.0.10 to 8.0.16 in /src/static/app
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.10 to 8.0.16.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump cidr-tools from 11.3.5 to 12.0.2 in /src/static/app
Bumps [cidr-tools](https://github.com/silverwind/cidr-tools) from 11.3.5 to 12.0.2.
- [Release notes](https://github.com/silverwind/cidr-tools/releases)
- [Commits](https://github.com/silverwind/cidr-tools/compare/11.3.5...12.0.2)
---
updated-dependencies:
- dependency-name: cidr-tools
dependency-version: 12.0.2
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps-dev): bump vite from 8.0.12 to 8.0.16 in /src/static/client
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.12 to 8.0.16.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite)
---
updated-dependencies:
- dependency-name: vite
dependency-version: 8.0.16
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump dayjs from 1.11.20 to 1.11.21 in /src/static/client
Bumps [dayjs](https://github.com/iamkun/dayjs) from 1.11.20 to 1.11.21.
- [Release notes](https://github.com/iamkun/dayjs/releases)
- [Changelog](https://github.com/iamkun/dayjs/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/iamkun/dayjs/compare/v1.11.20...v1.11.21)
---
updated-dependencies:
- dependency-name: dayjs
dependency-version: 1.11.21
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump pyotp from 2.9.0 to 2.10.0 in /src
Bumps [pyotp](https://github.com/pyauth/pyotp) from 2.9.0 to 2.10.0.
- [Release notes](https://github.com/pyauth/pyotp/releases)
- [Changelog](https://github.com/pyauth/pyotp/blob/main/Changes.rst)
- [Commits](https://github.com/pyauth/pyotp/compare/v2.9.0...v2.10.0)
---
updated-dependencies:
- dependency-name: pyotp
dependency-version: 2.10.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump alpine from 3.23 to 3.24 in /docker
Bumps alpine from 3.23 to 3.24.
---
updated-dependencies:
- dependency-name: alpine
dependency-version: '3.24'
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump sqlalchemy from 2.0.49 to 2.0.51 in /src
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.49 to 2.0.51.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)
---
updated-dependencies:
- dependency-name: sqlalchemy
dependency-version: 2.0.51
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
* build(deps): bump axios from 1.16.0 to 1.18.0 in /src/static/client
Bumps [axios](https://github.com/axios/axios) from 1.16.0 to 1.18.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.16.0...v1.18.0)
---
updated-dependencies:
- dependency-name: axios
dependency-version: 1.18.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* Added OIDC for admin side
* Updated OIDC Algorithm Fallback
* chore: remove dist
---------
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Truffle <truffleagent@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Daan Selen <dselen@nerthus.nl>
Co-authored-by: neolegshishov <143963760+neolegshishov@users.noreply.github.com>
Co-authored-by: Tom Mills <accounts+github@tomjmills.co.uk>
Co-authored-by: Giuseppe Marinelli <35118227+BeppeMarnell@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: freetushkan <freetushkan@users.noreply.github.com>
Co-authored-by: sneds91 <sneds91@gmail.com>
Co-authored-by: sgtdeagle <46221457+sgtdeagle@users.noreply.github.com>
Co-authored-by: Truffle <truffleagent@gmail.com>
This commit is contained in:
co-authored by
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Daan Selen
neolegshishov
Tom Mills
Giuseppe Marinelli
Claude Sonnet 4.6
freetushkan
sneds91
sgtdeagle
Truffle
parent
b6da11ec2d
commit
b83c0f85ba
@@ -32,6 +32,8 @@ yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
dist
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist-ssr
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ RUN go version && \
|
||||
# AWG TOOLS BUILDING STAGE
|
||||
# Base: Alpine
|
||||
#
|
||||
FROM alpine:3.23 AS awg-tools
|
||||
FROM alpine:3.24 AS awg-tools
|
||||
|
||||
# Install needed dependencies.
|
||||
RUN apk add --no-cache \
|
||||
|
||||
@@ -213,6 +213,75 @@ ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||
- 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).
|
||||
|
||||
## 🧑💻 Local Development with Docker
|
||||
|
||||
You can develop against WGDashboard locally by mounting the `src/` directory into the container. This lets you edit Python and frontend code on your host and see changes reflected immediately (with a service restart for Python).
|
||||
|
||||
Create a `docker/compose-local.yaml` alongside the existing `compose.yaml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
wgdashboard:
|
||||
image: ghcr.io/wgdashboard/wgdashboard:latest
|
||||
restart: unless-stopped
|
||||
container_name: wgdashboard
|
||||
|
||||
ports:
|
||||
- 10086:10086/tcp
|
||||
- 51820:51820/udp
|
||||
|
||||
volumes:
|
||||
- aconf:/etc/amnezia/amneziawg
|
||||
- conf:/etc/wireguard
|
||||
- data:/data
|
||||
# Mount local src for live editing
|
||||
- ../src:/opt/wgdashboard/src
|
||||
# Keep venv in a named volume so it isn't overwritten by the mount
|
||||
- venv:/opt/wgdashboard/src/venv
|
||||
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
|
||||
volumes:
|
||||
aconf:
|
||||
conf:
|
||||
data:
|
||||
venv:
|
||||
```
|
||||
|
||||
The key additions compared to the production compose file:
|
||||
- `../src:/opt/wgdashboard/src` — mounts your local `src/` directory into the container so code changes are reflected without rebuilding the image.
|
||||
- `venv:/opt/wgdashboard/src/venv` — keeps the Python virtual environment in a named Docker volume. Without this, the host mount would overwrite the venv created during image build.
|
||||
|
||||
To start the development container:
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker compose -f compose-local.yaml up -d
|
||||
```
|
||||
|
||||
After editing Python files (e.g. `src/dashboard.py`), restart the container to pick up changes:
|
||||
|
||||
```bash
|
||||
docker restart wgdashboard
|
||||
```
|
||||
|
||||
For frontend changes, install dependencies and rebuild the Vue app on your host:
|
||||
|
||||
```bash
|
||||
cd src/static/app
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Then restart the container so it serves the updated dist files:
|
||||
|
||||
```bash
|
||||
docker restart wgdashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Closing remarks:
|
||||
|
||||
For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.
|
||||
|
||||
+2
-2
@@ -100,7 +100,7 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
|
||||
date = datetime.datetime.now(tz=datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
emailSender = EmailSender(dashboardConfig)
|
||||
if not emailSender.ready():
|
||||
if not emailSender.is_ready():
|
||||
return ResponseObject(False, "We can't send you an email due to your Administrator has not setup email service. Please contact your administrator.")
|
||||
|
||||
data = request.get_json()
|
||||
@@ -244,4 +244,4 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
|
||||
|
||||
return ResponseObject(status, message)
|
||||
|
||||
return client
|
||||
return client
|
||||
|
||||
+140
-47
@@ -2,13 +2,15 @@ import logging
|
||||
import random, shutil, sqlite3, configparser, hashlib, ipaddress, json, os, secrets, subprocess
|
||||
import time, re, uuid, bcrypt, psutil, pyotp, threading
|
||||
import traceback
|
||||
from functools import wraps
|
||||
from urllib.parse import unquote
|
||||
from uuid import uuid4
|
||||
from zipfile import ZipFile
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import sqlalchemy
|
||||
from jinja2 import Template
|
||||
from flask import Flask, request, render_template, session, send_file, current_app
|
||||
from flask import Flask, request, render_template, session, send_file, current_app, redirect, url_for
|
||||
from flask_cors import CORS
|
||||
from icmplib import ping, traceroute
|
||||
from flask.json.provider import DefaultJSONProvider
|
||||
@@ -30,6 +32,7 @@ from modules.PeerJobs import PeerJobs
|
||||
from modules.DashboardConfig import DashboardConfig
|
||||
from modules.WireguardConfiguration import WireguardConfiguration
|
||||
from modules.AmneziaConfiguration import AmneziaConfiguration
|
||||
from modules.DashboardOIDC import DashboardOIDC
|
||||
|
||||
from client import createClientBlueprint
|
||||
|
||||
@@ -68,6 +71,21 @@ def ResponseObject(status=True, message=None, data=None, status_code = 200) -> F
|
||||
response.content_type = "application/json"
|
||||
return response
|
||||
|
||||
def require_fields(*fields):
|
||||
"""Decorator that validates required fields in request.json."""
|
||||
def decorator(f):
|
||||
@wraps(f)
|
||||
def decorated(*args, **kwargs):
|
||||
data = request.json
|
||||
if data is None:
|
||||
return ResponseObject(False, "Request body must be JSON", status_code=400)
|
||||
missing = [field for field in fields if field not in data]
|
||||
if missing:
|
||||
return ResponseObject(False, f"Missing required fields: {', '.join(missing)}", status_code=400)
|
||||
return f(*args, **kwargs)
|
||||
return decorated
|
||||
return decorator
|
||||
|
||||
'''
|
||||
Flask App
|
||||
'''
|
||||
@@ -208,6 +226,7 @@ with app.app_context():
|
||||
NewConfigurationTemplates: NewConfigurationTemplates = NewConfigurationTemplates()
|
||||
InitWireguardConfigurationsList(startup=True)
|
||||
DashboardClients: DashboardClients = DashboardClients(WireguardConfigurations)
|
||||
AdminOIDC = DashboardOIDC("Admin")
|
||||
app.register_blueprint(createClientBlueprint(WireguardConfigurations, DashboardConfig, DashboardClients))
|
||||
|
||||
_, APP_PREFIX = DashboardConfig.GetConfig("Server", "app_prefix")
|
||||
@@ -262,6 +281,8 @@ def auth_req():
|
||||
f'{appPrefix}/api/sharePeer/get',
|
||||
f'{appPrefix}/api/isTotpEnabled',
|
||||
f'{appPrefix}/api/locale',
|
||||
f'{appPrefix}/api/oidc/providers',
|
||||
f'{appPrefix}/api/oidc/authenticate',
|
||||
]
|
||||
|
||||
|
||||
@@ -299,6 +320,38 @@ def API_ValidateAuthentication():
|
||||
def API_RequireAuthentication():
|
||||
return ResponseObject(data=DashboardConfig.GetConfig("Server", "auth_req")[1])
|
||||
|
||||
# OIDC for Admin
|
||||
@app.get(f'{APP_PREFIX}/api/oidc/providers')
|
||||
def API_OIDC_GetProviders():
|
||||
_, oidc = DashboardConfig.GetConfig("OIDC", "admin_enable")
|
||||
if not oidc:
|
||||
return ResponseObject(status=False, message="OIDC is disabled")
|
||||
|
||||
return ResponseObject(data=AdminOIDC.GetProviders())
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/oidc/authenticate')
|
||||
def API_OIDC_Authenticate():
|
||||
_, oidc = DashboardConfig.GetConfig("OIDC", "admin_enable")
|
||||
if not oidc:
|
||||
return ResponseObject(False, "OIDC is disabled")
|
||||
|
||||
requestData = request.get_json()
|
||||
status, data = AdminOIDC.VerifyToken(**requestData)
|
||||
if not status:
|
||||
return ResponseObject(False, "OIDC Authentication Failed. Reason: " + data)
|
||||
session['role'] = 'admin'
|
||||
authToken = hashlib.sha256(f'${data['sid']}{datetime.now()}{app.secret_key}'.encode()).hexdigest()
|
||||
session['username'] = authToken
|
||||
session['signInMethod'] = 'OIDC'
|
||||
session['signInPayload'] = {
|
||||
"Provider": requestData.get('provider'),
|
||||
"Payload": data
|
||||
}
|
||||
resp = ResponseObject()
|
||||
resp.set_cookie('authToken', authToken)
|
||||
return resp
|
||||
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/authenticate')
|
||||
def API_AuthenticateLogin():
|
||||
data = request.get_json()
|
||||
@@ -318,7 +371,10 @@ def API_AuthenticateLogin():
|
||||
totpEnabled = DashboardConfig.GetConfig("Account", "enable_totp")[1]
|
||||
totpValid = False
|
||||
if totpEnabled:
|
||||
totpValid = pyotp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).now() == data['totp']
|
||||
totp_code = str(data.get("totp", "")).strip()
|
||||
totpValid = pyotp.TOTP(
|
||||
DashboardConfig.GetConfig("Account", "totp_key")[1]
|
||||
).verify(totp_code, valid_window=1)
|
||||
|
||||
if (valid
|
||||
and data['username'] == DashboardConfig.GetConfig("Account", "username")[1]
|
||||
@@ -327,6 +383,7 @@ def API_AuthenticateLogin():
|
||||
authToken = hashlib.sha256(f"{data['username']}{datetime.now()}".encode()).hexdigest()
|
||||
session['role'] = 'admin'
|
||||
session['username'] = authToken
|
||||
session['signInMethod'] = 'local'
|
||||
resp = ResponseObject(True, DashboardConfig.GetConfig("Other", "welcome_session")[1])
|
||||
resp.set_cookie("authToken", authToken)
|
||||
session.permanent = True
|
||||
@@ -342,6 +399,14 @@ def API_AuthenticateLogin():
|
||||
def API_SignOut():
|
||||
resp = ResponseObject(True, "")
|
||||
resp.delete_cookie("authToken")
|
||||
if session.get('signInMethod') == "OIDC":
|
||||
status, oidc_config = AdminOIDC.GetProviderConfiguration(session.get('signInPayload').get("Provider"))
|
||||
signOut = requests.get(
|
||||
oidc_config.get("end_session_endpoint"),
|
||||
params={
|
||||
'id_token_hint': session.get('signInPayload').get("Payload").get('sid')
|
||||
}
|
||||
)
|
||||
session.clear()
|
||||
return resp
|
||||
|
||||
@@ -1204,52 +1269,75 @@ def API_getDashboardTheme():
|
||||
def API_getDashboardVersion():
|
||||
return ResponseObject(data=DashboardConfig.GetConfig("Server", "version")[1])
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/savePeerScheduleJob')
|
||||
@app.post(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('Configuration', 'Peer', 'Field', 'Operator', 'Value', 'Action')
|
||||
def API_savePeerScheduleJob():
|
||||
data = request.json
|
||||
if "Job" not in data.keys():
|
||||
return ResponseObject(False, "Please specify job")
|
||||
job: dict = data['Job']
|
||||
if "Peer" not in job.keys() or "Configuration" not in job.keys():
|
||||
return ResponseObject(False, "Please specify peer and configuration")
|
||||
configuration = WireguardConfigurations.get(job['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
f, fp = configuration.searchPeer(job['Peer'])
|
||||
if not f:
|
||||
return ResponseObject(False, "Peer does not exist")
|
||||
|
||||
|
||||
s, p = AllPeerJobs.saveJob(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
if s:
|
||||
return ResponseObject(s, data=p)
|
||||
return ResponseObject(s, message=p)
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/deletePeerScheduleJob')
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
peerKey = unquote(data['Peer'])
|
||||
found, _ = configuration.searchPeer(peerKey)
|
||||
if not found:
|
||||
return ResponseObject(False, "Peer does not exist", status_code=404)
|
||||
|
||||
jobID = data.get('JobID', str(uuid4()))
|
||||
if len(AllPeerJobs.searchJobById(jobID)) > 0:
|
||||
return ResponseObject(False, "Job already exists", status_code=409)
|
||||
|
||||
success, result = AllPeerJobs.saveJob(PeerJob(
|
||||
jobID, data['Configuration'], peerKey, data['Field'], data['Operator'], data['Value'],
|
||||
datetime.now(), data.get('ExpireDate'), data['Action']))
|
||||
if success:
|
||||
return ResponseObject(success, data=result)
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.put(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('JobID', 'Configuration', 'Peer', 'Field', 'Operator', 'Value', 'Action')
|
||||
def API_updatePeerScheduleJob():
|
||||
data = request.json
|
||||
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
peerKey = unquote(data['Peer'])
|
||||
found, _ = configuration.searchPeer(peerKey)
|
||||
if not found:
|
||||
return ResponseObject(False, "Peer does not exist", status_code=404)
|
||||
|
||||
existing = AllPeerJobs.searchJobById(data['JobID'])
|
||||
if len(existing) == 0:
|
||||
return ResponseObject(False, "Job does not exist", status_code=404)
|
||||
|
||||
success, result = AllPeerJobs.saveJob(PeerJob(
|
||||
data['JobID'], data['Configuration'], peerKey, data['Field'], data['Operator'], data['Value'],
|
||||
datetime.now(), data.get('ExpireDate'), data['Action']))
|
||||
if success:
|
||||
return ResponseObject(success, data=result)
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.delete(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('JobID', 'Configuration', 'Peer')
|
||||
def API_deletePeerScheduleJob():
|
||||
data = request.json
|
||||
if "Job" not in data.keys():
|
||||
return ResponseObject(False, "Please specify job")
|
||||
job: dict = data['Job']
|
||||
if "Peer" not in job.keys() or "Configuration" not in job.keys():
|
||||
return ResponseObject(False, "Please specify peer and configuration")
|
||||
configuration = WireguardConfigurations.get(job['Configuration'])
|
||||
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
# f, fp = configuration.searchPeer(job['Peer'])
|
||||
# if not f:
|
||||
# return ResponseObject(False, "Peer does not exist")
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
s, p = AllPeerJobs.deleteJob(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
if s:
|
||||
return ResponseObject(s)
|
||||
return ResponseObject(s, message=p)
|
||||
peerKey = unquote(data['Peer'])
|
||||
success, result = AllPeerJobs.deleteJob(PeerJob(
|
||||
data['JobID'], data['Configuration'], peerKey, data.get('Field', ''),
|
||||
data.get('Operator', ''), data.get('Value', ''),
|
||||
datetime.now(), data.get('ExpireDate'), data.get('Action', '')))
|
||||
if success:
|
||||
return ResponseObject(success, message="Job deleted successfully")
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.get(f'{APP_PREFIX}/api/getPeerScheduleJobLogs/<configName>')
|
||||
@app.get(f'{APP_PREFIX}/api/PeerScheduleJobLogs/<configName>')
|
||||
def API_getPeerScheduleJobLogs(configName):
|
||||
if configName not in WireguardConfigurations.keys():
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
@@ -1274,11 +1362,11 @@ def API_ping_getAllPeersIpAddress():
|
||||
for x in allowed_ip:
|
||||
try:
|
||||
ip = ipaddress.ip_network(x, strict=False)
|
||||
if ip.num_addresses == 1:
|
||||
parsed.append(str(ip.network_address))
|
||||
except ValueError as e:
|
||||
app.logger.error(f"Failed to parse IP address of {p.id} - {c.Name}")
|
||||
host = list(ip.hosts())
|
||||
if len(host) == 1:
|
||||
parsed.append(str(host[0]))
|
||||
|
||||
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
|
||||
if len(p.name) > 0:
|
||||
cips[f"{p.name} - {p.id}"] = {
|
||||
@@ -1415,11 +1503,15 @@ def API_Welcome_GetTotpLink():
|
||||
@app.post(f'{APP_PREFIX}/api/Welcome_VerifyTotpLink')
|
||||
def API_Welcome_VerifyTotpLink():
|
||||
data = request.get_json()
|
||||
totp = pyotp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).now()
|
||||
if totp == data['totp']:
|
||||
totp_code = str(data.get("totp", "")).strip()
|
||||
totpValid = pyotp.TOTP(
|
||||
DashboardConfig.GetConfig("Account", "totp_key")[1]
|
||||
).verify(totp_code, valid_window=1)
|
||||
|
||||
if totpValid:
|
||||
DashboardConfig.SetConfig("Account", "totp_verified", "true")
|
||||
DashboardConfig.SetConfig("Account", "enable_totp", "true")
|
||||
return ResponseObject(totp == data['totp'])
|
||||
return ResponseObject(totpValid)
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/Welcome_Finish')
|
||||
def API_Welcome_Finish():
|
||||
@@ -1511,7 +1603,8 @@ def API_Email_Send():
|
||||
subject = Template(data.get('Subject', '')).render(peer=p.toJson(), configurationFile=download)
|
||||
if data.get('IncludeAttachment', False):
|
||||
u = str(uuid4())
|
||||
attachmentName = f'{u}.conf'
|
||||
peerName = p.toJson().get('name', '').strip()
|
||||
attachmentName = f'{peerName if peerName else u}.conf'
|
||||
with open(os.path.join('./attachments', attachmentName,), 'w+') as f:
|
||||
f.write(download['file'])
|
||||
|
||||
|
||||
@@ -32,11 +32,15 @@ class AmneziaConfiguration(WireguardConfiguration):
|
||||
self.H2 = 2
|
||||
self.H3 = 3
|
||||
self.H4 = 4
|
||||
self.I1 = "0"
|
||||
self.I2 = "0"
|
||||
self.I3 = "0"
|
||||
self.I4 = "0"
|
||||
self.I5 = "0"
|
||||
self.I1 = ""
|
||||
self.I2 = ""
|
||||
self.I3 = ""
|
||||
self.I4 = ""
|
||||
self.I5 = ""
|
||||
self.J1 = ""
|
||||
self.J2 = ""
|
||||
self.J3 = ""
|
||||
self.Itime = ""
|
||||
|
||||
super().__init__(DashboardConfig, AllPeerJobs, AllPeerShareLinks, DashboardWebHooks, name, data, backup, startup, wg=False)
|
||||
|
||||
@@ -79,7 +83,11 @@ class AmneziaConfiguration(WireguardConfiguration):
|
||||
"I2": self.I2,
|
||||
"I3": self.I3,
|
||||
"I4": self.I4,
|
||||
"I5": self.I5
|
||||
"I5": self.I5,
|
||||
"J1": self.J1,
|
||||
"J2": self.J2,
|
||||
"J3": self.J3,
|
||||
"Itime": self.Itime
|
||||
}
|
||||
|
||||
def createDatabase(self, dbName = None):
|
||||
|
||||
@@ -87,8 +87,9 @@ class AmneziaPeer(Peer):
|
||||
|
||||
if psk_exist: os.remove(uid)
|
||||
|
||||
if len(updateAllowedIp.decode().strip("\n")) != 0:
|
||||
current_app.logger.error(f"Update peer failed when updating Allowed IPs.\nInput: {newAllowedIPs}\nOutput: {updateAllowedIp.decode().strip('\n')}")
|
||||
output = updateAllowedIp.decode().strip("\n")
|
||||
if len(output) != 0:
|
||||
current_app.logger.error(f"Update peer failed when updating Allowed IPs.\nInput: {newAllowedIPs}\nOutput: {output}")
|
||||
return False, "Internal server error"
|
||||
|
||||
command = [f"{self.configuration.Protocol}-quick", "save", self.configuration.Name]
|
||||
|
||||
@@ -12,7 +12,7 @@ from .Utilities import (GetRemoteEndpoint, ValidateDNSAddress)
|
||||
from .DashboardAPIKey import DashboardAPIKey
|
||||
|
||||
class DashboardConfig:
|
||||
DashboardVersion = 'v4.3.3'
|
||||
DashboardVersion = 'v4.3.4'
|
||||
ConfigurationPath = os.getenv('CONFIGURATION_PATH', '.')
|
||||
ConfigurationFilePath = os.path.join(ConfigurationPath, 'wg-dashboard.ini')
|
||||
|
||||
@@ -51,7 +51,8 @@ class DashboardConfig:
|
||||
"peer_display_mode": "grid",
|
||||
"remote_endpoint": GetRemoteEndpoint(),
|
||||
"peer_MTU": "1420",
|
||||
"peer_keep_alive": "21"
|
||||
"peer_keep_alive": "21",
|
||||
"peer_preshared_key_default": "false"
|
||||
},
|
||||
"Other": {
|
||||
"welcome_session": "true"
|
||||
@@ -153,10 +154,10 @@ class DashboardConfig:
|
||||
|
||||
def getConnectionString(self, database) -> str or None:
|
||||
sqlitePath = os.path.join(DashboardConfig.ConfigurationPath, "db")
|
||||
|
||||
|
||||
if not os.path.isdir(sqlitePath):
|
||||
os.mkdir(sqlitePath)
|
||||
|
||||
|
||||
if self.GetConfig("Database", "type")[1] == "postgresql":
|
||||
cn = f'postgresql+psycopg2://{self.GetConfig("Database", "username")[1]}:{self.GetConfig("Database", "password")[1]}@{self.GetConfig("Database", "host")[1]}/{database}'
|
||||
elif self.GetConfig("Database", "type")[1] == "mysql":
|
||||
|
||||
@@ -82,13 +82,18 @@ class DashboardOIDC:
|
||||
|
||||
headers = jwt.get_unverified_header(id_token)
|
||||
kid = headers["kid"]
|
||||
|
||||
|
||||
key = next(k for k in jwks["keys"] if k["kid"] == kid)
|
||||
|
||||
|
||||
alg = key.get("alg") or headers.get("alg")
|
||||
supported_algs = oidc_config.get("id_token_signing_alg_values_supported")
|
||||
if supported_algs and alg not in supported_algs:
|
||||
return False, f"Unsupported token signing algorithm: {alg}"
|
||||
|
||||
payload = jwt.decode(
|
||||
id_token,
|
||||
key,
|
||||
algorithms=[key["alg"]],
|
||||
algorithms=[alg],
|
||||
audience=provider_info.get('client_id'),
|
||||
issuer=issuer,
|
||||
access_token=access_token
|
||||
@@ -134,7 +139,7 @@ class DashboardOIDC:
|
||||
'openid_configuration': oidc_config
|
||||
}
|
||||
self.provider_secret[k] = providers[k]['client_secret']
|
||||
current_app.logger.info(f"Registered OIDC Provider: {k}")
|
||||
current_app.logger.info(f"Registered OIDC Provider[{self.mode}]: {k}")
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to register OIDC config for {k}", exc_info=e)
|
||||
except Exception as e:
|
||||
|
||||
+5
-1
@@ -206,7 +206,11 @@ class Peer:
|
||||
"I2": self.configuration.I2,
|
||||
"I3": self.configuration.I3,
|
||||
"I4": self.configuration.I4,
|
||||
"I5": self.configuration.I5
|
||||
"I5": self.configuration.I5,
|
||||
"J1": self.configuration.J1,
|
||||
"J2": self.configuration.J2,
|
||||
"J3": self.configuration.J3,
|
||||
"Itime": self.configuration.Itime
|
||||
})
|
||||
|
||||
peerSection = {
|
||||
|
||||
@@ -109,23 +109,31 @@ class WireguardConfiguration:
|
||||
}
|
||||
|
||||
if self.Protocol == 'awg':
|
||||
self.__parser["Interface"]["Jc"] = self.Jc
|
||||
self.__parser["Interface"]["Jc"] = self.Jc
|
||||
self.__parser["Interface"]["Jmin"] = self.Jmin
|
||||
self.__parser["Interface"]["Jmax"] = self.Jmax
|
||||
self.__parser["Interface"]["S1"] = self.S1
|
||||
self.__parser["Interface"]["S2"] = self.S2
|
||||
self.__parser["Interface"]["S3"] = self.S3
|
||||
self.__parser["Interface"]["S4"] = self.S4
|
||||
self.__parser["Interface"]["H1"] = self.H1
|
||||
self.__parser["Interface"]["H2"] = self.H2
|
||||
self.__parser["Interface"]["H3"] = self.H3
|
||||
self.__parser["Interface"]["H4"] = self.H4
|
||||
self.__parser["Interface"]["I1"] = self.I1
|
||||
self.__parser["Interface"]["I2"] = self.I2
|
||||
self.__parser["Interface"]["I3"] = self.I3
|
||||
self.__parser["Interface"]["I4"] = self.I4
|
||||
self.__parser["Interface"]["I5"] = self.I5
|
||||
values = {
|
||||
"Jc": self.Jc,
|
||||
"Jmin": self.Jmin,
|
||||
"Jmax": self.Jmax,
|
||||
"S1": self.S1,
|
||||
"S2": self.S2,
|
||||
"S3": self.S3,
|
||||
"S4": self.S4,
|
||||
"H1": self.H1,
|
||||
"H2": self.H2,
|
||||
"H3": self.H3,
|
||||
"H4": self.H4,
|
||||
"I1": self.I1,
|
||||
"I2": self.I2,
|
||||
"I3": self.I3,
|
||||
"I4": self.I4,
|
||||
"I5": self.I5,
|
||||
"J1": self.J1,
|
||||
"J2": self.J2,
|
||||
"J3": self.J3,
|
||||
"Itime": self.Itime
|
||||
}
|
||||
for key, value in values.items():
|
||||
if value != None and str(value).strip():
|
||||
self.__parser["Interface"][key] = str(value)
|
||||
|
||||
if "Backup" not in data.keys():
|
||||
self.createDatabase()
|
||||
@@ -1014,8 +1022,10 @@ class WireguardConfiguration:
|
||||
with open(self.configPath, 'r') as f:
|
||||
original = [l.rstrip("\n") for l in f.readlines()]
|
||||
allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort", "Table"]
|
||||
awgKeys = []
|
||||
if self.Protocol == 'awg':
|
||||
allowEdit += ["Jc", "Jmin", "Jmax", "S1", "S2", "S3", "S4", "H1", "H2", "H3", "H4", "I1", "I2", "I3", "I4", "I5"]
|
||||
awgKeys = ["Jc", "Jmin", "Jmax", "S1", "S2", "S3", "S4", "H1", "H2", "H3", "H4", "I1", "I2", "I3", "I4", "I5", "J1", "J2", "J3", "Itime"]
|
||||
allowEdit += awgKeys
|
||||
start = original.index("[Interface]")
|
||||
try:
|
||||
end = original.index("[Peer]")
|
||||
@@ -1029,7 +1039,10 @@ class WireguardConfiguration:
|
||||
if split[0] not in allowEdit:
|
||||
new.append(original[line])
|
||||
for key in allowEdit:
|
||||
new.insert(1, f"{key} = {str(newData[key]).strip()}")
|
||||
val = str(newData.get(key, "")).strip()
|
||||
if key in awgKeys and val == "":
|
||||
continue
|
||||
new.insert(1, f"{key} = {val}")
|
||||
new.append("")
|
||||
for line in range(end, len(original)):
|
||||
new.append(original[line])
|
||||
@@ -1079,6 +1092,11 @@ class WireguardConfiguration:
|
||||
doRenameStatement("_restrict_access")
|
||||
doRenameStatement("_deleted")
|
||||
doRenameStatement("_transfer")
|
||||
conn.execute(
|
||||
self.infoTable.update()
|
||||
.where(self.infoTable.c.ID == self.Name)
|
||||
.values(ID=newConfigurationName)
|
||||
)
|
||||
|
||||
self.AllPeerJobs.updateJobConfigurationName(self.Name, newConfigurationName)
|
||||
shutil.copy(
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
bcrypt==5.0.0
|
||||
ifcfg==0.24
|
||||
psutil==7.2.2
|
||||
pyotp==2.9.0
|
||||
pyotp==2.10.0
|
||||
Flask==3.1.2
|
||||
flask-cors==6.0.2
|
||||
flask-cors==6.0.5
|
||||
icmplib==3.0.4
|
||||
gunicorn==25.0.3
|
||||
requests==2.32.5
|
||||
gunicorn==26.0.0
|
||||
requests==2.34.2
|
||||
tcconfig==0.30.1
|
||||
sqlalchemy==2.0.46
|
||||
sqlalchemy==2.0.51
|
||||
sqlalchemy_utils==0.42.1
|
||||
psycopg[binary]==3.3.3
|
||||
PyMySQL==1.1.2
|
||||
psycopg[binary]==3.3.4
|
||||
PyMySQL==1.2.0
|
||||
tzlocal==5.3.1
|
||||
python-jose==3.5.0
|
||||
pydantic==2.12.5
|
||||
pydantic==2.13.4
|
||||
|
||||
@@ -11,6 +11,26 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WGDashboard</title>
|
||||
<base href="./">
|
||||
<style>
|
||||
#preloader{
|
||||
width: 100vw; height: 100vh; display: flex
|
||||
}
|
||||
#preloader_placeholder{
|
||||
width: 50px; height: 50px; background-color: #000; margin: auto;
|
||||
animation: 3s ease-in-out fadeInPreloader infinite;
|
||||
}
|
||||
@keyframes fadeInPreloader {
|
||||
0%{
|
||||
opacity: 0;
|
||||
}
|
||||
50%{
|
||||
opacity: 1;
|
||||
}
|
||||
100%{
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const isViteDevMode = document.querySelector('script[src*="@vite/client"]') !== null;
|
||||
const base = document.querySelector('base');
|
||||
@@ -20,7 +40,13 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
<div id="preloader">
|
||||
<div id="preloader_placeholder">
|
||||
<img style="width: 100%" src="./img/Logo-2-128x128.png" alt="WGDashboard Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="./src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Generated
+865
-1102
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app",
|
||||
"version": "4.3.3",
|
||||
"version": "4.3.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"module": "es2022",
|
||||
@@ -13,35 +13,35 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@volar/language-server": "2.4.28",
|
||||
"@vue/language-server": "3.2.4",
|
||||
"@vuepic/vue-datepicker": "^12.1.0",
|
||||
"@vue/language-server": "3.2.7",
|
||||
"@vuepic/vue-datepicker": "^14.0.0",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"@vueuse/shared": "^14.1.0",
|
||||
"@vueuse/shared": "^14.3.0",
|
||||
"animate.css": "^4.1.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"cidr-tools": "^11.3.2",
|
||||
"cidr-tools": "^12.0.2",
|
||||
"css-color-converter": "^2.0.0",
|
||||
"dayjs": "^1.11.19",
|
||||
"electron-builder": "^26.7.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"fuse.js": "^7.3.0",
|
||||
"i": "^0.3.7",
|
||||
"is-cidr": "^6.0.3",
|
||||
"npm": "^11.8.0",
|
||||
"ol": "^10.7.0",
|
||||
"npm": "^11.13.0",
|
||||
"ol": "^10.9.0",
|
||||
"pinia": "^3.0.4",
|
||||
"pinia-plugin-persistedstate": "^4.7.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"qrcodejs": "^1.0.0",
|
||||
"simple-code-editor": "^2.0.9",
|
||||
"uuid": "^13.0.0",
|
||||
"vue": "^3.5.31",
|
||||
"uuid": "^14.0.0",
|
||||
"vue": "^3.5.32",
|
||||
"vue-chartjs": "^5.3.3",
|
||||
"vue-router": "^5.0.4"
|
||||
"vue-router": "^5.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"vite": "^7.3.1"
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"vite": "^8.0.16"
|
||||
},
|
||||
"overrides": {
|
||||
"tar": "^7.5.6"
|
||||
|
||||
+14
-5
@@ -6,18 +6,27 @@ export default {
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
saving: Boolean,
|
||||
defaultEnabled: Boolean
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
enable: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const hasKey = !!(this.data && this.data.preshared_key && this.data.preshared_key.length > 0)
|
||||
if (hasKey || this.defaultEnabled){
|
||||
this.enable = true
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
enable(){
|
||||
if (this.enable){
|
||||
this.data.preshared_key = window.wireguard.generateKeypair().presharedKey
|
||||
}else {
|
||||
if (this.enable) {
|
||||
if (!this.data.preshared_key){
|
||||
this.data.preshared_key = window.wireguard.generateKeypair().presharedKey
|
||||
}
|
||||
} else {
|
||||
this.data.preshared_key = ""
|
||||
}
|
||||
}
|
||||
@@ -48,4 +57,4 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -32,7 +32,7 @@ const peerData = ref({
|
||||
keepalive: parseInt(dashboardStore.Configuration.Peers.peer_keep_alive),
|
||||
mtu: parseInt(dashboardStore.Configuration.Peers.peer_mtu),
|
||||
preshared_key: "",
|
||||
preshared_key_bulkAdd: false,
|
||||
preshared_key_bulkAdd: Boolean(dashboardStore.Configuration.Peers.peer_preshared_key_default),
|
||||
allowed_ips_validation: true,
|
||||
})
|
||||
const availableIp = ref([])
|
||||
@@ -128,7 +128,7 @@ watch(() => {
|
||||
<EndpointAllowedIps :saving="saving" :data="peerData"></EndpointAllowedIps>
|
||||
<div class="row gy-3">
|
||||
<div class="col-sm" v-if="!peerData.bulkAdd">
|
||||
<PresharedKeyInput :saving="saving" :data="peerData" :bulk="peerData.bulkAdd"></PresharedKeyInput>
|
||||
<PresharedKeyInput :saving="saving" :data="peerData" :bulk="peerData.bulkAdd" :defaultEnabled="Boolean(dashboardStore.Configuration.Peers.peer_preshared_key_default)"></PresharedKeyInput>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
@@ -177,4 +177,4 @@ watch(() => {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -36,7 +36,7 @@ export default {
|
||||
keepalive: parseInt(this.dashboardStore.Configuration.Peers.peer_keep_alive),
|
||||
mtu: parseInt(this.dashboardStore.Configuration.Peers.peer_mtu),
|
||||
preshared_key: "",
|
||||
preshared_key_bulkAdd: false,
|
||||
preshared_key_bulkAdd: Boolean(this.dashboardStore.Configuration.Peers.peer_preshared_key_default),
|
||||
},
|
||||
availableIp: undefined,
|
||||
availableIpSearchString: "",
|
||||
@@ -133,7 +133,7 @@ export default {
|
||||
<hr class="mb-0 mt-2">
|
||||
<div class="row gy-3">
|
||||
<div class="col-sm" v-if="!this.data.bulkAdd">
|
||||
<PresharedKeyInput :saving="saving" :data="data" :bulk="this.data.bulkAdd"></PresharedKeyInput>
|
||||
<PresharedKeyInput :saving="saving" :data="data" :bulk="this.data.bulkAdd" :defaultEnabled="Boolean(this.dashboardStore.Configuration.Peers.peer_preshared_key_default)"></PresharedKeyInput>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
@@ -187,4 +187,4 @@ div{
|
||||
.card{
|
||||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
methods: {
|
||||
async fetchLog(){
|
||||
this.dataLoading = true;
|
||||
await fetchGet(`/api/getPeerScheduleJobLogs/${this.configurationInfo.Name}`, {}, (res) => {
|
||||
await fetchGet(`/api/PeerScheduleJobLogs/${this.configurationInfo.Name}`, {}, (res) => {
|
||||
this.data = res.data;
|
||||
this.logFetchTime = dayjs().format("YYYY-MM-DD HH:mm:ss")
|
||||
this.dataLoading = false;
|
||||
|
||||
+4
-7
@@ -2,7 +2,7 @@
|
||||
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
|
||||
import {ref} from "vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {fetchPost} from "@/utilities/fetch.js";
|
||||
import {fetchPost, fetchPut, fetchDelete} from "@/utilities/fetch.js";
|
||||
import { VueDatePicker } from "@vuepic/vue-datepicker";
|
||||
import dayjs from "dayjs";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
@@ -46,9 +46,8 @@ export default {
|
||||
methods: {
|
||||
save(){
|
||||
if (this.job.Field && this.job.Operator && this.job.Action && this.job.Value){
|
||||
fetchPost(`/api/savePeerScheduleJob`, {
|
||||
Job: this.job
|
||||
}, (res) => {
|
||||
const fn = this.newJob ? fetchPost : fetchPut;
|
||||
fn(`/api/PeerScheduleJob`, this.job, (res) => {
|
||||
if (res.status){
|
||||
this.edit = false;
|
||||
this.store.newMessage("Server", "Peer job saved", "success")
|
||||
@@ -84,9 +83,7 @@ export default {
|
||||
},
|
||||
delete(){
|
||||
if(this.job.CreationDate){
|
||||
fetchPost(`/api/deletePeerScheduleJob`, {
|
||||
Job: this.job
|
||||
}, (res) => {
|
||||
fetchDelete(`/api/PeerScheduleJob`, this.job, (res) => {
|
||||
if (!res.status){
|
||||
this.store.newMessage("Server", res.message, "danger")
|
||||
this.$emit('delete')
|
||||
|
||||
@@ -22,6 +22,8 @@ import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefau
|
||||
targetData="peer_mtu" title="MTU"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="peer_keep_alive" title="Persistent Keepalive"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="peer_preshared_key_default" title="Pre-Shared Key Default"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="remote_endpoint" title="Peer Remote Endpoint"
|
||||
:warning="true" warningText="This will be changed globally, and will be apply to all peer's QR code and configuration file."
|
||||
@@ -34,4 +36,4 @@ import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefau
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -31,6 +31,11 @@ export default {
|
||||
mounted() {
|
||||
this.value = this.store.Configuration.Peers[this.targetData];
|
||||
},
|
||||
computed: {
|
||||
isBoolean(){
|
||||
return typeof this.value === "boolean"
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
async useValidation(){
|
||||
if(this.changed){
|
||||
@@ -67,7 +72,14 @@ export default {
|
||||
<LocaleText :t="this.title"></LocaleText>
|
||||
</small></strong>
|
||||
</label>
|
||||
<input type="text" class="form-control"
|
||||
<div v-if="isBoolean" class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
v-model="this.value"
|
||||
:id="this.uuid"
|
||||
@change="this.changed = true; useValidation()"
|
||||
:disabled="this.updating">
|
||||
</div>
|
||||
<input v-else type="text" class="form-control"
|
||||
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
|
||||
:id="this.uuid"
|
||||
v-model="this.value"
|
||||
@@ -88,4 +100,4 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup async>
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
const providers = ref([])
|
||||
const oidcEnabled = ref(false)
|
||||
|
||||
await fetchGet("/api/oidc/providers", {}, async (res) => {
|
||||
if (res.status){
|
||||
await Promise.all(Object.entries(res.data).map(([key, value]) => {
|
||||
return fetch(`${value.issuer}/.well-known/openid-configuration`).then((res) => {
|
||||
providers.value.push({
|
||||
Provider: key,
|
||||
ProviderInfo: value
|
||||
})
|
||||
}).catch(() => {
|
||||
console.log("Failed to request " + key)
|
||||
})
|
||||
}))
|
||||
oidcEnabled.value = providers.value.length > 0
|
||||
}
|
||||
})
|
||||
console.log(providers.value)
|
||||
const oidcUrl = (provider) => {
|
||||
const params = new URLSearchParams({
|
||||
client_id: provider.ProviderInfo.client_id,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname,
|
||||
response_type: 'code',
|
||||
state: provider.Provider,
|
||||
scope: 'openid email profile'
|
||||
})
|
||||
console.log(params.entries())
|
||||
const url = new URL(provider.ProviderInfo.openid_configuration.authorization_endpoint)
|
||||
url.search = params.toString()
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="oidcEnabled">
|
||||
<hr class="mb-4"/>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn bg-body border w-100 rounded-3"
|
||||
:href="oidcUrl(provider)"
|
||||
v-for="provider in providers" style="flex: 1 1 0;">
|
||||
<LocaleText :t="'Sign In With ' + provider.Provider"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
+57
-10
@@ -7,18 +7,65 @@ import '@vuepic/vue-datepicker/dist/main.css'
|
||||
import {createApp, markRaw} from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router/router.js'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
|
||||
const app = createApp(App)
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const state = params.get('state')
|
||||
const code = params.get('code')
|
||||
|
||||
app.use(router)
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
pinia.use(({ store }) => {
|
||||
store.$router = markRaw(router)
|
||||
})
|
||||
if (state && code) {
|
||||
window.history.replaceState({}, '', window.location.pathname);
|
||||
console.log('After replaceState:', window.location.href);
|
||||
}
|
||||
|
||||
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
const initApp = async () => {
|
||||
const { default: router } = await import('./router/router.js')
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
pinia.use(({ store }) => {
|
||||
store.$router = markRaw(router)
|
||||
})
|
||||
|
||||
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
||||
console.log('After router import:', window.location.href)
|
||||
}
|
||||
|
||||
export const getUrl = (url) => {
|
||||
if (import.meta.env.MODE === 'development') {
|
||||
return url;
|
||||
}
|
||||
return `./.${url}`;
|
||||
}
|
||||
|
||||
if (state && code){
|
||||
await fetch(getUrl('/api/oidc/authenticate'), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
provider: state,
|
||||
code: code,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname
|
||||
})
|
||||
}).then(res => res.json()).then( async (res) => {
|
||||
if (res.status){
|
||||
window.location.replace(window.location.protocol + '//' + window.location.host + window.location.pathname)
|
||||
}else{
|
||||
await initApp()
|
||||
const store = DashboardConfigurationStore()
|
||||
store.newMessage('Server OIDC', res.message, 'danger')
|
||||
}
|
||||
})
|
||||
}else{
|
||||
await initApp()
|
||||
}
|
||||
|
||||
@@ -4,17 +4,21 @@ const getHeaders = () => {
|
||||
let headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
const store = DashboardConfigurationStore();
|
||||
const crossServer = store.getActiveCrossServer();
|
||||
if (crossServer){
|
||||
headers['wg-dashboard-apikey'] = crossServer.apiKey
|
||||
if (crossServer.headers){
|
||||
for (let header of Object.values(crossServer.headers)){
|
||||
if (header.key && header.value && !Object.keys(headers).includes(header.key)){
|
||||
headers[header.key] = header.value
|
||||
}
|
||||
}
|
||||
}
|
||||
try{
|
||||
const store = DashboardConfigurationStore();
|
||||
const crossServer = store.getActiveCrossServer();
|
||||
if (crossServer){
|
||||
headers['wg-dashboard-apikey'] = crossServer.apiKey
|
||||
if (crossServer.headers){
|
||||
for (let header of Object.values(crossServer.headers)){
|
||||
if (header.key && header.value && !Object.keys(headers).includes(header.key)){
|
||||
headers[header.key] = header.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +26,13 @@ const getHeaders = () => {
|
||||
}
|
||||
|
||||
export const getUrl = (url) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
const apiKey = store.getActiveCrossServer();
|
||||
if (apiKey){
|
||||
return `${apiKey.host}${url}`
|
||||
}
|
||||
try{
|
||||
const store = DashboardConfigurationStore();
|
||||
const apiKey = store.getActiveCrossServer();
|
||||
if (apiKey){
|
||||
return `${apiKey.host}${url}`
|
||||
}
|
||||
}catch (e){}
|
||||
if (import.meta.env.MODE === 'development') {
|
||||
return url;
|
||||
}
|
||||
@@ -79,4 +85,50 @@ export const fetchPost = async (url, body, callback) => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchPut = async (url, body, callback) => {
|
||||
await fetch(`${getUrl(url)}`, {
|
||||
headers: getHeaders(),
|
||||
method: "PUT",
|
||||
body: JSON.stringify(body)
|
||||
}).then((x) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
if (!x.ok){
|
||||
if (x.status !== 200){
|
||||
if (x.status === 401){
|
||||
store.newMessage("WGDashboard", "Sign in session ended, please sign in again", "warning")
|
||||
}
|
||||
throw new Error(x.statusText)
|
||||
}
|
||||
}else{
|
||||
return x.json()
|
||||
}
|
||||
}).then(x => callback ? callback(x) : undefined).catch(x => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchDelete = async (url, body, callback) => {
|
||||
await fetch(`${getUrl(url)}`, {
|
||||
headers: getHeaders(),
|
||||
method: "DELETE",
|
||||
body: JSON.stringify(body)
|
||||
}).then((x) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
if (!x.ok){
|
||||
if (x.status !== 200){
|
||||
if (x.status === 401){
|
||||
store.newMessage("WGDashboard", "Sign in session ended, please sign in again", "warning")
|
||||
}
|
||||
throw new Error(x.statusText)
|
||||
}
|
||||
}else{
|
||||
return x.json()
|
||||
}
|
||||
}).then(x => callback ? callback(x) : undefined).catch(x => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
@@ -7,10 +7,11 @@ import {GetLocale} from "@/utilities/locale.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import SignInInput from "@/components/signIn/signInInput.vue";
|
||||
import SignInTOTP from "@/components/signIn/signInTOTP.vue";
|
||||
import SignInOIDC from "@/components/signIn/signInOIDC.vue";
|
||||
|
||||
export default {
|
||||
name: "signin",
|
||||
components: {SignInTOTP, SignInInput, LocaleText, RemoteServerList, Message},
|
||||
components: {SignInOIDC, SignInTOTP, SignInInput, LocaleText, RemoteServerList, Message},
|
||||
async setup(){
|
||||
const store = DashboardConfigurationStore()
|
||||
let theme = "dark"
|
||||
@@ -171,7 +172,7 @@ export default {
|
||||
</form>
|
||||
<RemoteServerList v-else></RemoteServerList>
|
||||
|
||||
<div class="d-flex mt-3" v-if="!this.store.IsElectronApp">
|
||||
<div class="d-flex mt-3 flex-column" v-if="!this.store.IsElectronApp">
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<input
|
||||
v-model="this.store.CrossServerConfiguration.Enable"
|
||||
@@ -184,6 +185,8 @@ export default {
|
||||
<LocaleText t="Access Remote Server"></LocaleText>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<SignInOIDC />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Generated
+1542
-1711
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "client",
|
||||
"version": "v1.0",
|
||||
"version": "v1.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -9,20 +9,20 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.9.0",
|
||||
"bootstrap": "^5.3.6",
|
||||
"axios": "^1.18.0",
|
||||
"bootstrap": "^5.3.8",
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"oidc-client-ts": "^3.2.1",
|
||||
"pinia": "^3.0.2",
|
||||
"dayjs": "^1.11.21",
|
||||
"oidc-client-ts": "^3.5.0",
|
||||
"pinia": "^3.0.4",
|
||||
"qrcode": "^1.5.4",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.1"
|
||||
"uuid": "^14.0.0",
|
||||
"vue": "^3.5.35",
|
||||
"vue-router": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"vite": "^6.2.4",
|
||||
"vite-plugin-vue-devtools": "^7.7.2"
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"vite": "^8.0.16",
|
||||
"vite-plugin-vue-devtools": "^8.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from "@/router/router.js";
|
||||
import {createPinia} from "pinia";
|
||||
|
||||
import 'bootstrap/dist/js/bootstrap.bundle.js'
|
||||
@@ -13,7 +12,13 @@ const params = new URLSearchParams(window.location.search)
|
||||
const state = params.get('state')
|
||||
const code = params.get('code')
|
||||
|
||||
if (state && code) {
|
||||
window.history.replaceState({}, '', window.location.pathname);
|
||||
}
|
||||
|
||||
const initApp = async () => {
|
||||
debugger
|
||||
const { default: router } = await import('./router/router.js')
|
||||
const app = createApp(App)
|
||||
const serverInformation = await axiosGet("/api/serverInformation", {})
|
||||
app.use(createPinia())
|
||||
@@ -31,12 +36,10 @@ if (state && code){
|
||||
code: code,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname
|
||||
}).then(async (data) => {
|
||||
let url = new URL(window.location.href);
|
||||
url.search = '';
|
||||
history.replaceState({}, document.title, url.toString());
|
||||
|
||||
await initApp()
|
||||
if (!data.status){
|
||||
if (data.status){
|
||||
window.location.replace(window.location.protocol + '//' + window.location.host + window.location.pathname)
|
||||
}else {
|
||||
await initApp()
|
||||
const store = clientStore()
|
||||
store.newNotification(data.message, 'danger')
|
||||
}
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
import{a5 as A,r as n,D as S,g as l,z as v}from"./index-DXzxfcZW.js";const b=A("DashboardClientAssignmentStore",()=>{const f=n({}),d=n([]),o=n({}),c=n([]),g=n(!1),r=n(""),i=S(),w=async()=>{await l("/api/clients/allClients",{},s=>{o.value=s.data})},y=async()=>{await l("/api/clients/allClientsRaw",{},s=>{c.value=s.data,console.log(c.value)})},m=s=>Object.values(o.value).flat().find(e=>e.ClientID===s),u=async(s,e)=>{await l("/api/clients/assignedClients",{ConfigurationName:s,Peer:e},a=>{d.value=a.data})};return{assignments:d,getAssignedClients:u,getClients:w,getClientsRaw:y,clients:o,unassignClient:async(s,e,a)=>{g.value=!0,await v("/api/clients/unassignClient",{AssignmentID:a},async t=>{t.status?(i.newMessage("Server","Unassign successfully!","success"),s&&e&&await u(s,e)):(i.newMessage("Server","Unassign Failed. Reason: "+t.message,"success"),console.error("Unassign Failed. Reason: "+t.message)),g.value=!1})},assignClient:async(s,e,a,t=!0)=>{r.value=a,await v("/api/clients/assignClient",{ConfigurationName:s,Peer:e,ClientID:a},async C=>{C.status?(i.newMessage("Server","Assign successfully!","success"),t&&await u(s,e)):(i.newMessage("Server","Assign Failed. Reason: "+C.message,"success"),console.error("Assign Failed. Reason: "+C.message)),r.value=""})},getClientById:m,unassigning:g,assigning:r,clientsRaw:c,allConfigurationsPeers:f,getAllConfigurationsPeers:async()=>{await l("/api/clients/allConfigurationsPeers",{},s=>{f.value=s.data})}}});export{b as D};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
@media screen and (min-width: 576px){.backLink[data-v-f874264d]{display:none}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
@media screen and (max-width: 576px){.clientListContainer.hide[data-v-a8650ee3],.clientViewerContainer.hide[data-v-a8650ee3]{display:none!important}.clientListContainer[data-v-a8650ee3]{border-right:none!important;animation:blurIn-a8650ee3 .2s ease-in-out forwards}.clientViewerContainer[data-v-a8650ee3]{animation:blurIn-a8650ee3 .2s ease-in-out forwards}}@keyframes blurIn-a8650ee3{0%{filter:blur(8px)}to{filter:blur(0px)}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{_ as r,c as i,b as o,w as e,k as l,j as a,l as _,S as u,h as d,f as t}from"./index-DXzxfcZW.js";const m={name:"configuration"},f={class:"mt-md-5 mt-3 text-body"};function p(h,k,x,w,$,v){const n=d("RouterView");return t(),i("div",f,[o(n,null,{default:e(({Component:s,route:c})=>[o(l,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(_(s),{key:c.path,class:"z-1"}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",p]]);export{B as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.fade-enter-active[data-v-9f596f5e]{transition-delay:var(--v0d365bfc)!important}.progress-bar[data-v-01ef60a9]{width:0;transition:all 1s cubic-bezier(.42,0,.22,1)}.filter a[data-v-7ed053f0]{text-decoration:none}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
@media screen and (max-width: 992px){.apiKey-card-body{&[data-v-a76253c8]{flex-direction:column!important;align-items:start!important}div.ms-auto[data-v-a76253c8]{margin-left:0!important}div[data-v-a76253c8]{width:100%;align-items:start!important}small[data-v-a76253c8]{margin-right:auto}}}.apiKey-move[data-v-f7e62927],.apiKey-enter-active[data-v-f7e62927],.apiKey-leave-active[data-v-f7e62927]{transition:all .5s ease}.apiKey-enter-from[data-v-f7e62927],.apiKey-leave-to[data-v-f7e62927]{opacity:0;transform:translateY(30px) scale(.9)}.apiKey-leave-active[data-v-f7e62927]{position:absolute;width:100%}.dropdown-menu[data-v-4e34593e]{width:100%}
|
||||
-1
@@ -1 +0,0 @@
|
||||
.list-group{&[data-v-4aa2aed9]:first-child{border-top-left-radius:var(--bs-border-radius-lg);border-top-right-radius:var(--bs-border-radius-lg)}&[data-v-4aa2aed9]:last-child{border-bottom-left-radius:var(--bs-border-radius-lg);border-bottom-right-radius:var(--bs-border-radius-lg)}}
|
||||
src/static/dist/WGDashboardAdmin/assets/dashboardSettingsWireguardConfigurationAutostart-DWZoKQw6.js
Vendored
-1
@@ -1 +0,0 @@
|
||||
import{_ as f,c as i,a as t,b as u,h as w,d as k,m as x,y,n as p,t as v,z as _,D as m,W as b,A as S,f as n,r as D,q as $,F as W,i as V}from"./index-DXzxfcZW.js";import{L as C}from"./localeText-Dmcj5qqx.js";const F={name:"dashboardSettingsInputWireguardConfigurationPath",components:{LocaleText:C},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const o=m(),s=b(),r=`input_${S()}`;return{store:o,uuid:r,WireguardConfigurationStore:s}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Server[this.targetData]},methods:{async useValidation(){this.changed&&(this.updating=!0,await _("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},o=>{o.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3),this.WireguardConfigurationStore.getConfigurations(),this.store.newMessage("Server","WireGuard configuration path saved","success")):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=o.message),this.changed=!1,this.updating=!1}))}}},I={class:"card"},T={class:"card-header"},A={class:"my-2"},L={class:"card-body"},M={class:"form-group"},N=["for"],P={class:"d-flex gap-2 align-items-start"},B={class:"flex-grow-1"},G=["id","disabled"],z={class:"invalid-feedback fw-bold"},U=["disabled"],q={key:0,class:"bi bi-save2-fill"},E={key:1,class:"spinner-border spinner-border-sm"},K={key:0,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1 mb-2"};function j(o,s,r,a,c,g){const d=w("LocaleText");return n(),i("div",I,[t("div",T,[t("h6",A,[u(d,{t:"Path"})])]),t("div",L,[t("div",M,[t("label",{for:this.uuid,class:"text-muted mb-1"},[t("strong",null,[t("small",null,[u(d,{t:this.title},null,8,["t"])])])],8,N),t("div",P,[t("div",B,[x(t("input",{type:"text",class:p(["form-control rounded-3",{"is-invalid":this.showInvalidFeedback,"is-valid":this.isValid}]),id:this.uuid,"onUpdate:modelValue":s[0]||(s[0]=e=>this.value=e),onKeydown:s[1]||(s[1]=e=>this.changed=!0),disabled:this.updating},null,42,G),[[y,this.value]]),t("div",z,v(this.invalidFeedback),1)]),t("button",{onClick:s[2]||(s[2]=e=>this.useValidation()),disabled:!this.changed,class:"ms-auto btn rounded-3 border-success-subtle bg-success-subtle text-success-emphasis"},[this.updating?(n(),i("span",E)):(n(),i("i",q))],8,U)]),r.warning?(n(),i("div",K,[t("small",null,[s[3]||(s[3]=t("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),u(d,{t:r.warningText},null,8,["t"])])])):k("",!0)])])])}const et=f(F,[["render",j]]),H={class:"card rounded-3"},J={class:"card-header"},O={class:"my-2"},Q={class:"card-body d-flex gap-2"},R={class:"list-group w-100"},X=["onClick"],Y={__name:"dashboardSettingsWireguardConfigurationAutostart",setup(o){const s=m(),r=b(),a=D(s.Configuration.WireGuardConfiguration.autostart),c=$(()=>r.Configurations.map(e=>e.Name)),g=async()=>{await _("/api/updateDashboardConfigurationItem",{section:"WireGuardConfiguration",key:"autostart",value:a.value},async e=>{e.status?(s.newMessage("Server","Start up configurations saved","success"),a.value=e.data):s.newMessage("Server","Start up configurations failed to save","danger")})},d=e=>{a.value.includes(e)?a.value=a.value.filter(h=>h!==e):a.value.push(e),g()};return(e,h)=>(n(),i("div",H,[t("div",J,[t("h6",O,[u(C,{t:"Toggle When Start Up"})])]),t("div",Q,[t("div",R,[(n(!0),i(W,null,V(c.value,l=>(n(),i("button",{type:"button",key:l,onClick:Z=>d(l),class:"list-group-item list-group-item-action py-2 w-100 d-flex align-items-center"},[t("samp",null,v(l),1),t("i",{class:p(["ms-auto",[a.value.includes(l)?"bi-check-circle-fill":"bi-circle"]])},null,2)],8,X))),128))])])]))}},at=f(Y,[["__scopeId","data-v-4aa2aed9"]]);export{et as D,at as a};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.table[data-v-7b6e949e]>:not(caption)>*>*{padding-left:0!important;padding-right:1rem!important}.list-group-item[data-v-e0f0e683]{border-radius:0!important;border-left:0!important;border-right:0!important}.list-group-item[data-v-e0f0e683]:first-child{border-top:0!important}.url[data-v-e0f0e683]{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;font-size:.9rem}
|
||||
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 +0,0 @@
|
||||
var n={},l;function u(){if(l)return n;l=1;const i=new Uint8Array(512),t=new Uint8Array(256);return(function(){let r=1;for(let e=0;e<255;e++)i[e]=r,t[r]=e,r<<=1,r&256&&(r^=285);for(let e=255;e<512;e++)i[e]=i[e-255]})(),n.log=function(r){if(r<1)throw new Error("log("+r+")");return t[r]},n.exp=function(r){return i[r]},n.mul=function(r,e){return r===0||e===0?0:i[t[r]+t[e]]},n}export{u as r};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
function x(n){return n.includes(":")?6:n.includes(".")?4:0}function p(n){const t=x(n);if(!t)throw new Error(`Invalid IP address: ${n}`);let e=0n,r=0n;const s=Object.create(null);if(t===4)for(const i of n.split(".").map(BigInt).reverse())e+=i*2n**r,r+=8n;else{if(n.includes(".")&&(s.ipv4mapped=!0,n=n.split(":").map(o=>{if(o.includes(".")){const[u,l,f,a]=o.split(".").map(d=>Number(d).toString(16).padStart(2,"0"));return`${u}${l}:${f}${a}`}else return o}).join(":")),n.includes("%")){let o;[,n,o]=/(.+)%(.+)/.exec(n)||[],s.scopeid=o}const i=n.split(":"),c=i.indexOf("");if(c!==-1)for(;i.length<8;)i.splice(c,0,"");for(const o of i.map(u=>BigInt(parseInt(u||"0",16))).reverse())e+=o*2n**r,r+=16n}return s.number=e,s.version=t,s}function m({number:n,version:t,ipv4mapped:e,scopeid:r},{compress:s=!0,hexify:i=!1}={}){let c=t===4?24n:112n;const o=t===4?8n:16n;let u=n;const l=[];for(;c>0n;){const f=2n**c;l.push(u/f),u=n%f,c-=o}if(l.push(u),t===4)return l.join(".");{let f="";if(e&&!i){for(const[a,d]of l.entries())a<6?f+=`${d.toString(16)}:`:f+=`${String(d>>8n)}.${String(d&255n)}${a===6?".":""}`;s&&(f=y(f.split(":")))}else s?f=y(l.map(a=>a.toString(16))):f=l.map(a=>a.toString(16)).join(":");return r?`${f}%${r}`:f}}function B(n,{compress:t=!0,hexify:e=!1}={}){return m(p(n),{compress:t,hexify:e})}function y(n){let t=null,e=null;for(const[r,s]of n.entries())s==="0"?e?e.add(r):e=new Set([r]):e&&((!t||e.size>t.size)&&(t=e),e=null);(!t&&e||e&&t&&e.size>t.size)&&(t=e);for(const r of t||[])n[r]=":";return n.filter(Boolean).join(":").replace(/:{2,}/,"::")}const v={4:32,6:128};function b(n){return Array.from(new Set(n))}function N(n){return n.includes("/")?x(n):0}function I(n,t){const{number:e,version:r}=p(n.replace(/\/.+/,"")),{number:s,version:i}=p(t.replace(/\/.+/,""));return r===i?e-s>0n?1:e-s<0n?-1:0:r>i?1:0}function P(n,{compress:t=!0,hexify:e=!1}={}){const{start:r,end:s,prefix:i,version:c,prefixPresent:o}=g(n);return r!==s||o?`${B(m({number:r,version:c}),{compress:t,hexify:e})}/${i}`:B(n,{compress:t,hexify:e})}function h(n,t){return Array.isArray(n)?n.map(e=>h(e,t)):P(n,t)}function g(n){const t=N(n),e=Object.create(null);let r;if(t)r=n,e.version=t;else{const S=x(n);if(S)r=`${n}/${v[S]}`,e.version=S;else throw new Error(`Network is not a CIDR or IP: ${n}`)}const[s,i]=r.split("/");if(!/^[0-9]+$/.test(i))throw new Error(`Network is not a CIDR or IP: ${n}`);const{number:c,version:o,ipv4mapped:u,scopeid:l}=p(s);e.ip=m({number:c,version:o,ipv4mapped:u,scopeid:l}),e.cidr=`${e.ip}/${i}`,e.prefix=i,e.prefixPresent=!!t;const f=v[o],a=c.toString(2).padStart(f,"0"),d=Number(f-Number(i)),w=a.substring(0,f-d);return e.start=BigInt(`0b${w}${"0".repeat(d)}`),e.end=BigInt(`0b${w}${"1".repeat(d)}`),e}function z(n,t){return!(t.start<n.start||t.end>n.end)}function C(n){return n===0n?0n:2n**BigInt(String(n.toString(2).length-1))}function $(n){if(n.end-n.start===1n)return n.end%2n===0n?[{start:n.start,end:n.start},{start:n.end,end:n.end}]:[{start:n.start,end:n.end}];const t=A(n.end,n.start);let e=C(t),r,s;if(t===e&&n.start+t===n.end)return[n];if(n.start%e===0n)r=n.start,s=r+e-1n;else if(r=n.end/e*e,r+e-1n>n.end){for(r=(n.end/e-1n)*e;r<n.start;)e/=2n,r=(n.end/e-1n)*e;s=r+e-1n}else r=n.end/e*e,s=r+e-1n;let i=[{start:r,end:s}];return r!==n.start&&(i=i.concat($({start:n.start,end:r-1n}))),s!==n.end&&(i=i.concat($({start:s+1n,end:n.end}))),i}function A(n,t){return n+1n-t}function j(n,t){const e=h(m({number:BigInt(n.start.toString()),version:t})),r=A(n.end,n.start).toString(2),s=v[t]-(r.match(/0/g)||[]).length;return`${e}/${s}`}function O(n){const t={4:{},6:{}};for(const{start:e,end:r,version:s}of n)t[s][String(e)]||(t[s][String(e)]={start:0,end:0}),t[s][String(r)]||(t[s][String(r)]={start:0,end:0}),t[s][String(e)].start+=1,t[s][String(r)].end+=1;return t}function V(n){let t=null,e=null;const r=Object.keys(n);let s=0;const i=[];for(const[c,o]of r.entries()){const u=n[String(o)];if(t===null&&u.start&&(t=BigInt(o)),u.end&&(e=BigInt(o)),t===null)continue;u.start&&(s+=u.start),u.end&&(s-=u.end);const l=r[c+1];if(u.end&&s===0&&l&&BigInt(l)-BigInt(o)>1){for(const f of $({start:t,end:e}))i.push(f);t=null,e=null}else if(c===r.length-1)for(const f of $({start:t,end:e}))i.push(f)}return i}function k(n){const t=b((Array.isArray(n)?n:[n]).sort(I).map(g)),e=O(t),r={4:[],6:[]};for(const s of[4,6])r[s]=V(e[s]).map(i=>j(i,s));return[...r[4].sort(I),...r[6].sort(I)]}function*E(n){const t=b(Array.isArray(n)?n:[n]);for(const e of k(t)){const{start:r,end:s,version:i}=g(e);for(let c=r;c<=s;c++)yield h(m({number:c,version:i}))}}function R(n,t){const e=b(Array.isArray(n)?n:[n]),r=b(Array.isArray(t)?t:[t]),s=r.length;let i=0;for(const c of e){const o=g(c);for(const u of r){const l=g(u);if(o.version===l.version&&z(o,l)){i++;continue}}}return i===s}export{R as c,E as e,k as m,g as p};
|
||||
@@ -1 +0,0 @@
|
||||
import{H as I,q as w,P as S,J as k,Q as L,u as R}from"./index-DXzxfcZW.js";const W=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const X=Object.prototype.toString,Y=t=>X.call(t)==="[object Object]",$=()=>{};function C(t){return Array.isArray(t)?t:[t]}function q(t,a,r){return I(t,a,{...r,immediate:!0})}const O=W?window:void 0;function P(t){var a;const r=S(t);return(a=r?.$el)!==null&&a!==void 0?a:r}function T(...t){const a=(o,u,s,d)=>(o.addEventListener(u,s,d),()=>o.removeEventListener(u,s,d)),r=w(()=>{const o=C(S(t[0])).filter(u=>u!=null);return o.every(u=>typeof u!="string")?o:void 0});return q(()=>{var o,u;return[(o=(u=r.value)===null||u===void 0?void 0:u.map(s=>P(s)))!==null&&o!==void 0?o:[O].filter(s=>s!=null),C(S(r.value?t[1]:t[0])),C(R(r.value?t[2]:t[1])),S(r.value?t[3]:t[2])]},([o,u,s,d],p,c)=>{if(!o?.length||!u?.length||!s?.length)return;const f=Y(d)?{...d}:d,v=o.flatMap(b=>u.flatMap(h=>s.map(y=>a(b,h,y,f))));c(()=>{v.forEach(b=>b())})},{flush:"post"})}function B(t,a,r={}){const{window:o=O,ignore:u=[],capture:s=!0,detectIframe:d=!1,controls:p=!1}=r;if(!o)return p?{stop:$,cancel:$,trigger:$}:$;let c=!0;const f=e=>S(u).some(n=>{if(typeof n=="string")return Array.from(o.document.querySelectorAll(n)).some(i=>i===e.target||e.composedPath().includes(i));{const i=P(n);return i&&(e.target===i||e.composedPath().includes(i))}});function v(e){const n=S(e);return n&&n.$.subTree.shapeFlag===16}function b(e,n){const i=S(e),m=i.$.subTree&&i.$.subTree.children;return m==null||!Array.isArray(m)?!1:m.some(A=>A.el===n.target||n.composedPath().includes(A.el))}const h=e=>{const n=P(t);if(e.target!=null&&!(!(n instanceof Element)&&v(t)&&b(t,e))&&!(!n||n===e.target||e.composedPath().includes(n))){if("detail"in e&&e.detail===0&&(c=!f(e)),!c){c=!0;return}a(e)}};let y=!1;const E=[T(o,"click",e=>{y||(y=!0,setTimeout(()=>{y=!1},0),h(e))},{passive:!0,capture:s}),T(o,"pointerdown",e=>{const n=P(t);c=!f(e)&&!!(n&&!e.composedPath().includes(n))},{passive:!0}),d&&T(o,"blur",e=>{setTimeout(()=>{var n;const i=P(t);((n=o.document.activeElement)===null||n===void 0?void 0:n.tagName)==="IFRAME"&&!i?.contains(o.document.activeElement)&&a(e)},0)},{passive:!0})].filter(Boolean),x=()=>E.forEach(e=>e());return p?{stop:x,cancel:()=>{c=!1},trigger:e=>{c=!0,h(e),c=!1}}:x}function D(t,a={}){const{threshold:r=50,onSwipe:o,onSwipeEnd:u,onSwipeStart:s,passive:d=!0}=a,p=k({x:0,y:0}),c=k({x:0,y:0}),f=w(()=>p.x-c.x),v=w(()=>p.y-c.y),{max:b,abs:h}=Math,y=w(()=>b(h(f.value),h(v.value))>=r),E=L(!1),x=w(()=>y.value?h(f.value)>h(v.value)?f.value>0?"left":"right":v.value>0?"up":"down":"none"),e=l=>[l.touches[0].clientX,l.touches[0].clientY],n=(l,g)=>{p.x=l,p.y=g},i=(l,g)=>{c.x=l,c.y=g},m={passive:d,capture:!d},A=l=>{E.value&&u?.(l,x.value),E.value=!1},j=[T(t,"touchstart",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);n(g,M),i(g,M),s?.(l)},m),T(t,"touchmove",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);i(g,M),m.capture&&!m.passive&&Math.abs(f.value)>Math.abs(v.value)&&l.preventDefault(),!E.value&&y.value&&(E.value=!0),E.value&&o?.(l)},m),T(t,["touchend","touchcancel"],A,m)];return{isSwiping:E,direction:x,coordsStart:p,coordsEnd:c,lengthX:f,lengthY:v,stop:()=>j.forEach(l=>l())}}export{D as a,B as o,P as u};
|
||||
@@ -1 +0,0 @@
|
||||
.agentContainer[data-v-f37f608d]{--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-f37f608d]{height:calc(var(--agentHeight) - 1rem)}@media screen and (max-width: 768px){.agentContainer[data-v-f37f608d]{--agentHeight: 100vh !important;top:0;left:0;max-height:calc(var(--agentHeight) - 58px - 1rem);width:calc(100% - 1rem)}}.agentChatroomBody[data-v-f37f608d]{flex:1 1 auto;overflow-y:auto;max-height:calc(var(--agentHeight) - 70px - 244px)}@media screen and (max-width: 768px){.navbar-container[data-v-982f1a52]{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-982f1a52]{animation-direction:normal;display:block!important;animation-name:zoomInFade-982f1a52}}.navbar-container[data-v-982f1a52]{height:100vh;position:relative}@supports (height: 100dvh){@media screen and (max-width: 768px){.navbar-container[data-v-982f1a52]{height:calc(100dvh - 58px)}}}@keyframes zoomInFade-982f1a52{0%{opacity:0;transform:translateY(60px);filter:blur(3px)}to{opacity:1;transform:translateY(0);filter:blur(0px)}}.slideIn-enter-active[data-v-982f1a52],.slideIn-leave-active[data-v-982f1a52]{transition:all .3s cubic-bezier(.82,.58,.17,1)}.slideIn-enter-from[data-v-982f1a52],.slideIn-leave-to[data-v-982f1a52]{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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{_ as e,G as t,c as o,t as a,f as c}from"./index-DXzxfcZW.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return c(),o("span",null,a(this.getLocaleText),1)}const m=e(s,[["render",n]]);export{m as L};
|
||||
@@ -1 +0,0 @@
|
||||
.message[data-v-94c76b54]{width:100%}@media screen and (min-width: 576px){.message[data-v-94c76b54]{width:400px}}
|
||||
@@ -1 +0,0 @@
|
||||
import{L as l}from"./localeText-Dmcj5qqx.js";import{d as c}from"./dayjs.min-C-brjxlJ.js";import{_ as h,c as o,a as e,b as a,w as u,e as p,h as g,t as i,k as f,n as _,f as n}from"./index-DXzxfcZW.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(C,s,L,j,t,m){const d=g("LocaleText");return n(),o("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:_([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[a(f,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(n(),o("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)),a(d,{t:"Dismiss"})])])):(n(),o("div",b,[e("small",w,[a(d,{t:"FROM "}),p(" "+i(this.message.from),1)]),e("small",y,i(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,i(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
@@ -1 +0,0 @@
|
||||
.protocolBtnGroup a[data-v-14fcf0ee]{transition:all .2s ease-in-out}
|
||||
@@ -1 +0,0 @@
|
||||
.ol-layer canvas{border-radius:var(--bs-border-radius-lg)!important}#map{height:300px}
|
||||
@@ -1 +0,0 @@
|
||||
import{S as C,e as y,c as w,m as _,a as L,f as S,l as v,i as M,b as k,d as x,g as A,h as F,j as R,M as D,V as P,T as b,k as l,O as E,n as O,F as h,P as f,o as T,p as c,C as V,q as u,r as X}from"./Vector-CuSZivra.js";import{_ as Y,D as G,c as $,d as j,f as q}from"./index-DXzxfcZW.js";class r extends C{constructor(t,e){super(),this.flatMidpoint_=null,this.flatMidpointRevision_=-1,this.maxDelta_=-1,this.maxDeltaRevision_=-1,e!==void 0&&!Array.isArray(t[0])?this.setFlatCoordinates(e,t):this.setCoordinates(t,e)}appendCoordinate(t){y(this.flatCoordinates,t),this.changed()}clone(){const t=new r(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t}closestPointXY(t,e,o,n){return n<w(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(_(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),L(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,this.maxDelta_,!1,t,e,o,n))}forEachSegment(t){return S(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)}getCoordinateAtM(t,e){return this.layout!="XYM"&&this.layout!="XYZM"?null:(e=e!==void 0?e:!1,v(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e))}getCoordinates(){return M(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getCoordinateAt(t,e){return k(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,this.stride)}getLength(){return x(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getFlatMidpoint(){return this.flatMidpointRevision_!=this.getRevision()&&(this.flatMidpoint_=this.getCoordinateAt(.5,this.flatMidpoint_??void 0),this.flatMidpointRevision_=this.getRevision()),this.flatMidpoint_}getSimplifiedGeometryInternal(t){const e=[];return e.length=A(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,0),new r(e,"XY")}getType(){return"LineString"}intersectsExtent(t){return F(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,this.getExtent())}setCoordinates(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=R(this.flatCoordinates,0,t,this.stride),this.changed()}}const B={name:"osmap",props:{type:"",d:Object||Array},data(){return{osmAvailable:!0}},setup(){return{store:G()}},methods:{getLastLonLat(){if(this.type==="traceroute"){const i=this.d.findLast(t=>t.geo&&t.geo.lat&&t.geo.lon);return i?[i.geo.lon,i.geo.lat]:[0,0]}return[this.d.geo.lon,this.d.geo.lat]}},async mounted(){await fetch("https://tile.openstreetmap.org/",{signal:AbortSignal.timeout(1500)}).then(i=>{const t=new D({target:"map",layers:[new b({source:new E})],view:new P({center:l(this.getLastLonLat()),zoom:this.type==="traceroute"?3:10})}),e=[],o=new O;if(this.type==="traceroute")this.d.forEach(s=>{if(s.geo&&s.geo.lat&&s.geo.lon){const a=l([s.geo.lon,s.geo.lat]);e.push(a);const g=this.getLastLonLat(),m=new h({geometry:new f(a),last:s.geo.lon===g[0]&&s.geo.lat===g[1]});o.addFeature(m)}});else{const s=l([this.d.geo.lon,this.d.geo.lat]);e.push(s);const a=new h({geometry:new f(s)});o.addFeature(a)}const n=new r(e),d=new h({geometry:n});o.addFeature(d);const p=new T({source:o,style:function(s){if(s.getGeometry().getType()==="Point")return new c({image:new V({radius:10,fill:new X({color:s.get("last")?"#dc3545":"#0d6efd"}),stroke:new u({color:"white",width:5})})});if(s.getGeometry().getType()==="LineString")return new c({stroke:new u({color:"#0d6efd",width:2})})}});t.addLayer(p)}).catch(i=>{this.osmAvailable=!1})}},z={key:0,id:"map",class:"w-100 rounded-3"};function I(i,t,e,o,n,d){return this.osmAvailable?(q(),$("div",z)):j("",!0)}const H=Y(B,[["render",I]]);export{H as O};
|
||||
@@ -1 +0,0 @@
|
||||
.list-move[data-v-ed72944d],.list-enter-active[data-v-ed72944d],.list-leave-active[data-v-ed72944d]{transition:all .3s ease}.list-enter-from[data-v-ed72944d],.list-leave-to[data-v-ed72944d]{opacity:0;transform:translateY(10px)}.list-leave-active[data-v-ed72944d]{position:absolute}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.list-move[data-v-99c0844e],.list-enter-active[data-v-99c0844e],.list-leave-active[data-v-99c0844e]{transition:all .5s ease}.list-enter-from[data-v-99c0844e],.list-leave-to[data-v-99c0844e]{opacity:0;transform:scale(.9)}.list-leave-active[data-v-99c0844e]{position:absolute;width:100%}.assignment[data-v-99c0844e]:last-child{margin-bottom:0!important}[data-v-b52659b4]:focus{outline:none}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{_ as v,D as g,r as o,o as h,L as x,g as y,c as i,f as n,a as s,b as c,d as w,n as C,w as k,k as F}from"./index-DXzxfcZW.js";import{L as T}from"./localeText-Dmcj5qqx.js";import"./browser-DFwZaPoQ.js";import"./galois-field-I2lBzzs-.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"},L={class:"card rounded-3 shadow w-100"},P={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"},N={style:{height:"300px"},class:"d-flex"},V=["value"],j={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)=>(n(),i("div",M,[s("div",S,[s("div",D,[s("div",L,[s("div",P,[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",N,[s("textarea",{style:{height:"300px"},class:C(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,V),a.value?(n(),i("div",j,[...e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)])])):w("",!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?(n(),i("span",q,[...e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)])])):(n(),i("span",$,[...e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])]))]),_:1})],8,W)])])])])])]))}},H=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{H as default};
|
||||
@@ -1 +0,0 @@
|
||||
.slide-up-enter-active[data-v-b0ea2d46],.slide-up-leave-active[data-v-b0ea2d46]{transition:all .2s cubic-bezier(.42,0,.22,1)}.slide-up-enter-from[data-v-b0ea2d46],.slide-up-leave-to[data-v-b0ea2d46]{opacity:0;transform:scale(.9)}@keyframes spin-b0ea2d46{0%{transform:rotate(0)}to{transform:rotate(360deg)}}#check[data-v-b0ea2d46]{animation:cubic-bezier(.42,0,.22,1.3) .7s spin-b0ea2d46}
|
||||
@@ -1 +0,0 @@
|
||||
import{L as o}from"./localeText-Dmcj5qqx.js";import{P as t}from"./peersDefaultSettingsInput-KXSGcg6g.js";import{B as s,c as l,a,b as e,f as n}from"./index-DXzxfcZW.js";const r={class:"d-flex gap-3 flex-column"},i={class:"card rounded-3"},d={class:"card-header"},c={class:"my-2"},_={class:"card-body"},D=s({__name:"peerDefaultSettings",setup(p){return(g,m)=>(n(),l("div",r,[a("div",i,[a("div",d,[a("h6",c,[e(o,{t:"Peer Default Settings"})])]),a("div",_,[a("div",null,[e(t,{targetData:"peer_global_dns",title:"DNS"}),e(t,{targetData:"peer_endpoint_allowed_ip",title:"Endpoint Allowed IPs"}),e(t,{targetData:"peer_mtu",title:"MTU"}),e(t,{targetData:"peer_keep_alive",title:"Persistent Keepalive"}),e(t,{targetData:"remote_endpoint",title:"Peer Remote Endpoint",warning:!0,warningText:"This will be changed globally, and will be apply to all peer's QR code and configuration file."})])])])]))}});export{D as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{a as p,S as b}from"./schedulePeerJob-DOBEE-kC.js";import{_ as h,h as i,c as a,f as s,a as e,b as r,w as u,d as m,F as _,i as f,j as v,T as J,A as x,W as g}from"./index-DXzxfcZW.js";import{L as w}from"./localeText-Dmcj5qqx.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";import"./dayjs.min-C-brjxlJ.js";const P={name:"peerJobs",setup(){return{store:g()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:b,ScheduleDropdown:p},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:x().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},j={class:"mb-0 fw-normal"},k={class:"card-body px-4 pb-4 pt-2 position-relative"},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 s(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",j,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=o=>this.$emit("close"))})]),e("div",k,[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]=o=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(J,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:u(()=>[(s(!0),a(_,null,f(this.selectedPeer.jobs,(o,E)=>(s(),v(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(o),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:o.JobID,pjob:o},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(s(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):m("",!0)]),_:1})])])])])])}const H=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{H as default};
|
||||
@@ -1 +0,0 @@
|
||||
.schedulePeerJobTransition-move[data-v-5bbdd42b],.schedulePeerJobTransition-enter-active[data-v-5bbdd42b],.schedulePeerJobTransition-leave-active[data-v-5bbdd42b]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.schedulePeerJobTransition-enter-from[data-v-5bbdd42b],.schedulePeerJobTransition-leave-to[data-v-5bbdd42b]{opacity:0;transform:scale(.9)}.schedulePeerJobTransition-leave-active[data-v-5bbdd42b]{position:absolute;width:100%}
|
||||
@@ -1 +0,0 @@
|
||||
import{S as _}from"./schedulePeerJob-DOBEE-kC.js";import{_ as g,h as c,c as r,f as t,a as e,b as l,F as p,i as b,d as f,t as m,j as v,W as y}from"./index-DXzxfcZW.js";import{L as x}from"./localeText-Dmcj5qqx.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";import"./dayjs.min-C-brjxlJ.js";const J={name:"peerJobsAllModal",setup(){return{store:y()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},w={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},$={class:"container d-flex h-100 w-100"},k={class:"m-auto modal-dialog-centered dashboardModal"},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"},j={class:"card-body px-4 pb-4 pt-2"},C={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},P={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",w,[e("div",$,[e("div",k,[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",j,[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",C,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",P,[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(),v(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 X=g(J,[["render",W]]);export{X as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.icon[data-v-3c48f50e]{flex:1;min-width:30px;max-width:30px;width:30px;aspect-ratio:1 / 1}.icon[data-v-accdf15e]{flex:1;aspect-ratio:1 / 1}#peerTag[data-v-ab3e5c4e]{width:300px;position:absolute;right:0;z-index:9999;margin-top:2px}.animation__fadeInDropdown[data-v-71502547]{animation-name:fadeInDropdown-71502547;animation-duration:.2s;animation-timing-function:cubic-bezier(.82,.58,.17,.9)}@keyframes fadeInDropdown-71502547{0%{opacity:0;filter:blur(3px);transform:translateY(-60px)}to{opacity:1;filter:blur(0px);transform:translateY(-40px)}}.displayModal .dashboardModal[data-v-71502547]{width:400px!important}@media screen and (max-width: 992px){.peerSearchContainer[data-v-71502547]{flex-direction:column}.peerSettingContainer .dashboardModal[data-v-71502547]{width:100%!important}}.peerSearchContainer>button[data-v-71502547],.peerSearchContainer .dropdown>button[data-v-71502547]{text-align:left;display:flex;align-items:center}span[data-v-d4e41a56]{top:-34px;left:0}.dropdown-menu[data-v-18549c26]{right:0;min-width:200px}.dropdown-menu.dropup[data-v-18549c26]{bottom:100%}.dropdown-item.disabled[data-v-18549c26],.dropdown-item[data-v-18549c26]:disabled{opacity:.7}.confirmDelete[data-v-18549c26]{padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x)}.subMenuBtn.active[data-v-f38d3291]{background-color:#ffffff20}.peerCard[data-v-f38d3291]{transition:box-shadow .1s cubic-bezier(.82,.58,.17,.9)}.peerCard[data-v-f38d3291]:hover{box-shadow:var(--bs-box-shadow)!important}@media screen and (max-width: 992px){.calendar-day .session-badge-list[data-v-5178a57b],.sessions-label[data-v-5178a57b]{display:none}}.session-list[data-v-5178a57b]{aspect-ratio:1 / 1}@media screen and (min-width: 992px){.session-dot[data-v-5178a57b]{display:none!important}.session-list[data-v-5178a57b]{height:12.5vh;overflow:scroll;aspect-ratio:auto!important}}.calendar-grid[data-v-3b03c7a5]{display:grid;grid-template-areas:"sun mon tue wed thu fri sat";grid-template-columns:repeat(7,1fr)}.calendar-day.day-6[data-v-3b03c7a5]{border-right:none!important}.calendar-day[data-v-3b03c7a5]{min-height:150px}@media screen and (max-width: 992px){.calendar-day[data-v-3b03c7a5]{min-height:100px!important}}@media screen and (min-width: 992px){.dayDetail[data-v-3b03c7a5]{display:none}}.extra-day .day-label[data-v-3b03c7a5]{opacity:.5}.peerNav .nav-link{&.active[data-v-b4fba9bc]{background-color:#efefef}}th[data-v-b4fba9bc],td[data-v-b4fba9bc]{background-color:transparent!important}@media screen and (max-width: 576px){.titleBtn[data-v-b4fba9bc]{flex-basis:100%}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{Q as l}from"./browser-DFwZaPoQ.js";import{L as _}from"./localeText-Dmcj5qqx.js";import{_ as h,h as f,c,f as s,a as e,b as p,d as i,j as m,n as u,g,D as v}from"./index-DXzxfcZW.js";import"./galois-field-I2lBzzs-.js";const w={name:"peerQRCode",components:{LocaleText:_},props:{selectedPeer:Object},setup(){return{dashboardStore:v()}},data(){return{loading:!0}},mounted(){g("/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};l.toCanvas(document.querySelector("#awg_vpn_qrcode"),btoa(JSON.stringify(a)),d=>{d&&console.error(d)})}t=o.data.file,l.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"},x={class:"container d-flex h-100 w-100"},P={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},C={class:"card rounded-3 shadow"},y={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},S={class:"mb-0"},k={class:"card-body p-4"},q={class:"d-flex gap-2 flex-column"},L={class:"d-flex flex-column gap-2 align-items-center"},N={key:0,class:"d-flex flex-column gap-2 align-items-center"},Q={key:1,class:"spinner-border m-auto",role:"status"};function z(o,t,a,d,r,A){const n=f("LocaleText");return s(),c("div",b,[e("div",x,[e("div",P,[e("div",C,[e("div",y,[e("h4",S,[p(n,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=R=>this.$emit("close"))})]),e("div",k,[e("div",q,[e("div",L,[e("canvas",{id:"qrcode",style:{width:"200px !important",height:"200px !important"},class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),this.selectedPeer.configuration.Protocol==="wg"?(s(),m(n,{key:0,t:"Scan with WireGuard App",class:"text-muted"})):i("",!0),this.selectedPeer.configuration.Protocol==="awg"?(s(),m(n,{key:1,t:"Scan with AmneziaWG App",class:"text-muted"})):i("",!0)]),this.selectedPeer.configuration.Protocol==="awg"?(s(),c("div",N,[e("canvas",{id:"awg_vpn_qrcode",class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),p(n,{t:"Scan with AmneziaVPN App",class:"text-muted"})])):i("",!0),r.loading?(s(),c("div",Q,[...t[1]||(t[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)])])):i("",!0)])])])])])])}const $=h(w,[["render",z],["__scopeId","data-v-02f2240d"]]);export{$ as default};
|
||||
@@ -1 +0,0 @@
|
||||
@media screen and (max-width: 768px){.qrcode[data-v-02f2240d]{width:100%!important;height:auto!important;aspect-ratio:1/1}}.qrcode[data-v-02f2240d]{width:200px!important;height:200px!important}
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as p,q as m,G as f,W as h,r as u,a0 as _,L as v,K as g,o as x,a1 as S,c as y,d as b,f as B,a as s,m as w,y as T}from"./index-DXzxfcZW.js";const q={key:0,class:"fixed-bottom w-100 bottom-0 z-2 p-3",style:{"z-index":"1"}},C={class:"d-flex flex-column searchPeersContainer ms-auto p-2 rounded-5",style:{width:"300px"}},P={class:"rounded-5 border border-white p-2 d-flex align-items-center gap-1 w-100"},R=["placeholder"],k={__name:"peerSearchBar",props:["ConfigurationInfo"],emits:["close"],setup(V,{emit:z}){const l=m(()=>f("Search Peers..."));let r;const t=h(),e=u(t.searchString),d=()=>{r?(clearTimeout(r),r=setTimeout(()=>{t.searchString=e.value},300)):r=setTimeout(()=>{t.searchString=e.value},300)};_("searchBar");const a=v(),i=g();a.query.peer&&(e.value=a.query.peer,i.replace({query:null}));const n=u(!0);return x(()=>{document.querySelector("#searchPeers").focus()}),S(()=>{n.value=!1}),(G,o)=>n.value?(B(),y("div",q,[s("div",C,[s("div",P,[w(s("input",{ref:"searchBar",class:"flex-grow-1 form-control form-control-sm rounded-5 bg-transparent border-0 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:o[0]||(o[0]=c=>d()),"onUpdate:modelValue":o[1]||(o[1]=c=>e.value=c)},null,40,R),[[T,e.value]])])])])):b("",!0)}},K=p(k,[["__scopeId","data-v-576347d8"]]);export{K as default};
|
||||
@@ -1 +0,0 @@
|
||||
.searchPeersContainer[data-v-576347d8]{backdrop-filter:blur(8px);width:100%;background:linear-gradient(var(--degree),rgba(45,173,255,.4),rgba(255,108,109,.4),var(--brandColor2) 100%)}#searchPeers[data-v-576347d8]::placeholder{color:#fff}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.toggleShowKey[data-v-f702a2b1]{position:absolute;top:35px;right:12px}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.card[data-v-1a7765d4]{border-color:var(--bs-border-color)!important}textarea[data-v-01e380d2]:focus,input[data-v-01e380d2]:focus{box-shadow:none;border-color:var(--bs-border-color)!important}textarea[data-v-01e380d2]{padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as h,c as o,a as e,m as c,d as m,b as d,h as f,y as g,n as v,t as p,z as b,D as w,A as x,f as r}from"./index-DXzxfcZW.js";import{L as _}from"./localeText-Dmcj5qqx.js";const k={components:{LocaleText:_},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const s=w(),t=`input_${x()}`;return{store:s,uuid:t}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Peers[this.targetData]},methods:{async useValidation(){this.changed&&await b("/api/updateDashboardConfigurationItem",{section:"Peers",key:this.targetData,value:this.value},s=>{s.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Peers[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=s.message),this.changed=!1,this.updating=!1})}}},V={class:"form-group mb-2"},D=["for"],y=["id","disabled"],T={class:"invalid-feedback"},C={key:0,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1"};function F(s,t,a,I,n,u){const l=f("LocaleText");return r(),o("div",V,[e("label",{for:this.uuid,class:"text-muted mb-1"},[e("strong",null,[e("small",null,[d(l,{t:this.title},null,8,["t"])])])],8,D),c(e("input",{type:"text",class:v(["form-control",{"is-invalid":n.showInvalidFeedback,"is-valid":n.isValid}]),id:this.uuid,"onUpdate:modelValue":t[0]||(t[0]=i=>this.value=i),onKeydown:t[1]||(t[1]=i=>this.changed=!0),onBlur:t[2]||(t[2]=i=>u.useValidation()),disabled:this.updating},null,42,y),[[g,this.value]]),e("div",T,p(this.invalidFeedback),1),a.warning?(r(),o("div",C,[e("small",null,[t[3]||(t[3]=e("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),d(l,{t:a.warningText},null,8,["t"])])])):m("",!0)])}const B=h(k,[["render",F]]);export{B as P};
|
||||
@@ -1 +0,0 @@
|
||||
.pingPlaceholder[data-v-a08ce97e]{width:100%;height:79.98px}.ping-move[data-v-a08ce97e],.ping-enter-active[data-v-a08ce97e],.ping-leave-active[data-v-a08ce97e]{transition:all .4s cubic-bezier(.82,.58,.17,.9)}.ping-leave-active[data-v-a08ce97e]{position:absolute;width:100%}.ping-enter-from[data-v-a08ce97e],.ping-leave-to[data-v-a08ce97e]{opacity:0;filter:blur(3px)}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{L as n}from"./localeText-Dmcj5qqx.js";import{c as a,d as r,e as s,j as i,f as e}from"./index-DXzxfcZW.js";const d={class:"position-relative"},c={key:0,class:"badge wireguardBg rounded-3 shadow z-1"},l={key:1,class:"badge amneziawgBg rounded-3 shadow"},p={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(o){return(m,t)=>(e(),a("div",d,[o.protocol==="wg"?(e(),a("span",c,[t[0]||(t[0]=s(" WireGuard ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):o.protocol==="awg"?(e(),a("span",l,[t[1]||(t[1]=s(" AmneziaWG ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):r("",!0)]))}};export{p as _};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.dropdownIcon[data-v-ccf48ac7]{transition:all .2s ease-in-out}.dropdownIcon.active[data-v-ccf48ac7]{transform:rotate(180deg)}.steps{&[data-v-324df2b1]{transition:all .3s ease-in-out;opacity:.3}&.active[data-v-324df2b1]{opacity:1}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.btn.disabled[data-v-abe2acbc]{opacity:1;background-color:#0d6efd17;border-color:transparent}[data-v-73513cfe]{font-size:.875rem}input[data-v-73513cfe]{padding:.1rem .4rem}input[data-v-73513cfe]:disabled{border-color:transparent;background-color:#0d6efd17;color:#0d6efd}.dp__main[data-v-73513cfe]{width:auto;flex-grow:1;--dp-input-padding: 2.5px 30px 2.5px 12px;--dp-border-radius: .5rem}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.card[data-v-177407c1]{height:100%}.dashboardModal[data-v-177407c1]{height:calc(100% - 1rem)!important}@media screen and (min-height: 700px){.card[data-v-177407c1]{height:700px}}.peerBtn[data-v-177407c1]{border:var(--bs-border-width) solid var(--bs-border-color)}.peerBtn.active[data-v-177407c1]{border:var(--bs-border-width) solid var(--bs-body-color)}
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as c,z as D,D as m,A as x,c as i,a as t,t as S,m as l,y as u,e as p,f as o,b as n,F as $,i as w,h as r,w as I}from"./index-DXzxfcZW.js";import{P}from"./peersDefaultSettingsInput-KXSGcg6g.js";import{A as k,a as A,D as y,b as C,c as V,d as F,e as T,_ as L}from"./dashboardEmailSettings-BNCV3lPl.js";import{D as R,a as W}from"./dashboardSettingsWireguardConfigurationAutostart-DWZoKQw6.js";import{L as U}from"./localeText-Dmcj5qqx.js";import"./dayjs.min-C-brjxlJ.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";const B={name:"dashboardSettingsInputIPAddressAndPort",props:{},setup(){const e=m(),s=`input_${x()}`;return{store:e,uuid:s}},data(){return{app_ip:"",app_port:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.app_ip=this.store.Configuration.Server.app_ip,this.app_port=this.store.Configuration.Server.app_port},methods:{async useValidation(){this.changed&&await D("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},e=>{e.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=e.message)})}}},G={class:"invalid-feedback d-block mt-0"},N={class:"row"},E={class:"form-group mb-2 col-sm"},M=["for"],j=["id"],z={class:"form-group col-sm"},K=["for"],q=["id"];function H(e,s,h,_,b,f){return o(),i("div",null,[t("div",G,S(this.invalidFeedback),1),t("div",N,[t("div",E,[t("label",{for:"app_ip_"+this.uuid,class:"text-muted mb-1"},[...s[2]||(s[2]=[t("strong",null,[t("small",null,"Dashboard IP Address")],-1)])],8,M),l(t("input",{type:"text",class:"form-control mb-2",id:"app_ip_"+this.uuid,"onUpdate:modelValue":s[0]||(s[0]=a=>this.app_ip=a)},null,8,j),[[u,this.app_ip]]),s[3]||(s[3]=t("div",{class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block"},[t("small",null,[t("i",{class:"bi bi-exclamation-triangle-fill me-2"}),t("code",null,"0.0.0.0"),p(" means it can be access by anyone with your server IP Address.")])],-1))]),t("div",z,[t("label",{for:"app_port_"+this.uuid,class:"text-muted mb-1"},[...s[4]||(s[4]=[t("strong",null,[t("small",null,"Dashboard Port")],-1)])],8,K),l(t("input",{type:"text",class:"form-control mb-2",id:"app_port_"+this.uuid,"onUpdate:modelValue":s[1]||(s[1]=a=>this.app_port=a)},null,8,q),[[u,this.app_port]])])]),s[5]||(s[5]=t("button",{class:"btn btn-success btn-sm fw-bold rounded-3"},[t("i",{class:"bi bi-floppy-fill me-2"}),p("Update Dashboard Settings & Restart ")],-1))])}const J=c(B,[["render",H]]),O={name:"settings",components:{DashboardEmailSettings:L,DashboardSettingsWireguardConfigurationAutostart:W,DashboardIPPortInput:T,DashboardLanguage:F,LocaleText:U,AccountSettingsMFA:V,DashboardAPIKeys:C,DashboardSettingsInputIPAddressAndPort:J,DashboardTheme:y,DashboardSettingsInputWireguardConfigurationPath:R,AccountSettingsInputPassword:A,AccountSettingsInputUsername:k,PeersDefaultSettingsInput:P},setup(){return{dashboardConfigurationStore:m()}},data(){return{activeTab:"WGDashboard",tabs:[{id:"",title:"WGDashboard Settings"},{id:"peers_settings",title:"Peers Settings"},{id:"wireguard_settings",title:"WireGuard Configuration Settings"}]}}},Q={class:"mt-md-5 mt-3 text-body mb-3"},X={class:"container-md d-flex flex-column gap-3"},Y={class:"border-bottom pb-3"},Z={class:"nav nav-pills nav-justified align-items-center gap-2"},tt={class:"nav-item"},st={class:"my-2"};function et(e,s,h,_,b,f){const a=r("LocaleText"),g=r("RouterLink"),v=r("RouterView");return o(),i("div",Q,[t("div",X,[t("div",Y,[t("ul",Z,[(o(!0),i($,null,w(this.tabs,d=>(o(),i("li",tt,[n(g,{to:{name:d.title},class:"nav-link rounded-3","exact-active-class":"active",role:"button"},{default:I(()=>[t("h6",st,[n(a,{t:d.title},null,8,["t"])])]),_:2},1032,["to"])]))),256))])]),n(v)])])}const pt=c(O,[["render",et]]);export{pt as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as u,c as r,a as e,b as o,h as m,e as p,d as c,t as h,m as l,y as d,z as f,D as w,f as i}from"./index-DXzxfcZW.js";import{L as g}from"./localeText-Dmcj5qqx.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:w()}},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,f("/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"},$={for:"confirmPassword",class:"mb-1 text-muted"},q=["disabled"],A={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=m("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]=p(" 😊",-1))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):c("",!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",$,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",A,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,q)])])])],8,_)}const W=u(b,[["render",B]]);export{W as default};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user