Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 53867985d1 | |||
| b3cc1ce839 | |||
| 71aaec93ef | |||
| 7a219b73d4 | |||
| c456c5e7dd | |||
| a5880cc0b8 | |||
| 5fca628ebd | |||
| 7ab297c366 | |||
| c5de8f0f44 | |||
| c0641889cf | |||
| 9141562f91 | |||
| d21af70df1 | |||
| 56ee86cc1c | |||
| f017b4968c | |||
| 6004457666 | |||
| 1a5a0180ea | |||
| c732f149e6 | |||
| 4819480eb0 | |||
| fc7ab0dc21 | |||
| eb6b96c0f1 | |||
| f62fad9c40 | |||
| e9a472c8f7 | |||
| 552e2b8cbf | |||
| a0b4192cbd | |||
| 32a055093a | |||
| 51558c7027 | |||
| b85286f0ab | |||
| 48f3fbd715 | |||
| 458f66818a | |||
| 7964dc7993 | |||
| 0ac5d7d461 | |||
| 826914a4f3 | |||
| 261da431e7 | |||
| 94b33abf5e | |||
| 8325056ccc | |||
| 81a1b2c907 | |||
| fc8f89fb83 | |||
| d846c7745f | |||
| 61c6fd6c02 | |||
| abe5708058 | |||
| 626339bddb | |||
| 381ae23c07 | |||
| 52382d1d7a | |||
| 68e5216d4b | |||
| ceff95b336 | |||
| 782d1c215f | |||
| e8e26cfe10 | |||
| 400d4d992e | |||
| b08df55321 | |||
| b26a8110e0 | |||
| 692f550596 | |||
| badae8b8e4 | |||
| 7f89bde99e | |||
| 326717444b | |||
| 4e4bfc75e3 | |||
| 5c97a8ba73 | |||
| cba7a160ea | |||
| 4a75e1379d | |||
| 10a140d188 |
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
|
||||
@@ -18,10 +18,10 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
os: ubuntu-24.04-arm
|
||||
- platform: linux/arm/v7
|
||||
os: ubuntu-24.04-arm
|
||||
# - platform: linux/arm/v7
|
||||
# os: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
contents: write
|
||||
needs: docker-merge
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
|
||||
@@ -25,10 +25,10 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
os: ubuntu-24.04-arm
|
||||
- platform: linux/arm/v7
|
||||
os: ubuntu-24.04-arm
|
||||
# - platform: linux/arm/v7
|
||||
# os: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: master
|
||||
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
contents: write
|
||||
needs: docker-merge
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: master
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
os: ubuntu-24.04-arm
|
||||
- platform: linux/arm/v7
|
||||
os: ubuntu-24.04-arm
|
||||
# - platform: linux/arm/v7
|
||||
# os: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
|
||||
@@ -26,10 +26,10 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
os: ubuntu-24.04-arm
|
||||
- platform: linux/arm/v7
|
||||
os: ubuntu-24.04-arm
|
||||
# - platform: linux/arm/v7
|
||||
# os: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
contents: write
|
||||
needs: docker-merge
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
|
||||
Vendored
-1
@@ -3,7 +3,6 @@
|
||||
"aaron-bond.better-comments",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"antfu.goto-alias",
|
||||
"visualstudioexptteam.vscodeintellicode",
|
||||
"esbenp.prettier-vscode",
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
|
||||
+38
-5
@@ -7,19 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## Added
|
||||
## [15.2.2] - 2026-02-06
|
||||
|
||||
### Added
|
||||
|
||||
- Added Userspace WireGuard support (https://github.com/wg-easy/wg-easy/pull/2419)
|
||||
|
||||
### Fixed
|
||||
|
||||
- LangSelector overlapping with Buttons (https://github.com/wg-easy/wg-easy/pull/2434)
|
||||
- AmnzeziaWG config parameters (https://github.com/wg-easy/wg-easy/pull/2440)
|
||||
- OpenMetrics help string format (https://github.com/wg-easy/wg-easy/pull/2453)
|
||||
- Reset 2fa when resetting admin password (https://github.com/wg-easy/wg-easy/pull/2461)
|
||||
|
||||
### Docs
|
||||
|
||||
- Replace Watchtower with maintained fork (https://github.com/wg-easy/wg-easy/pull/2456)
|
||||
|
||||
## [15.2.1] - 2026-01-14
|
||||
|
||||
### Fixed
|
||||
|
||||
- Icon in Searchbar (https://github.com/wg-easy/wg-easy/commit/458f66818a400f181e2c6326ede077c8793d71f2)
|
||||
- Interface save not working (https://github.com/wg-easy/wg-easy/commit/48f3fbd715a889e2425702a8a46332f2752aef91)
|
||||
- Error Messages in Setup (https://github.com/wg-easy/wg-easy/commit/32a055093a76342c40858d8dcf563b0700a8bd48)
|
||||
|
||||
## [15.2.0] - 2026-01-12
|
||||
|
||||
### Added
|
||||
|
||||
- AmneziaWG integration (https://github.com/wg-easy/wg-easy/pull/2102, https://github.com/wg-easy/wg-easy/pull/2226)
|
||||
- Search / filter box (https://github.com/wg-easy/wg-easy/pull/2170)
|
||||
- `INIT_ALLOWED_IPS` env var (https://github.com/wg-easy/wg-easy/pull/2164)
|
||||
- Show client endpoint (https://github.com/wg-easy/wg-easy/pull/2058)
|
||||
- Add option to view and copy config (https://github.com/wg-easy/wg-easy/pull/2289)
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
|
||||
- Fix download as conf.txt (https://github.com/wg-easy/wg-easy/pull/2269)
|
||||
- Clean filename for OTL download (https://github.com/wg-easy/wg-easy/pull/2253)
|
||||
- Text color in admin menu in light mode (https://github.com/wg-easy/wg-easy/pull/2307)
|
||||
|
||||
## Changed
|
||||
### Changed
|
||||
|
||||
- Allow lower MTU (https://github.com/wg-easy/wg-easy/pull/2228)
|
||||
- Use /32 and /128 for client Cidr (https://github.com/wg-easy/wg-easy/pull/2217)
|
||||
@@ -27,11 +56,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Publish on Codeberg (https://github.com/wg-easy/wg-easy/pull/2160)
|
||||
- Allow empty DNS (https://github.com/wg-easy/wg-easy/pull/2052, https://github.com/wg-easy/wg-easy/pull/2057)
|
||||
- Don't include keys in API responses (https://github.com/wg-easy/wg-easy/pull/2015)
|
||||
- Try all QR ecc levels (https://github.com/wg-easy/wg-easy/pull/2288)
|
||||
- Update OneTimeLink expiry on reuse (https://github.com/wg-easy/wg-easy/pull/2370)
|
||||
- Removed ARMv7 support (https://github.com/wg-easy/wg-easy/pull/2369)
|
||||
|
||||
## Docs
|
||||
### Docs
|
||||
|
||||
- Add AdGuard Home (https://github.com/wg-easy/wg-easy/pull/2175)
|
||||
- Add Routed (No NAT) docs (https://github.com/wg-easy/wg-easy/pull/2181)
|
||||
- Add Routed (No NAT) docs (https://github.com/wg-easy/wg-easy/pull/2181, https://github.com/wg-easy/wg-easy/pull/2380)
|
||||
- Add AmneziaWG docs (https://github.com/wg-easy/wg-easy/pull/2108, https://github.com/wg-easy/wg-easy/pull/2292)
|
||||
|
||||
## [15.1.0] - 2025-07-01
|
||||
|
||||
|
||||
+10
-3
@@ -15,9 +15,12 @@ COPY src ./
|
||||
RUN pnpm build
|
||||
|
||||
# Build amneziawg-tools
|
||||
RUN apk add linux-headers build-base git && \
|
||||
RUN apk add linux-headers build-base go git && \
|
||||
git clone https://github.com/amnezia-vpn/amneziawg-tools.git && \
|
||||
cd amneziawg-tools/src && \
|
||||
git clone https://github.com/amnezia-vpn/amneziawg-go && \
|
||||
cd amneziawg-go && \
|
||||
make && \
|
||||
cd ../amneziawg-tools/src && \
|
||||
make
|
||||
|
||||
# Copy build result to a new image.
|
||||
@@ -33,11 +36,14 @@ COPY --from=build /app/.output /app
|
||||
COPY --from=build /app/server/database/migrations /app/server/database/migrations
|
||||
# libsql (https://github.com/nitrojs/nitro/issues/3328)
|
||||
RUN cd /app/server && \
|
||||
npm install --no-save libsql && \
|
||||
npm install --no-save --omit=dev libsql && \
|
||||
npm cache clean --force
|
||||
# cli
|
||||
COPY --from=build /app/cli/cli.sh /usr/local/bin/cli
|
||||
RUN chmod +x /usr/local/bin/cli
|
||||
# Copy amneziawg-go
|
||||
COPY --from=build /app/amneziawg-go/amneziawg-go /usr/bin/amneziawg-go
|
||||
RUN chmod +x /usr/bin/amneziawg-go
|
||||
# Copy amneziawg-tools
|
||||
COPY --from=build /app/amneziawg-tools/src/wg /usr/bin/awg
|
||||
COPY --from=build /app/amneziawg-tools/src/wg-quick/linux.bash /usr/bin/awg-quick
|
||||
@@ -52,6 +58,7 @@ RUN apk add --no-cache \
|
||||
nftables \
|
||||
kmod \
|
||||
iptables-legacy \
|
||||
wireguard-go \
|
||||
wireguard-tools
|
||||
|
||||
RUN mkdir -p /etc/amnezia
|
||||
|
||||
@@ -16,6 +16,7 @@ RUN apk add --no-cache \
|
||||
ip6tables \
|
||||
kmod \
|
||||
iptables-legacy \
|
||||
wireguard-go \
|
||||
wireguard-tools
|
||||
|
||||
# Use iptables-legacy
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 167 KiB |
@@ -2,7 +2,9 @@
|
||||
title: AmneziaWG
|
||||
---
|
||||
|
||||
Experimental support for AmneziaWG can be enabled by setting the `EXPERIMENTAL_AWG` environment variable to `true`. This feature is still under development and may change in future releases.
|
||||
## Introduction
|
||||
|
||||
**AmneziaWG** is a modified version of the WireGuard protocol with enhanced traffic obfuscation capabilities. AmneziaWG's primary goal is to counter deep packet inspection (DPI) systems and bypass VPN blocking.
|
||||
|
||||
AmneziaWG adds multi-level transport-layer obfuscation by:
|
||||
|
||||
@@ -12,6 +14,12 @@ AmneziaWG adds multi-level transport-layer obfuscation by:
|
||||
|
||||
These measures make it harder for third parties to analyze or identify your traffic, enhancing both privacy and security.
|
||||
|
||||
## Activating AmneziaWG
|
||||
|
||||
You must install the [AmneziaWG kernel module](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module) on the host system.
|
||||
|
||||
Experimental support for AmneziaWG can be enabled by setting the `EXPERIMENTAL_AWG` environment variable to `true`. Starting from wg-easy version 16, this setting will be enabled by default. This feature is still under development and may change in future releases.
|
||||
|
||||
When enabled, wg-easy will automatically detect whether the AmneziaWG kernel module is available. If it is not, the system will fall back to the standard WireGuard module.
|
||||
|
||||
To override this automatic detection, set the `OVERRIDE_AUTO_AWG` environment variable. By default, this variable is unset.
|
||||
@@ -21,17 +29,51 @@ Possible values:
|
||||
- `awg` — Force use of AmneziaWG
|
||||
- `wg` — Force use of standard WireGuard
|
||||
|
||||
To be able to connect to wg-easy if AmneziaWG is enabled, you must have a AmneziaWG-compatible client.
|
||||
## AmneziaWG Parameters
|
||||
|
||||
Parameter descriptions can be found in the [AmneziaWG documentation](https://docs.amnezia.org/documentation/amnezia-wg) and on the [kernel module page](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module).
|
||||
|
||||
All parameters except I1-I5 will be set at first startup. For information on how to set I1-I5 parameters, refer to the [AmneziaWG documentation](https://docs.amnezia.org/documentation/instructions/new-amneziawg-selfhosted/#how-to-extract-a-protocol-signature-for-amneziawg-15-manually).
|
||||
|
||||
If a parameter is not set, it will not be added to the configuration. If all AmneziaWG-specific parameters are absent, AmneziaWG will be fully compatible with standard WireGuard.
|
||||
|
||||
### Parameter Compatibility Table
|
||||
|
||||
| Parameter | Can differ between server and client | Configurable on server | Configurable on client |
|
||||
| --------- | ------------------------------------ | ---------------------- | ----------------------- |
|
||||
| Jc | ✅ Yes | ✅ | ✅ |
|
||||
| Jmin | ✅ Yes | ✅ | ✅ |
|
||||
| Jmax | ✅ Yes | ✅ | ✅ |
|
||||
| S1-S4 | ❌ No, must match | ✅ | ❌ (copied from server) |
|
||||
| H1-H4 | ❌ No, must match | ✅ | ❌ (copied from server) |
|
||||
| I1-I5 | ✅ Yes | ✅ | ✅ |
|
||||
|
||||
## Client Applications
|
||||
|
||||
To be able to connect to wg-easy if AmneziaWG is enabled, you must have an AmneziaWG-compatible client. Where an AmneziaWG app is available for your platform, it is recommended to use it rather than Amnezia VPN.
|
||||
|
||||
Android:
|
||||
|
||||
- [AmneziaWG](https://play.google.com/store/apps/details?id=org.amnezia.awg) - Official Client
|
||||
- [AmneziaWG](https://play.google.com/store/apps/details?id=org.amnezia.awg) - AmneziaWG Official Client
|
||||
- [WG Tunnel](https://play.google.com/store/apps/details?id=com.zaneschepke.wireguardautotunnel) - Third Party Client
|
||||
- [Amnezia VPN](https://play.google.com/store/apps/details?id=org.amnezia.vpn) - Amnezia VPN Official Client
|
||||
|
||||
iOS and macOS:
|
||||
|
||||
- [AmneziaWG](https://apps.apple.com/us/app/amneziawg/id6478942365) - Official Client
|
||||
- [AmneziaWG](https://apps.apple.com/us/app/amneziawg/id6478942365) - AmneziaWG Official Client
|
||||
- [Amnezia VPN](https://apps.apple.com/us/app/amneziavpn/id1600529900) - Amnezia VPN Official Client
|
||||
|
||||
Windows:
|
||||
|
||||
- [AmneziaWG](https://github.com/amnezia-vpn/amneziawg-windows-client/releases) - Official Client
|
||||
- [AmneziaWG](https://github.com/amnezia-vpn/amneziawg-windows-client/releases) - AmneziaWG Official Client (Requires building from source code)
|
||||
- [Amnezia VPN](https://amnezia.org/downloads) - Amnezia VPN Official Client
|
||||
|
||||
Linux:
|
||||
|
||||
- [Amnezia VPN](https://amnezia.org/downloads) - Amnezia VPN Official Client
|
||||
- [amneziawg-tools](https://github.com/amnezia-vpn/amneziawg-tools) - AmneziaWG Tools
|
||||
|
||||
OpenWRT:
|
||||
|
||||
- [AmneziaWG OpenWRT](https://github.com/Slava-Shchipunov/awg-openwrt) - AmneziaWG OpenWRT Packages
|
||||
- [AmneziaWG OpenWRT](https://github.com/lolo6oT/awg-openwrt) - AmneziaWG OpenWRT Packages
|
||||
|
||||
@@ -7,7 +7,7 @@ This guide will help you migrate from `v14` to version `v15` of `wg-easy`.
|
||||
## Changes
|
||||
|
||||
- This is a complete rewrite of the `wg-easy` project, therefore the configuration files and the way you interact with the project have changed.
|
||||
- If you use armv6, you unfortunately won't be able to migrate to `v15`.
|
||||
- If you use armv6 or armv7, you unfortunately won't be able to migrate to `v15`.
|
||||
- If you are connecting to the Web UI via HTTP, you need to set the `INSECURE` environment variable to `true` in the new container.
|
||||
|
||||
## Migration
|
||||
|
||||
@@ -20,7 +20,7 @@ File: `/etc/docker/containers/watchtower/docker-compose.yml`
|
||||
```yaml
|
||||
services:
|
||||
watchtower:
|
||||
image: containrrr/watchtower:latest
|
||||
image: nickfedor/watchtower:latest
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
env_file:
|
||||
|
||||
@@ -8,7 +8,7 @@ title: Basic Installation
|
||||
|
||||
1. You need to have a host that you can manage
|
||||
2. You need to have a domain name or a public IP address
|
||||
3. You need a supported architecture (x86_64, arm64, armv7)
|
||||
3. You need a supported architecture (x86_64, arm64)
|
||||
4. You need curl installed on your host
|
||||
|
||||
## Install Docker
|
||||
|
||||
@@ -93,3 +93,19 @@ PostDown
|
||||
```shell
|
||||
iptables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; ip6tables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT
|
||||
```
|
||||
|
||||
/// warning | Important: When using nftables use the following hooks instead.
|
||||
|
||||
PostUp
|
||||
|
||||
```shell
|
||||
nft add chain ip filter WG_EASY; nft add rule ip filter DOCKER-USER jump WG_EASY; nft add rule ip filter WG_EASY iifname {{device}} accept; nft add rule ip filter WG_EASY oifname {{device}} accept; nft add chain ip6 filter WG_EASY; nft add rule ip6 filter DOCKER-USER jump WG_EASY; nft add rule ip6 filter WG_EASY iifname {{device}} accept; nft add rule ip6 filter WG_EASY oifname {{device}} accept;
|
||||
```
|
||||
|
||||
PostDown
|
||||
|
||||
```shell
|
||||
nft delete rule ip filter DOCKER-USER handle $(nft -a list chain ip filter DOCKER-USER | awk '/jump WG_EASY/ {print $NF}'); nft flush chain ip filter WG_EASY; nft delete chain ip filter WG_EASY; nft delete rule ip6 filter DOCKER-USER handle $(nft -a list chain ip6 filter DOCKER-USER | awk '/jump WG_EASY/ {print $NF}'); nft flush chain ip6 filter WG_EASY; nft delete chain ip6 filter WG_EASY
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -12,7 +12,7 @@ Before you can get started with deploying your own VPN, there are some requireme
|
||||
|
||||
1. You need to have a host that you can manage
|
||||
2. You need to have a domain name or a public IP address
|
||||
3. You need a supported architecture (x86_64, arm64, armv7)
|
||||
3. You need a supported architecture (x86_64, arm64)
|
||||
|
||||
### Host Setup
|
||||
|
||||
@@ -45,15 +45,15 @@ All workflows are using the tagging convention listed below. It is subsequently
|
||||
| tag | Type | Example | Description |
|
||||
| ------------- | ------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| `15` | latest minor for that major tag | `ghcr.io/wg-easy/wg-easy:15` | latest features for specific major versions, no breaking changes, recommended |
|
||||
| `latest` | latest tag | `ghcr.io/wg-easy/wg-easy:latest` or `ghcr.io/wg-easy/wg-easy` | points to latest release, can include breaking changes |
|
||||
| `15.0` | latest patch for that minor tag | `ghcr.io/wg-easy/wg-easy:15.0` | latest patches for specific minor version |
|
||||
| `15.0.0` | specific tag | `ghcr.io/wg-easy/wg-easy:15.0.0` | specific release, no updates |
|
||||
| `edge` | push to `master` | `ghcr.io/wg-easy/wg-easy:edge` | mostly unstable, gets frequent package and code updates |
|
||||
| `development` | pull requests | `ghcr.io/wg-easy/wg-easy:development` | used for development, testing code from PRs |
|
||||
| `latest` | latest tag | `ghcr.io/wg-easy/wg-easy:latest` or `ghcr.io/wg-easy/wg-easy` | points to the v14 release, should be avoided |
|
||||
|
||||
<!-- ref: major version (check links too) -->
|
||||
|
||||
When publishing a tag we follow the [Semantic Versioning][semver] specification. The `latest` tag is always pointing to the latest stable release. If you want to avoid breaking changes, use the major version tag (e.g. `15`).
|
||||
When publishing a tag we follow the [Semantic Versioning][semver] specification. Pin to the latest major version to avoid breaking changes (e.g. `15`), avoid using the `latest` tag.
|
||||
|
||||
[github-ci]: https://github.com/wg-easy/wg-easy/actions
|
||||
[ghcr-image]: https://github.com/wg-easy/wg-easy/pkgs/container/wg-easy
|
||||
|
||||
@@ -8,7 +8,7 @@ hide:
|
||||
|
||||
/// info | This Documentation is Versioned
|
||||
|
||||
**Make sure** to select the correct version of this documentation! It should match the version of the image you are using. The default version corresponds to the `:latest` image tag - [the most recent stable release][docs-tagging].
|
||||
**Make sure** to select the correct version of this documentation! It should match the version of the image you are using. The default version corresponds to [the most recent stable release][docs-tagging].
|
||||
///
|
||||
|
||||
This documentation provides you not only with the basic setup and configuration of `wg-easy` but also with advanced configuration, elaborate usage scenarios, detailed examples, hints and more.
|
||||
|
||||
+3
-2
@@ -7,10 +7,11 @@
|
||||
"build": "docker build -t wg-easy .",
|
||||
"docs:preview": "docker run --rm -it -p 8080:8080 -v ./docs:/docs squidfunk/mkdocs-material serve -a 0.0.0.0:8080",
|
||||
"scripts:version": "bash scripts/version.sh",
|
||||
"scripts:i18n": "bash scripts/i18n.sh",
|
||||
"format:check:docs": "prettier --check docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.6.2"
|
||||
"prettier": "^3.8.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.21.0"
|
||||
"packageManager": "pnpm@10.29.2"
|
||||
}
|
||||
|
||||
Generated
+5
-5
@@ -9,16 +9,16 @@ importers:
|
||||
.:
|
||||
devDependencies:
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
specifier: ^3.8.1
|
||||
version: 3.8.1
|
||||
|
||||
packages:
|
||||
|
||||
prettier@3.6.2:
|
||||
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||
prettier@3.8.1:
|
||||
resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
prettier@3.6.2: {}
|
||||
prettier@3.8.1: {}
|
||||
|
||||
@@ -30,6 +30,7 @@ echo "Updated package.json to version $new_version"
|
||||
|
||||
echo "----"
|
||||
echo "If you changed the major version, remember to update the docker-compose.yml file and docs (search for: ref: major version)"
|
||||
echo "Make sure to stage any changes before proceeding (e.g. Changelog updates)."
|
||||
echo "----"
|
||||
|
||||
echo "If you did everything press 'y' to commit the changes and create a new tag"
|
||||
|
||||
@@ -23,4 +23,6 @@ logs
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
coverage/
|
||||
|
||||
wg-easy.db
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
setups.@nuxt/test-utils="3.23.0"
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="overflow-x-auto rounded border-2 border-red-800 py-2">
|
||||
<pre
|
||||
class="mx-2 inline-block"
|
||||
@click="selectCode"
|
||||
><code ref="codeBlock">{{ code }}</code></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
code: string;
|
||||
}>();
|
||||
|
||||
const codeBlock = useTemplateRef('codeBlock');
|
||||
|
||||
function selectCode() {
|
||||
// TODO: keyboard support?
|
||||
if (codeBlock.value) {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(codeBlock.value);
|
||||
const sel = window.getSelection();
|
||||
if (sel) {
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<ClientCardCharts :client="client" />
|
||||
<div
|
||||
class="relative z-10 flex flex-col justify-between gap-3 px-3 py-3 sm:flex-row md:py-5"
|
||||
class="relative flex flex-col justify-between gap-3 px-3 py-3 sm:flex-row md:py-5"
|
||||
>
|
||||
<div class="flex w-full items-center gap-3 md:gap-4">
|
||||
<ClientCardAvatar :client="client" />
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<BaseDialog :trigger-class="triggerClass">
|
||||
<template #trigger>
|
||||
<slot />
|
||||
</template>
|
||||
<template #title>
|
||||
{{ $t('client.config') }}
|
||||
</template>
|
||||
<template #description>
|
||||
<div v-if="status === 'success'">
|
||||
<BaseCodeBlock :code="config ?? ''" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<span>{{ $t('general.loading') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<DialogClose as-child>
|
||||
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
|
||||
</DialogClose>
|
||||
<DialogClose as-child>
|
||||
<BasePrimaryButton @click="copyCode">
|
||||
{{ $t('copy.copy') }}
|
||||
</BasePrimaryButton>
|
||||
</DialogClose>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ triggerClass?: string; clientId: number }>();
|
||||
|
||||
const toast = useToast();
|
||||
const { copied, copy, isSupported } = useClipboard({
|
||||
// fallback does not work
|
||||
legacy: false,
|
||||
});
|
||||
|
||||
const { data: config, status } = useFetch(
|
||||
`/api/client/${props.clientId}/configuration`,
|
||||
{
|
||||
responseType: 'text',
|
||||
server: false,
|
||||
}
|
||||
);
|
||||
|
||||
async function copyCode() {
|
||||
if (status.value !== 'success') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSupported.value) {
|
||||
toast.showToast({
|
||||
type: 'error',
|
||||
message: $t('copy.notSupported'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await copy(config.value ?? '');
|
||||
|
||||
if (copied.value) {
|
||||
toast.showToast({
|
||||
type: 'success',
|
||||
message: $t('copy.copied'),
|
||||
});
|
||||
} else {
|
||||
toast.showToast({
|
||||
type: 'error',
|
||||
message: $t('copy.failed'),
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<DialogClose>
|
||||
<DialogClose as-child>
|
||||
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
|
||||
</DialogClose>
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="relative w-60 md:mr-2">
|
||||
<div class="relative flex h-full items-center">
|
||||
<MagnifyingGlassIcon
|
||||
<IconsMagnifyingGlass
|
||||
class="absolute left-2.5 h-4 w-4 text-gray-400 dark:text-neutral-500"
|
||||
/>
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
:placeholder="$t('client.search')"
|
||||
class="w-full rounded bg-white py-2 pr-8 text-sm text-gray-900 shadow-sm ring-1 ring-gray-300 transition-all placeholder:text-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-red-600 dark:bg-neutral-800 dark:text-white dark:ring-neutral-700 dark:placeholder:text-neutral-500 dark:focus:ring-red-700"
|
||||
class="w-full rounded bg-white px-8 py-2 text-sm text-gray-900 shadow-sm ring-1 ring-gray-300 transition-all placeholder:text-gray-400 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-red-600 dark:bg-neutral-800 dark:text-white dark:ring-neutral-700 dark:placeholder:text-neutral-500 dark:focus:ring-red-700"
|
||||
@input="updateSearch"
|
||||
/>
|
||||
<button
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<MagnifyingGlassIcon />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MagnifyingGlassIcon from '@heroicons/vue/24/outline/esm/MagnifyingGlassIcon';
|
||||
</script>
|
||||
@@ -7,7 +7,7 @@
|
||||
href="https://github.com/wg-easy/wg-easy"
|
||||
>WireGuard Easy</a
|
||||
>
|
||||
({{ globalStore.information?.currentRelease }}) © 2021-2025 by
|
||||
({{ globalStore.information?.currentRelease }}) © 2021-2026 by
|
||||
<a
|
||||
class="hover:underline"
|
||||
target="_blank"
|
||||
|
||||
@@ -4,25 +4,27 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const event = useRequestEvent();
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const userData = await authStore.getSession();
|
||||
authStore.userData = await authStore.getSession(event);
|
||||
|
||||
// skip login if already logged in
|
||||
if (to.path === '/login') {
|
||||
if (userData?.username) {
|
||||
if (authStore.userData?.username) {
|
||||
return navigateTo('/', { redirectCode: 302 });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Require auth for every page other than Login
|
||||
if (!userData?.username) {
|
||||
if (!authStore.userData?.username) {
|
||||
return navigateTo('/login', { redirectCode: 302 });
|
||||
}
|
||||
|
||||
// Check for admin access
|
||||
if (to.path.startsWith('/admin')) {
|
||||
if (!hasPermissions(userData, 'admin', 'any')) {
|
||||
if (!hasPermissions(authStore.userData, 'admin', 'any')) {
|
||||
return abortNavigation('Not allowed to access Admin Panel');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
v-for="(item, index) in menuItems"
|
||||
:key="index"
|
||||
:to="`/admin/${item.id}`"
|
||||
active-class="bg-red-800 rounded"
|
||||
class="group rounded"
|
||||
active-class="bg-red-800 active"
|
||||
>
|
||||
<BaseSecondaryButton
|
||||
as="span"
|
||||
class="w-full cursor-pointer rounded p-2 font-medium transition-colors duration-200 hover:bg-red-800 dark:text-neutral-200"
|
||||
class="w-full font-medium group-[.active]:text-white"
|
||||
>
|
||||
{{ item.name }}
|
||||
</BaseSecondaryButton>
|
||||
@@ -37,9 +38,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const authStore = useAuthStore();
|
||||
authStore.update();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
@@ -179,13 +179,25 @@
|
||||
@delete="deleteClient"
|
||||
>
|
||||
<FormSecondaryActionField
|
||||
label="Delete"
|
||||
:label="$t('client.delete')"
|
||||
class="w-full"
|
||||
type="button"
|
||||
tabindex="-1"
|
||||
as="span"
|
||||
/>
|
||||
</ClientsDeleteDialog>
|
||||
<ClientsConfigDialog
|
||||
trigger-class="col-span-2"
|
||||
:client-id="data.id"
|
||||
>
|
||||
<FormSecondaryActionField
|
||||
:label="$t('client.viewConfig')"
|
||||
class="w-full"
|
||||
type="button"
|
||||
tabindex="-1"
|
||||
as="span"
|
||||
/>
|
||||
</ClientsConfigDialog>
|
||||
</FormGroup>
|
||||
</FormElement>
|
||||
</PanelBody>
|
||||
@@ -194,9 +206,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const authStore = useAuthStore();
|
||||
const globalStore = useGlobalStore();
|
||||
authStore.update();
|
||||
|
||||
const route = useRoute();
|
||||
const id = route.params.id as string;
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const authStore = useAuthStore();
|
||||
authStore.update();
|
||||
|
||||
const globalStore = useGlobalStore();
|
||||
const clientsStore = useClientsStore();
|
||||
|
||||
|
||||
@@ -67,9 +67,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const authStore = useAuthStore();
|
||||
authStore.update();
|
||||
|
||||
const toast = useToast();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@
|
||||
import { encodeQR } from 'qr';
|
||||
|
||||
const authStore = useAuthStore();
|
||||
authStore.update();
|
||||
|
||||
const name = ref(authStore.userData?.name);
|
||||
const email = ref(authStore.userData?.email);
|
||||
|
||||
+14
-7
@@ -1,18 +1,25 @@
|
||||
export const useAuthStore = defineStore('Auth', () => {
|
||||
const { data: userData, refresh: update } = useFetch('/api/session', {
|
||||
method: 'get',
|
||||
});
|
||||
import type { H3Event } from 'h3';
|
||||
import type { SharedPublicUser } from '~~/shared/utils/permissions';
|
||||
|
||||
async function getSession() {
|
||||
export const useAuthStore = defineStore('Auth', () => {
|
||||
const userData = useState<SharedPublicUser | null>('user-data', () => null);
|
||||
|
||||
async function getSession(event?: H3Event) {
|
||||
const fetch = event?.$fetch || $fetch;
|
||||
try {
|
||||
const { data } = await useFetch('/api/session', {
|
||||
const data = await fetch('/api/session', {
|
||||
method: 'get',
|
||||
});
|
||||
return data.value;
|
||||
return data;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function update() {
|
||||
const data = await getSession();
|
||||
userData.value = data;
|
||||
}
|
||||
|
||||
return { userData, update, getSession };
|
||||
});
|
||||
|
||||
@@ -66,10 +66,11 @@ export const useClientsStore = defineStore('Clients', () => {
|
||||
const clientPersist = clientsPersist.value[client.id]!;
|
||||
|
||||
// Debug
|
||||
// client.transferRx = this.clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
|
||||
// client.transferTx = this.clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
|
||||
// client.latestHandshakeAt = new Date();
|
||||
// this.requiresPassword = true;
|
||||
/* client.transferRx =
|
||||
clientPersist.transferRxPrevious + Math.random() * 1000;
|
||||
client.transferTx =
|
||||
clientPersist.transferTxPrevious + Math.random() * 1000;
|
||||
client.latestHandshakeAt = new Date().toISOString(); */
|
||||
|
||||
clientPersist.transferRxCurrent =
|
||||
(client.transferRx ?? 0) - clientPersist.transferRxPrevious;
|
||||
|
||||
+3
-1
@@ -18,7 +18,7 @@ const db = drizzle({ client, schema });
|
||||
const dbAdminReset = defineCommand({
|
||||
meta: {
|
||||
name: 'db:admin:reset',
|
||||
description: 'Reset the admin user',
|
||||
description: 'Reset the admin user password and TOTP settings',
|
||||
},
|
||||
args: {
|
||||
password: {
|
||||
@@ -61,6 +61,8 @@ const dbAdminReset = defineCommand({
|
||||
.update(schema.user)
|
||||
.set({
|
||||
password: hash,
|
||||
totpVerified: false,
|
||||
totpKey: null,
|
||||
})
|
||||
.where(eq(schema.user.id, 1));
|
||||
|
||||
|
||||
@@ -7,12 +7,17 @@ import it from './locales/it.json';
|
||||
import ru from './locales/ru.json';
|
||||
import zhhk from './locales/zh-HK.json';
|
||||
import zhcn from './locales/zh-CN.json';
|
||||
import zhtw from './locales/zh-TW.json';
|
||||
import ko from './locales/ko.json';
|
||||
import es from './locales/es.json';
|
||||
import ptbr from './locales/pt-BR.json';
|
||||
import tr from './locales/tr.json';
|
||||
import bn from './locales/bn.json';
|
||||
import id from './locales/id.json';
|
||||
import nl from './locales/nl.json';
|
||||
import nb from './locales/nb.json';
|
||||
import bg from './locales/bg.json';
|
||||
import gl from './locales/gl.json';
|
||||
|
||||
export default defineI18nConfig(() => ({
|
||||
legacy: false,
|
||||
@@ -27,11 +32,16 @@ export default defineI18nConfig(() => ({
|
||||
ru,
|
||||
'zh-HK': zhhk,
|
||||
'zh-CN': zhcn,
|
||||
'zh-TW': zhtw,
|
||||
ko,
|
||||
es,
|
||||
'pt-BR': ptbr,
|
||||
tr,
|
||||
bn,
|
||||
id,
|
||||
nl,
|
||||
nb,
|
||||
bg,
|
||||
gl,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Профил",
|
||||
"clients": "Клиенти",
|
||||
"admin": {
|
||||
"panel": "Админ Панел",
|
||||
"general": "Общи",
|
||||
"config": "Конфигурация",
|
||||
"interface": "Интерфейс",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "Имейл"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Текуща парола",
|
||||
"enable2fa": "Активирай двуфакторна автентикация",
|
||||
"enable2faDesc": "Сканирай QR кода с твоето приложение за автентикатор или въведи ключа ръчно.",
|
||||
"2faKey": "TOTP ключ",
|
||||
"2faCodeDesc": "Въведи кода от твоето приложение за автентикатор.",
|
||||
"disable2fa": "Деактивирай двуфакторна автентикация",
|
||||
"disable2faDesc": "Въведи паролата си, за да деактивираш двуфакторната автентикация."
|
||||
},
|
||||
"general": {
|
||||
"name": "Име",
|
||||
"username": "Потребителско име",
|
||||
"password": "Парола",
|
||||
"newPassword": "Нова парола",
|
||||
"updatePassword": "Обнови парола",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Разрешени IP-та",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Постоянно поддържане на връзката",
|
||||
"logout": "Изход",
|
||||
"continue": "Продължи",
|
||||
"host": "Хост",
|
||||
"port": "Порт",
|
||||
"yes": "Да",
|
||||
"no": "Не",
|
||||
"confirmPassword": "Потвърди парола",
|
||||
"loading": "Зареждане...",
|
||||
"2fa": "Двуфакторна автентикация",
|
||||
"2faCode": "TOTP код"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Добре дошъл в първоначалната настройка на wg-easy",
|
||||
"welcomeDesc": "Откри най-лесния начин да инсталираш и управляваш WireGuard на всеки Linux сървър",
|
||||
"existingSetup": "Имаш ли вече съществуваща инсталация?",
|
||||
"createAdminDesc": "Моля, първо въведи администраторско потребителско име и силна сигурна парола. Тези данни ще се използват за вход в административния панел.",
|
||||
"setupConfigDesc": "Моля, въведи хост и порт. Тази информация ще се използва при генериране на клиентски конфигурации за WireGuard.",
|
||||
"setupMigrationDesc": "Ако желаеш да мигрираш данните от предишна версия на wg-easy, качи резервното копие.",
|
||||
"upload": "Качи",
|
||||
"migration": "Възстанови от резервно копие:",
|
||||
"createAccount": "Създай акаунт",
|
||||
"successful": "Настройката е успешна",
|
||||
"hostDesc": "Публично име/адрес, към който клиентите ще се свързват",
|
||||
"portDesc": "Публичен UDP порт, на който клиентите ще се свързват и на който WireGuard слуша"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Налична е актуализация!",
|
||||
"update": "Актуализирай"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Тъмна тема",
|
||||
"light": "Светла тема",
|
||||
"system": "Системна тема"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Покажи/скрий графики",
|
||||
"donate": "Дарение"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Вход",
|
||||
"rememberMe": "Запомни ме",
|
||||
"rememberMeDesc": "Остани влязъл след затваряне на браузъра",
|
||||
"insecure": "Не можеш да влезеш през несигурна връзка. Използвай HTTPS.",
|
||||
"2faRequired": "Изисква се двуфакторна автентикация",
|
||||
"2faWrong": "Грешен код за двуфакторна автентикация"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Все още няма клиенти.",
|
||||
"newShort": "Нов",
|
||||
"sort": "Сортирай",
|
||||
"create": "Създай клиент",
|
||||
"created": "Клиентът е създаден",
|
||||
"new": "Нов клиент",
|
||||
"name": "Име",
|
||||
"expireDate": "Дата на изтичане",
|
||||
"expireDateDesc": "Дата, след която клиентът ще бъде деактивиран. Празно = постоянен",
|
||||
"delete": "Изтрий",
|
||||
"deleteClient": "Изтрий клиент",
|
||||
"deleteDialog1": "Сигурен ли си, че искаш да изтриеш",
|
||||
"deleteDialog2": "Това действие е необратимо.",
|
||||
"enabled": "Активен",
|
||||
"address": "Адрес",
|
||||
"serverAllowedIps": "Разрешени IP-та от сървъра",
|
||||
"otlDesc": "Генерирай кратък еднократен линк",
|
||||
"permanent": "Постоянно",
|
||||
"createdOn": "Създаден на ",
|
||||
"lastSeen": "Последно видян на ",
|
||||
"totalDownload": "Общо изтеглени: ",
|
||||
"totalUpload": "Общо качени: ",
|
||||
"newClient": "Нов клиент",
|
||||
"disableClient": "Деактивирай клиент",
|
||||
"enableClient": "Активирай клиент",
|
||||
"noPrivKey": "Този клиент няма известен частен ключ. Не може да се създаде конфигурация.",
|
||||
"showQR": "Покажи QR код",
|
||||
"downloadConfig": "Изтегли конфигурация",
|
||||
"allowedIpsDesc": "Кои IP-та ще се насочват през VPN (замества глобалната настройка)",
|
||||
"serverAllowedIpsDesc": "Кои IP-та сървърът ще насочва към клиента",
|
||||
"mtuDesc": "Задава максималния размер на пакета (MTU) за VPN тунела",
|
||||
"persistentKeepaliveDesc": "Интервал (в секунди) за изпращане на keep-alive пакети. 0 = изключено",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks работят само с wg-quick",
|
||||
"hooksLeaveEmpty": "Само за wg-quick. В противен случай остави празно",
|
||||
"dnsDesc": "DNS сървър, който клиентите ще използват (замества глобалната настройка)",
|
||||
"notConnected": "Клиентът не е свързан",
|
||||
"endpoint": "Крайна точка",
|
||||
"endpointDesc": "IP адресът на клиента, от който е установена WireGuard връзката",
|
||||
"search": "Търси клиенти...",
|
||||
"config": "Конфигурация",
|
||||
"viewConfig": "Прегледай конфигурацията"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Промени",
|
||||
"cancel": "Отказ",
|
||||
"create": "Създай"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Успех",
|
||||
"saved": "Запазено",
|
||||
"error": "Грешка"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Действия",
|
||||
"save": "Запази",
|
||||
"revert": "Отмени промените",
|
||||
"sectionGeneral": "Общи",
|
||||
"sectionAdvanced": "Разширени",
|
||||
"noItems": "Няма елементи",
|
||||
"nullNoItems": "Няма елементи. Използва се глобалната конфигурация",
|
||||
"add": "Добави"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Време на сесията",
|
||||
"sessionTimeoutDesc": "Продължителност на сесията при „Запомни ме“ (в секунди)",
|
||||
"metrics": "Метрики",
|
||||
"metricsPassword": "Парола",
|
||||
"metricsPasswordDesc": "Bearer парола за достъп до metrics ендпойнт (парола или argon2 хеш)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Път за метрики в JSON формат",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Път за Prometheus метрики"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Връзка",
|
||||
"hostDesc": "Публично име/адрес за клиентите (инвалидира конфигурациите)",
|
||||
"portDesc": "Публичен UDP порт за клиентите (инвалидира конфигурациите; вероятно искаш да смениш и порта на интерфейса)",
|
||||
"allowedIpsDesc": "Разрешени IP-та за клиентите (глобална настройка)",
|
||||
"dnsDesc": "DNS сървър за клиентите (глобална настройка)",
|
||||
"mtuDesc": "MTU, който ще ползват клиентите (само за нови клиенти)",
|
||||
"persistentKeepaliveDesc": "Интервал в секунди за keep-alive към сървъра. 0 = изключено (само за нови клиенти)",
|
||||
"suggest": "Предложи",
|
||||
"suggestDesc": "Избери IP адрес или хост за полето Host"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR променен",
|
||||
"device": "Устройство",
|
||||
"deviceDesc": "Мрежово устройство, през което да се препраща WireGuard трафикът",
|
||||
"mtuDesc": "MTU, който ще ползва WireGuard",
|
||||
"portDesc": "UDP порт, на който слуша WireGuard (вероятно искаш да смениш и порта в Config)",
|
||||
"changeCidr": "Смени CIDR",
|
||||
"restart": "Рестартирай интерфейс",
|
||||
"restartDesc": "Рестартиране на WireGuard интерфейса",
|
||||
"restartWarn": "Сигурен ли си, че искаш да рестартираш интерфейса? Всички клиенти ще бъдат изключени.",
|
||||
"restartSuccess": "Интерфейсът е рестартиран"
|
||||
},
|
||||
"introText": "Добре дошъл в административния панел.\n\nТук можеш да управляваш общите настройки, конфигурацията, настройките на интерфейса и hooks.\n\nЗапочни, като избереш някоя от секциите в страничното меню."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} е задължително",
|
||||
"validNumber": "{0} трябва да е валидно число",
|
||||
"validString": "{0} трябва да е валиден текст",
|
||||
"validBoolean": "{0} трябва да е валидна булева стойност",
|
||||
"validArray": "{0} трябва да е валиден масив",
|
||||
"stringMin": "{0} трябва да съдържа поне {1} символа",
|
||||
"numberMin": "{0} трябва да е поне {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID на клиента",
|
||||
"name": "Име",
|
||||
"expiresAt": "Изтича на",
|
||||
"address4": "IPv4 адрес",
|
||||
"address6": "IPv6 адрес",
|
||||
"serverAllowedIps": "Разрешени IP-та от сървъра"
|
||||
},
|
||||
"user": {
|
||||
"username": "Потребителско име",
|
||||
"password": "Парола",
|
||||
"remember": "Запомни",
|
||||
"name": "Име",
|
||||
"email": "Имейл",
|
||||
"emailInvalid": "Имейлът трябва да е валиден",
|
||||
"passwordMatch": "Паролите трябва да съвпадат",
|
||||
"totpEnable": "Активиране на TOTP",
|
||||
"totpEnableTrue": "TOTP Enable трябва да е true",
|
||||
"totpCode": "TOTP код"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Хост"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Време на сесията",
|
||||
"metricsEnabled": "Метрики",
|
||||
"metricsPassword": "Парола за метрики"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Устройство",
|
||||
"cidrValid": "CIDR трябва да е валиден"
|
||||
},
|
||||
"otl": "Еднократен линк",
|
||||
"stringMalformed": "Невалиден формат на низа",
|
||||
"body": "Тялото трябва да е валиден обект",
|
||||
"hook": "Hook",
|
||||
"enabled": "Активиран",
|
||||
"mtu": "MTU",
|
||||
"port": "Порт",
|
||||
"persistentKeepalive": "Постоянно поддържане на връзката",
|
||||
"address": "IP адрес",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Разрешени IP-та",
|
||||
"file": "Файл"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Копиране не се поддържа",
|
||||
"copied": "Копирано!",
|
||||
"failed": "Копирането неуспешно",
|
||||
"copy": "Копирай"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Брой junk пакети (Jc)",
|
||||
"jCDescription": "Брой junk пакети за изпращане (1–128, препоръчително: 4–12)",
|
||||
"jMinLabel": "Минимален размер на junk пакети (Jmin)",
|
||||
"jMinDescription": "Минимален размер на junk пакетите (0–1279*, препоръчително: 8, трябва да е < Jmax)",
|
||||
"jMaxLabel": "Максимален размер на junk пакети (Jmax)",
|
||||
"jMaxDescription": "Максимален размер на junk пакетите (1–1280*, препоръчително: 80, трябва да е > Jmin)",
|
||||
"s1Label": "Размер на junk в init пакета (S1)",
|
||||
"s1Description": "Размер на junk в init пакета (0–1132 [1280*−148=1132], препоръчително: 15–150, S1+56 ≠ S2)",
|
||||
"s2Label": "Размер на junk в отговорния пакет (S2)",
|
||||
"s2Description": "Размер на junk в response пакета (0–1188 [1280*−92=1188], препоръчително: 15–150)",
|
||||
"s3Label": "Размер на junk в cookie reply пакета (S3)",
|
||||
"s3Description": "Размер на junk в cookie reply пакета",
|
||||
"s4Label": "Размер на junk в транспортния пакет (S4)",
|
||||
"s4Description": "Размер на junk в транспортния пакет",
|
||||
"i1Label": "Специален junk пакет 1 (I1)",
|
||||
"i1Description": "Пакет за имитация на протокол в hex формат: <b 0x...>",
|
||||
"i2Label": "Специален junk пакет 2 (I2)",
|
||||
"i2Description": "Пакет за имитация на протокол в hex формат: <b 0x...>",
|
||||
"i3Label": "Специален junk пакет 3 (I3)",
|
||||
"i3Description": "Пакет за имитация на протокол в hex формат: <b 0x...>",
|
||||
"i4Label": "Специален junk пакет 4 (I4)",
|
||||
"i4Description": "Пакет за имитация на протокол в hex формат: <b 0x...>",
|
||||
"i5Label": "Специален junk пакет 5 (I5)",
|
||||
"i5Description": "Пакет за имитация на протокол в hex формат: <b 0x...>",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Стойност на хедера в init пакета (5–2147483647, уникална спрямо H2–H4)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Стойност на хедера в response пакета (5–2147483647, уникална спрямо H1, H3, H4)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Стойност на хедера в cookie reply пакета (5–2147483647, уникална спрямо H1, H2, H4)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Стойност на хедера в транспортния пакет (5–2147483647, уникална спрямо H1–H3)",
|
||||
"mtuNote": "Стойностите зависят от MTU",
|
||||
"obfuscationParameters": "Параметри за обфускация на AmneziaWG"
|
||||
}
|
||||
}
|
||||
+74
-25
@@ -11,12 +11,12 @@
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "Email"
|
||||
"email": "E-Mail"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Aktuelles Passwort",
|
||||
"enable2fa": "Zwei-Faktor-Authentifizierunng aktivieren",
|
||||
"enable2faDesc": "Scannen Sie den QR-Code mit ihrer Authentifizierungs-App oder geben Sie den Schlüssel manuell ein.",
|
||||
"enable2fa": "Zwei-Faktor-Authentifizierung aktivieren",
|
||||
"enable2faDesc": "Scannen Sie den QR-Code mit Ihrer Authentifizierungs-App oder geben Sie den Schlüssel manuell ein.",
|
||||
"2faKey": "TOTP-Schlüssel",
|
||||
"2faCodeDesc": "Geben Sie den Code aus Ihrer Authentifizierungs-App ein.",
|
||||
"disable2fa": "Zwei-Faktor-Authentifizierung deaktivieren",
|
||||
@@ -45,26 +45,26 @@
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Willkommen zur Ersteinrichtung von wg-easy",
|
||||
"welcomeDesc": "Das ist der einfachste Weg, um Wireguard auf jedem Linux-Server zu installieren und zu betreiben.",
|
||||
"welcomeDesc": "Sie haben den einfachsten Weg gefunden, WireGuard auf jedem Linux-Server zu installieren und zu verwalten.",
|
||||
"existingSetup": "Haben Sie eine bestehende Einrichtung?",
|
||||
"createAdminDesc": "Bitte geben Sie zuerst einen Admin-Benutzernamen sowie ein starkes, sicheres Passwort ein. Diese Anmeldedaten benötigen Sie, um sich im Admin-Panel anzumelden.",
|
||||
"createAdminDesc": "Bitte geben Sie zuerst einen Admin-Benutzernamen sowie ein starkes, sicheres Passwort ein. Diese Anmeldedaten benötigen Sie, um sich in der Admin-Konsole anzumelden.",
|
||||
"setupConfigDesc": "Bitte geben Sie die Host- und Portinformationen ein. Diese werden für die Client-Konfiguration verwendet, wenn Sie WireGuard auf Ihren Geräten einrichten.",
|
||||
"setupMigrationDesc": "Bitte halten Sie die Sicherungsdatei bereit, wenn Sie Ihre Daten von Ihrer vorherigen wg-easy Version auf ihre neue Einrichtung migrieren möchten.",
|
||||
"upload": "Hochladen",
|
||||
"migration": "Sicherung wiederherstellen:",
|
||||
"migration": "Backup wiederherstellen:",
|
||||
"createAccount": "Konto erstellen",
|
||||
"successful": "Einrichtung erfolgreich",
|
||||
"hostDesc": "Öffentlicher Hostname mit dem sich die Clients verbinden",
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden und auf dem Wireguard läuft"
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden und auf dem WireGuard läuft"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Es ist ein neue Aktualisierung verfügbar!",
|
||||
"updateAvailable": "Ein neues Update ist verfügbar!",
|
||||
"update": "Aktualisieren"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Dunkles Thema",
|
||||
"light": "Helles Thema",
|
||||
"system": "System-Thema"
|
||||
"system": "System Thema"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Statistiken ein-/ausblenden",
|
||||
@@ -84,16 +84,16 @@
|
||||
"sort": "Sortieren",
|
||||
"create": "Client erstellen",
|
||||
"created": "Client wurde erstellt",
|
||||
"new": "Neuer client",
|
||||
"new": "Neuer Client",
|
||||
"name": "Name",
|
||||
"expireDate": "Ablaufdatum",
|
||||
"expireDateDesc": "Datum, an dem der Client deaktiviert wird. Leer lassen, damit dies nie passiert.",
|
||||
"expireDateDesc": "Datum, an dem der Client deaktiviert wird. Leer lassen für dauerhaft aktiv.",
|
||||
"deleteClient": "Client löschen",
|
||||
"deleteDialog1": "Sind Sie sicher, dass Sie diesen Client löschen wollen",
|
||||
"deleteDialog1": "Sind Sie sicher, dass Sie diesen Client löschen möchten",
|
||||
"deleteDialog2": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"enabled": "Aktiviert",
|
||||
"address": "Adresse",
|
||||
"serverAllowedIps": "serverseitig erlaubte IP-Adressen",
|
||||
"serverAllowedIps": "Serverseitig erlaubte IP-Adressen",
|
||||
"otlDesc": "Einen kurzen Einmal-Link erzeugen",
|
||||
"permanent": "Dauerhaft",
|
||||
"createdOn": "Angelegt am ",
|
||||
@@ -112,8 +112,15 @@
|
||||
"persistentKeepaliveDesc": "Legt das Intervall (in Sekunden) für Keepalive-Pakete fest. 0 deaktiviert es",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks funktionieren nur mit wg-quick",
|
||||
"hooksLeaveEmpty": "Nur für wg-quick. Sonst leer lassen",
|
||||
"dnsDesc": "DNS-Server, den die Clients benutzen (überschreibt die globale Konfiguration)"
|
||||
"hooksLeaveEmpty": "Nur für wg-quick. Andernfalls leer lassen",
|
||||
"dnsDesc": "DNS-Server, den die Clients benutzen (überschreibt die globale Konfiguration)",
|
||||
"delete": "Löschen",
|
||||
"notConnected": "Client nicht verbunden",
|
||||
"endpoint": "Endpunkt",
|
||||
"endpointDesc": "IP-Adresse des Clients, von dem aus die WireGuard-Verbindung hergestellt wird",
|
||||
"search": "Suche Clients...",
|
||||
"config": "Konfiguration",
|
||||
"viewConfig": "Konfiguration anzeigen"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Ändern",
|
||||
@@ -150,24 +157,24 @@
|
||||
"config": {
|
||||
"connection": "Verbindung",
|
||||
"hostDesc": "Öffentlicher Hostname mit dem sich die Clients verbinden (überschreibt die Konfiguration)",
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden (überschreibt die Konfiguration, vermutlich wollen Sie ebenfalls den Port der Weboberfläche ändern)",
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden (überschreibt die Konfiguration, vermutlich wollen Sie auch den Interface-Port ändern)",
|
||||
"allowedIpsDesc": "Erlaubte IP-Adressen, die die Clients nutzen werden (Globale Konfiguration)",
|
||||
"dnsDesc": "DNS-Server, den die Clients nutzen werden (Globale Konfiguration)",
|
||||
"mtuDesc": "MTU, den die Clients benutzen werden (nur für neue Clients)",
|
||||
"persistentKeepaliveDesc": "Intervall in Sekunden, in dem Keepalive-Packete an den Server gesendet werden. 0 = deaktiviert (nur für neue Clients)",
|
||||
"persistentKeepaliveDesc": "Intervall in Sekunden, in dem Keepalive-Pakete an den Server gesendet werden. 0 = deaktiviert (nur für neue Clients)",
|
||||
"suggest": "Vorschlagen",
|
||||
"suggestDesc": "Wählen Sie eine IP-Adresse oder einen Hostnamen für das Host-Feld aus"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR wurde geändert",
|
||||
"device": "Gerät",
|
||||
"deviceDesc": "Ethernet-Gerät, durch das der Wireguard-Datenverkehr geleitet werden soll",
|
||||
"deviceDesc": "Ethernet-Gerät, durch das der WireGuard-Datenverkehr geleitet werden soll",
|
||||
"mtuDesc": "MTU, den WireGuard benutzen wird",
|
||||
"portDesc": "UDP Port, auf dem WireGuard lauschen wird (Sie wollen wahrscheinlich auch den Config-Port ändern)",
|
||||
"portDesc": "UDP-Port, auf dem WireGuard lauschen wird (Sie wollen wahrscheinlich auch den Interface-Port ändern)",
|
||||
"changeCidr": "CIDR ändern",
|
||||
"restart": "Interface neu starten",
|
||||
"restartDesc": "Das WireGuard-Interface neu starten",
|
||||
"restartWarn": "Sind Sie sicher, dass Sie das Interface neu starten wollen? Dies wird die Verbindungen aller Clients trennen.",
|
||||
"restartWarn": "Sind Sie sicher, dass Sie das Interface neu starten möchten? Dies wird die Verbindungen aller Clients trennen.",
|
||||
"restartSuccess": "Interface neu gestartet"
|
||||
},
|
||||
"introText": "Willkommen in der Admin-Konsole.\n\nHier können Sie die allgemeinen Einstellungen, die Konfiguration, die Schnittstelleneinstellungen und die Hooks verwalten.\n\nBeginnen Sie, indem Sie einen der Bereiche in der Seitenleiste auswählen."
|
||||
@@ -188,15 +195,15 @@
|
||||
"expiresAt": "Läuft ab am",
|
||||
"address4": "IPv4-Adresse",
|
||||
"address6": "IPv6-Adresse",
|
||||
"serverAllowedIps": "serverseitig erlaubte IP-Adressen"
|
||||
"serverAllowedIps": "Serverseitig erlaubte IP-Adressen"
|
||||
},
|
||||
"user": {
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"remember": "Merken",
|
||||
"name": "Name",
|
||||
"email": "Email",
|
||||
"emailInvalid": "Die Email-Adresse muss valide sein",
|
||||
"email": "E-Mail",
|
||||
"emailInvalid": "Die E-Mail-Adresse muss gültig sein",
|
||||
"passwordMatch": "Die Passwörter müssen übereinstimmen",
|
||||
"totpEnable": "TOTP aktivieren",
|
||||
"totpEnableTrue": "\"TOTP aktivieren\" muss ausgewählt sein",
|
||||
@@ -212,8 +219,8 @@
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Geräte",
|
||||
"cidrValid": "CIDR muss valide sein"
|
||||
"device": "Gerät",
|
||||
"cidrValid": "CIDR muss gültig sein"
|
||||
},
|
||||
"otl": "Einmal-Link",
|
||||
"stringMalformed": "Zeichenkette ist fehlerhaft",
|
||||
@@ -233,5 +240,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopieren ist nicht unterstützt",
|
||||
"copied": "Kopiert!",
|
||||
"failed": "Kopieren fehlgeschlagen",
|
||||
"copy": "Kopieren"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Anzahl der Junk-Pakete (Jc)",
|
||||
"jCDescription": "Anzahl der zu sendenden Junk-Pakete (1-128, empfohlen: 4-12)",
|
||||
"jMinLabel": "Minimale Junk-Paketgröße (Jmin)",
|
||||
"jMinDescription": "Mindestgröße von Junk-Paketen (0-1279*, empfohlen: 8, muss < Jmax sein)",
|
||||
"jMaxLabel": "Maximale Junk-Paketgröße (Jmax)",
|
||||
"jMaxDescription": "Maximalgröße von Junk-Paketen (1-1280*, empfohlen: 80, muss > Jmin sein)",
|
||||
"s1Label": "Junk-Paketgröße des Init-Pakets (S1)",
|
||||
"s1Description": "Junk-Paketgröße des Init-Pakets (0-1132[1280* - 148 = 1132], empfohlen: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Junk-Paketgröße des Antwort-Pakets (S2)",
|
||||
"s2Description": "Junk-Paketgröße des Antwort-Pakets (0-1188[1280* - 92 = 1188], empfohlen: 15-150)",
|
||||
"s3Label": "Junk-Paketgröße des Cookie-Antwort-Pakets (S3)",
|
||||
"s3Description": "Junk-Paketgröße des Cookie-Antwort-Pakets",
|
||||
"s4Label": "Junk-Paketgröße des Transport-Pakets (S4)",
|
||||
"s4Description": "Junk-Paketgröße des Transport-Pakets",
|
||||
"i1Label": "Spezial-Junk-Paket 1 (I1)",
|
||||
"i1Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"i2Label": "Spezial-Junk-Paket 2 (I2)",
|
||||
"i2Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"i3Label": "Spezial-Junk-Paket 3 (I3)",
|
||||
"i3Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"i4Label": "Spezial-Junk-Paket 4 (I4)",
|
||||
"i4Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"i5Label": "Spezial-Junk-Paket 5 (I5)",
|
||||
"i5Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"h1Label": "Init-Magic-Header (H1)",
|
||||
"h1Description": "Wert des Init-Paket-Headers (5-2147483647, muss eindeutig zu H2-H4 sein)",
|
||||
"h2Label": "Antwort-Magic-Header (H2)",
|
||||
"h2Description": "Wert des Antwort-Paket-Headers (5-2147483647, muss eindeutig zu H1, H3, H4 sein)",
|
||||
"h3Label": "Cookie-Antwort-Magic-Header (H3)",
|
||||
"h3Description": "Wert des Cookie-Antwort-Paket-Headers (5-2147483647, muss eindeutig zu H1, H2, H4 sein)",
|
||||
"h4Label": "Transport-Magic-Header (H4)",
|
||||
"h4Description": "Wert des Transport-Paket-Headers (5-2147483647, muss eindeutig zu H1-H3 sein)",
|
||||
"mtuNote": "Werte hängen von der MTU ab",
|
||||
"obfuscationParameters": "AmneziaWG Verschleierungsparameter"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
"name": "Name",
|
||||
"expireDate": "Expire Date",
|
||||
"expireDateDesc": "Date the client will be disabled. Blank for permanent",
|
||||
"delete": "Delete",
|
||||
"deleteClient": "Delete Client",
|
||||
"deleteDialog1": "Are you sure you want to delete",
|
||||
"deleteDialog2": "This action cannot be undone.",
|
||||
@@ -117,7 +118,9 @@
|
||||
"notConnected": "Client not connected",
|
||||
"endpoint": "Endpoint",
|
||||
"endpointDesc": "IP of the client from which the WireGuard connection is established",
|
||||
"search": "Search clients..."
|
||||
"search": "Search clients...",
|
||||
"config": "Configuration",
|
||||
"viewConfig": "View Configuration"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Change",
|
||||
@@ -238,6 +241,12 @@
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Copy is not supported",
|
||||
"copied": "Copied!",
|
||||
"failed": "Copy failed",
|
||||
"copy": "Copy"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Junk packet count (Jc)",
|
||||
"jCDescription": "Number of junk packets to send (1-128, recommended: 4-12)",
|
||||
|
||||
+59
-13
@@ -15,12 +15,12 @@
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Mot de passe actuel",
|
||||
"enable2fa": "Activer l'authentification à double facteur",
|
||||
"enable2fa": "Activer l'authentification à deux facteurs",
|
||||
"enable2faDesc": "Scannez le code QR avec votre application d'authentification ou saisissez la clé manuellement.",
|
||||
"2faKey": "Clé TOTP",
|
||||
"2faCodeDesc": "Saisissez le code de votre application d'authentification.",
|
||||
"disable2fa": "Désactiver l'authentification à double facteur",
|
||||
"disable2faDesc": "Saisissez votre mot de passe pour désactiver l'authentification à double facteur"
|
||||
"disable2fa": "Désactiver l'authentification à deux facteurs",
|
||||
"disable2faDesc": "Saisissez votre mot de passe pour désactiver l'authentification à deux facteurs."
|
||||
},
|
||||
"general": {
|
||||
"name": "Nom",
|
||||
@@ -40,7 +40,7 @@
|
||||
"no": "Non",
|
||||
"confirmPassword": "Confirmer le mot de passe",
|
||||
"loading": "Chargement...",
|
||||
"2fa": "Authentification à double facteur",
|
||||
"2fa": "Authentification à deux facteurs",
|
||||
"2faCode": "Code TOTP"
|
||||
},
|
||||
"setup": {
|
||||
@@ -75,8 +75,8 @@
|
||||
"rememberMe": "Se souvenir de moi",
|
||||
"rememberMeDesc": "Rester connecté après avoir fermé le navigateur",
|
||||
"insecure": "Vous ne pouvez pas vous connecter avec une connexion non sécurisée. Utilisez HTTPS.",
|
||||
"2faRequired": "Une authentification à double facteur est requise",
|
||||
"2faWrong": "L'authentification à double facteur est incorrecte"
|
||||
"2faRequired": "L'authentification à deux facteurs est requise",
|
||||
"2faWrong": "Le code d'authentification à deux facteurs est incorrect"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Il n'y a pas encore de clients.",
|
||||
@@ -108,7 +108,7 @@
|
||||
"downloadConfig": "Télécharger la configuration",
|
||||
"allowedIpsDesc": "Quelles IPs seront acheminées par le VPN (remplace la configuration globale)",
|
||||
"serverAllowedIpsDesc": "Les IPs que le serveur acheminera vers le client",
|
||||
"mtuDesc": "Définit le nombre maximum d'unités de transmission (taille des paquets) pour le tunnel VPN.",
|
||||
"mtuDesc": "Définit l'unité de transmission maximale (taille des paquets) pour le tunnel VPN",
|
||||
"persistentKeepaliveDesc": "Définit l'intervalle (en secondes) pour les paquets keep-alive. 0 le désactive",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Les hooks ne fonctionnent qu'avec wg-quick",
|
||||
@@ -116,7 +116,11 @@
|
||||
"dnsDesc": "Serveur DNS que les clients utiliseront (remplace la configuration globale)",
|
||||
"notConnected": "Client non connecté",
|
||||
"endpoint": "Endpoint",
|
||||
"endpointDesc": "Adresse IP du client à partir duquel la connexion WireGuard est établie"
|
||||
"endpointDesc": "Adresse IP du client à partir duquel la connexion WireGuard est établie",
|
||||
"search": "Rechercher des clients...",
|
||||
"config": "Configuration",
|
||||
"viewConfig": "Voir la configuration",
|
||||
"delete": "Supprimer"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Modifier",
|
||||
@@ -146,9 +150,9 @@
|
||||
"metricsPassword": "Mot de passe",
|
||||
"metricsPasswordDesc": "Mot de passe Bearer pour le endpoint des métriques (mot de passe ou argon2 hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Acheminement pour les métriques au format JSON",
|
||||
"jsonDesc": "Route pour les métriques au format JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Acheminement pour les métriques de Prometheus"
|
||||
"prometheusDesc": "Route pour les métriques Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Connexion",
|
||||
@@ -180,13 +184,13 @@
|
||||
"required": "{0} est requis",
|
||||
"validNumber": "{0} doit être un nombre valide",
|
||||
"validString": "{0} doit être une chaîne de caractères valide",
|
||||
"validBoolean": "{0} doit être une variable valide",
|
||||
"validBoolean": "{0} doit être un booléen valide",
|
||||
"validArray": "{0} doit être un tableau valide",
|
||||
"stringMin": "{0} doit être d'au moins {1} Caractère",
|
||||
"stringMin": "{0} doit comporter au moins {1} caractère(s)",
|
||||
"numberMin": "{0} doit être d'au moins {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "Client ID",
|
||||
"id": "ID du client",
|
||||
"name": "Nom",
|
||||
"expiresAt": "Expire le",
|
||||
"address4": "Adresse IPv4",
|
||||
@@ -236,5 +240,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "La copie n'est pas prise en charge",
|
||||
"copied": "Copié !",
|
||||
"failed": "Échec de la copie",
|
||||
"copy": "Copier"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Nombre de paquets parasites (Jc)",
|
||||
"jCDescription": "Nombre de paquets parasites à envoyer (1-128, recommandé : 4-12)",
|
||||
"jMinLabel": "Taille min des paquets parasites (Jmin)",
|
||||
"jMinDescription": "Taille minimale des paquets parasites (0-1279*, recommandé : 8, doit être < Jmax)",
|
||||
"jMaxLabel": "Taille max des paquets parasites (Jmax)",
|
||||
"jMaxDescription": "Taille maximale des paquets parasites (1-1280*, recommandé : 80, doit être > Jmin)",
|
||||
"s1Label": "Taille parasite du paquet init (S1)",
|
||||
"s1Description": "Taille parasite du paquet d'initialisation (0-1132[1280* - 148 = 1132], recommandé : 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Taille parasite du paquet réponse (S2)",
|
||||
"s2Description": "Taille parasite du paquet de réponse (0-1188[1280* - 92 = 1188], recommandé : 15-150)",
|
||||
"s3Label": "Taille parasite du paquet cookie reply (S3)",
|
||||
"s3Description": "Taille parasite du paquet de réponse cookie",
|
||||
"s4Label": "Taille parasite du paquet transport (S4)",
|
||||
"s4Description": "Taille parasite du paquet de transport",
|
||||
"i1Label": "Paquet parasite spécial 1 (I1)",
|
||||
"i1Description": "Paquet de simulation de protocole en format hexadécimal : <b 0x...>",
|
||||
"i2Label": "Paquet parasite spécial 2 (I2)",
|
||||
"i2Description": "Paquet de simulation de protocole en format hexadécimal : <b 0x...>",
|
||||
"i3Label": "Paquet parasite spécial 3 (I3)",
|
||||
"i3Description": "Paquet de simulation de protocole en format hexadécimal : <b 0x...>",
|
||||
"i4Label": "Paquet parasite spécial 4 (I4)",
|
||||
"i4Description": "Paquet de simulation de protocole en format hexadécimal : <b 0x...>",
|
||||
"i5Label": "Paquet parasite spécial 5 (I5)",
|
||||
"i5Description": "Paquet de simulation de protocole en format hexadécimal : <b 0x...>",
|
||||
"h1Label": "En-tête magique init (H1)",
|
||||
"h1Description": "Valeur d'en-tête du paquet init (5-2147483647, doit être unique par rapport à H2-H4)",
|
||||
"h2Label": "En-tête magique réponse (H2)",
|
||||
"h2Description": "Valeur d'en-tête du paquet réponse (5-2147483647, doit être unique par rapport à H1, H3, H4)",
|
||||
"h3Label": "En-tête magique cookie reply (H3)",
|
||||
"h3Description": "Valeur d'en-tête du paquet cookie reply (5-2147483647, doit être unique par rapport à H1, H2, H4)",
|
||||
"h4Label": "En-tête magique transport (H4)",
|
||||
"h4Description": "Valeur d'en-tête du paquet transport (5-2147483647, doit être unique par rapport à H1-H3)",
|
||||
"mtuNote": "Les valeurs dépendent du MTU",
|
||||
"obfuscationParameters": "Paramètres d'obfuscation AmneziaWG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Conta",
|
||||
"clients": "Clientes",
|
||||
"admin": {
|
||||
"panel": "Panel de administración",
|
||||
"general": "Xeral",
|
||||
"config": "Configuración",
|
||||
"interface": "Interface",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "Correo electrónico"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Contrasinal actual",
|
||||
"enable2fa": "Activar a autenticación de dobre factor",
|
||||
"enable2faDesc": "Escanea o código QR coa túa aplicación de autenticación ou introduce a chave manualmente.",
|
||||
"2faKey": "Chave TOTP",
|
||||
"2faCodeDesc": "Introduce o código da túa aplicación de autenticación.",
|
||||
"disable2fa": "Desactivar a autenticación de dobre factor",
|
||||
"disable2faDesc": "Introduce o teu contrasinal para desactivar a autenticación de dobre factor."
|
||||
},
|
||||
"general": {
|
||||
"name": "Nome",
|
||||
"username": "Nome de usuario",
|
||||
"password": "Contrasinal",
|
||||
"newPassword": "Novo contrasinal",
|
||||
"updatePassword": "Actualizar contrasinal",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "IP permitidas",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Keepalive persistente",
|
||||
"logout": "Pechar sesión",
|
||||
"continue": "Continuar",
|
||||
"host": "Host",
|
||||
"port": "Porto",
|
||||
"yes": "Si",
|
||||
"no": "Non",
|
||||
"confirmPassword": "Confirmar o contrasinal",
|
||||
"loading": "Cargando...",
|
||||
"2fa": "Autenticación de dobre factor",
|
||||
"2faCode": "Código TOTP"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Benvido á túa primeira configuración de wg-easy",
|
||||
"welcomeDesc": "Atopaches a forma máis doada de instalar e xestionar WireGuard en calquera sistema Linux",
|
||||
"existingSetup": "Tes unha configuración existente?",
|
||||
"createAdminDesc": "Por favor, introduce primeiro un usuario administrador cun contrasinal seguro. Esta información empregarase para acceder ao panel de administración.",
|
||||
"setupConfigDesc": "Por favor, introduce a información do host e do porto. Isto empregarase para a configuración dos clientes ao configurar WireGuard nos seus dispositivos.",
|
||||
"setupMigrationDesc": "Por favor, fornece o ficheiro da copia de seguridade se queres migrar os datos da túa versión anterior de wg-easy á nova configuración.",
|
||||
"upload": "Subir",
|
||||
"migration": "Recuperar a copia de seguridade:",
|
||||
"createAccount": "Crear conta",
|
||||
"successful": "Configuración completada con éxito",
|
||||
"hostDesc": "Nome de host público ao que se conectarán os clientes",
|
||||
"portDesc": "Porto UDP público ao que se conectarán os clientes e no que escoitará WireGuard"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Hai unha actualización dispoñible!",
|
||||
"update": "Actualizar"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Tema escuro",
|
||||
"light": "Tema claro",
|
||||
"system": "Tema do sistema"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Amosar/Ocultar gráficas",
|
||||
"donate": "Doar"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Iniciar sesión",
|
||||
"rememberMe": "Lembrarme",
|
||||
"rememberMeDesc": "Manter a sesión iniciada ao pechar o navegador",
|
||||
"insecure": "Non podes iniciar sesión cunha conexión insegura. Usa HTTPS.",
|
||||
"2faRequired": "É necesaria a autenticación de dobre factor",
|
||||
"2faWrong": "A autenticación de dobre factor é incorrecta"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Aínda non hai clientes.",
|
||||
"newShort": "Novo",
|
||||
"sort": "Ordenar",
|
||||
"create": "Crear cliente",
|
||||
"created": "Cliente creado",
|
||||
"new": "Novo cliente",
|
||||
"name": "Nome",
|
||||
"expireDate": "Data de caducidade",
|
||||
"expireDateDesc": "Data na que o cliente será desactivado. Déixao en branco para permanente",
|
||||
"delete": "Eliminar",
|
||||
"deleteClient": "Eliminar cliente",
|
||||
"deleteDialog1": "Seguro que queres eliminar",
|
||||
"deleteDialog2": "Esta acción non se pode desfacer.",
|
||||
"enabled": "Activado",
|
||||
"address": "Enderezo",
|
||||
"serverAllowedIps": "IP permitidas polo servidor",
|
||||
"otlDesc": "Xerar ligazón curta dun só uso",
|
||||
"permanent": "Permanente",
|
||||
"createdOn": "Creado o ",
|
||||
"lastSeen": "Visto por última vez o ",
|
||||
"totalDownload": "Descarga total: ",
|
||||
"totalUpload": "Subida total: ",
|
||||
"newClient": "Novo cliente",
|
||||
"disableClient": "Desactivar cliente",
|
||||
"enableClient": "Activar cliente",
|
||||
"noPrivKey": "Este cliente non ten unha chave privada coñecida. Non se pode crear a configuración.",
|
||||
"showQR": "Amosar código QR",
|
||||
"downloadConfig": "Descargar configuración",
|
||||
"allowedIpsDesc": "IP que se encamiñarán a través da VPN (sobrescribe a configuración global)",
|
||||
"serverAllowedIpsDesc": "IP que o servidor encamiñará ao cliente",
|
||||
"mtuDesc": "Define a unidade máxima de transmisión (tamaño do paquete) para o túnel VPN",
|
||||
"persistentKeepaliveDesc": "Define o intervalo (en segundos) para os paquetes keep-alive. 0 desactívaos",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Os hooks só funcionan con wg-quick",
|
||||
"hooksLeaveEmpty": "Só para wg-quick. Noutro caso, déixao baleiro",
|
||||
"dnsDesc": "Servidor DNS que empregarán os clientes (sobrescribe a configuración global)",
|
||||
"notConnected": "Cliente non conectado",
|
||||
"endpoint": "Punto final",
|
||||
"endpointDesc": "IP do cliente desde a que se establece a conexión WireGuard",
|
||||
"search": "Buscar clientes...",
|
||||
"config": "Configuración",
|
||||
"viewConfig": "Ver configuración"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Cambiar",
|
||||
"cancel": "Cancelar",
|
||||
"create": "Crear"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Éxito",
|
||||
"saved": "Gardado",
|
||||
"error": "Erro"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Accións",
|
||||
"save": "Gardar",
|
||||
"revert": "Reverter",
|
||||
"sectionGeneral": "Xeral",
|
||||
"sectionAdvanced": "Avanzado",
|
||||
"noItems": "Sen elementos",
|
||||
"nullNoItems": "Sen elementos. Usando a configuración global",
|
||||
"add": "Engadir"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Konto",
|
||||
"clients": "Klienter",
|
||||
"admin": {
|
||||
"panel": "Adminpanel",
|
||||
"general": "Generelt",
|
||||
"config": "Oppsett",
|
||||
"interface": "Grensesnitt",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "E-post"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Nåværende passord",
|
||||
"enable2fa": "Aktiver tofaktorautentisering",
|
||||
"enable2faDesc": "Skann QR-koden med autentiseringsappen din eller skriv inn nøkkelen manuelt.",
|
||||
"2faKey": "TOTP-nøkkel",
|
||||
"2faCodeDesc": "Skriv inn koden fra autentiseringsappen din.",
|
||||
"disable2fa": "Deaktiver tofaktorautentisering",
|
||||
"disable2faDesc": "Skriv inn passordet ditt for å deaktivere tofaktorautentisering."
|
||||
},
|
||||
"general": {
|
||||
"name": "Navn",
|
||||
"username": "Brukernavn",
|
||||
"password": "Passord",
|
||||
"newPassword": "Nytt passord",
|
||||
"updatePassword": "Oppdater passord",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Tillatte IP-er",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Vedvarende keepalive",
|
||||
"logout": "Logg ut",
|
||||
"continue": "Fortsett",
|
||||
"host": "Vert",
|
||||
"port": "Port",
|
||||
"yes": "Ja",
|
||||
"no": "Nei",
|
||||
"confirmPassword": "Bekreft passord",
|
||||
"loading": "Laster...",
|
||||
"2fa": "Tofaktorautentisering",
|
||||
"2faCode": "TOTP-kode"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Velkommen til ditt oppsett av wg-easy",
|
||||
"welcomeDesc": "Du har funnet den enkleste måten å installere og administrere WireGuard på en hvilken som helst Linux-vert",
|
||||
"existingSetup": "Har du et eksisterende oppsett?",
|
||||
"createAdminDesc": "Skriv først inn et adminbrukernavn og et sterkt, sikkert passord. Denne informasjonen brukes til å logge inn i administrasjonspanelet.",
|
||||
"setupConfigDesc": "Skriv inn vert- og portinformasjon. Dette brukes til klientkonfigurasjonen når du setter opp WireGuard på enhetene deres.",
|
||||
"setupMigrationDesc": "Oppgi sikkerhetskopifilen hvis du vil migrere dataene dine fra forrige wg-easy-versjon til det nye oppsettet.",
|
||||
"upload": "Last opp",
|
||||
"migration": "Gjenopprett sikkerhetskopien:",
|
||||
"createAccount": "Opprett konto",
|
||||
"successful": "Oppsett vellykket",
|
||||
"hostDesc": "Offentlig vertsnavn klienter vil koble seg til",
|
||||
"portDesc": "Offentlig UDP-port klienter vil koble til og WireGuard vil lytte på"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "En oppdatering er tilgjengelig!",
|
||||
"update": "Oppdater"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Mørkt tema",
|
||||
"light": "Lyst tema",
|
||||
"system": "Systemtema"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Vis/skjul diagrammer",
|
||||
"donate": "Doner"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Logg inn",
|
||||
"rememberMe": "Husk meg",
|
||||
"rememberMeDesc": "Hold deg innlogget etter at nettleseren lukkes",
|
||||
"insecure": "Du kan ikke logge inn med en usikker tilkobling. Bruk HTTPS.",
|
||||
"2faRequired": "Tofaktorautentisering er påkrevd",
|
||||
"2faWrong": "Tofaktorautentisering er feil"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Det finnes ingen klienter ennå.",
|
||||
"newShort": "Ny",
|
||||
"sort": "Sorter",
|
||||
"create": "Opprett klient",
|
||||
"created": "Klient opprettet",
|
||||
"new": "Ny klient",
|
||||
"name": "Navn",
|
||||
"expireDate": "Utløpsdato",
|
||||
"expireDateDesc": "Datoen klienten blir deaktivert. Tomt for permanent",
|
||||
"delete": "Slett",
|
||||
"deleteClient": "Slett klient",
|
||||
"deleteDialog1": "Er du sikker på at du vil slette",
|
||||
"deleteDialog2": "Denne handlingen kan ikke angres.",
|
||||
"enabled": "Aktivert",
|
||||
"address": "Adresse",
|
||||
"serverAllowedIps": "Server tillatte IP-er",
|
||||
"otlDesc": "Generer kort engangslenke",
|
||||
"permanent": "Permanent",
|
||||
"createdOn": "Opprettet ",
|
||||
"lastSeen": "Sist sett ",
|
||||
"totalDownload": "Totalt nedlastet: ",
|
||||
"totalUpload": "Totalt opplastet: ",
|
||||
"newClient": "Ny klient",
|
||||
"disableClient": "Deaktiver klient",
|
||||
"enableClient": "Aktiver klient",
|
||||
"noPrivKey": "Denne klienten har ingen kjent privat nøkkel. Kan ikke opprette konfigurasjon.",
|
||||
"showQR": "Vis QR-kode",
|
||||
"downloadConfig": "Last ned konfigurasjon",
|
||||
"allowedIpsDesc": "Hvilke IP-er som rutes gjennom VPN (overstyrer global konfig)",
|
||||
"serverAllowedIpsDesc": "Hvilke IP-er serveren ruter til klienten",
|
||||
"mtuDesc": "Setter maksimal overføringsenhet (pakkestørrelse) for VPN-tunnelen",
|
||||
"persistentKeepaliveDesc": "Setter intervallet (i sekunder) for keepalive-pakker. 0 deaktiverer det",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks fungerer bare med wg-quick",
|
||||
"hooksLeaveEmpty": "Kun for wg-quick. Ellers la det være tomt",
|
||||
"dnsDesc": "DNS-server klienter vil bruke (overstyrer global konfig)",
|
||||
"notConnected": "Klient ikke tilkoblet",
|
||||
"endpoint": "Endepunkt",
|
||||
"endpointDesc": "IP-en til klienten som WireGuard-tilkoblingen etableres fra",
|
||||
"search": "Søk etter klienter...",
|
||||
"config": "Konfigurasjon",
|
||||
"viewConfig": "Vis konfigurasjon"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Endre",
|
||||
"cancel": "Avbryt",
|
||||
"create": "Opprett"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Vellykket",
|
||||
"saved": "Lagret",
|
||||
"error": "Feil"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Handlinger",
|
||||
"save": "Lagre",
|
||||
"revert": "Tilbakestill",
|
||||
"sectionGeneral": "Generelt",
|
||||
"sectionAdvanced": "Avansert",
|
||||
"noItems": "Ingen elementer",
|
||||
"nullNoItems": "Ingen elementer. Bruker global konfig",
|
||||
"add": "Legg til"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Øktutløp",
|
||||
"sessionTimeoutDesc": "Øktvarighet for Husk meg (sekunder)",
|
||||
"metrics": "Målinger",
|
||||
"metricsPassword": "Passord",
|
||||
"metricsPasswordDesc": "Bearer-passord for metrics-endepunktet (passord eller argon2-hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Rute for metrics i JSON-format",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Rute for Prometheus-målinger"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Tilkobling",
|
||||
"hostDesc": "Offentlig vertsnavn klienter vil koble til (ugyldiggjør konfig)",
|
||||
"portDesc": "Offentlig UDP-port klienter vil koble til (ugyldiggjør konfig, du vil sannsynligvis også endre Grensesnitt-port)",
|
||||
"allowedIpsDesc": "Tillatte IP-er klienter vil bruke (global konfig)",
|
||||
"dnsDesc": "DNS-server klienter vil bruke (global konfig)",
|
||||
"mtuDesc": "MTU klienter vil bruke (kun for nye klienter)",
|
||||
"persistentKeepaliveDesc": "Intervall i sekunder for å sende keepalives til serveren. 0 = deaktivert (kun for nye klienter)",
|
||||
"suggest": "Foreslå",
|
||||
"suggestDesc": "Velg en IP-adresse eller et vertsnavn for Vert-feltet"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR endret",
|
||||
"device": "Enhet",
|
||||
"deviceDesc": "Ethernet-enhet som WireGuard-trafikken skal videresendes gjennom",
|
||||
"mtuDesc": "MTU WireGuard vil bruke",
|
||||
"portDesc": "UDP-port WireGuard vil lytte på (du vil sannsynligvis også endre Konfig-port)",
|
||||
"changeCidr": "Endre CIDR",
|
||||
"restart": "Start grensesnitt på nytt",
|
||||
"restartDesc": "Start WireGuard-grensesnittet på nytt",
|
||||
"restartWarn": "Er du sikker på at du vil starte grensesnittet på nytt? Dette vil koble fra alle klienter.",
|
||||
"restartSuccess": "Grensesnitt startet på nytt"
|
||||
},
|
||||
"introText": "Velkommen til adminpanelet.\n\nHer kan du administrere de generelle innstillingene, konfigurasjonen, grensesnittinnstillingene og hooks.\n\nStart med å velge en av seksjonene i sidepanelet."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} er påkrevd",
|
||||
"validNumber": "{0} må være et gyldig tall",
|
||||
"validString": "{0} må være en gyldig streng",
|
||||
"validBoolean": "{0} må være en gyldig boolsk verdi",
|
||||
"validArray": "{0} må være en gyldig liste",
|
||||
"stringMin": "{0} må være minst {1} tegn",
|
||||
"numberMin": "{0} må være minst {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "Klient-ID",
|
||||
"name": "Navn",
|
||||
"expiresAt": "Utløper",
|
||||
"address4": "IPv4-adresse",
|
||||
"address6": "IPv6-adresse",
|
||||
"serverAllowedIps": "Server tillatte IP-er"
|
||||
},
|
||||
"user": {
|
||||
"username": "Brukernavn",
|
||||
"password": "Passord",
|
||||
"remember": "Husk",
|
||||
"name": "Navn",
|
||||
"email": "E-post",
|
||||
"emailInvalid": "E-post må være en gyldig e-postadresse",
|
||||
"passwordMatch": "Passord må være like",
|
||||
"totpEnable": "TOTP aktivert",
|
||||
"totpEnableTrue": "TOTP aktivert må være sant",
|
||||
"totpCode": "TOTP-kode"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Vert"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Øktutløp",
|
||||
"metricsEnabled": "Målinger",
|
||||
"metricsPassword": "Målingspassord"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Enhet",
|
||||
"cidrValid": "CIDR må være gyldig"
|
||||
},
|
||||
"otl": "Engangslenke",
|
||||
"stringMalformed": "Strengen er ugyldig",
|
||||
"body": "Innholdet må være et gyldig objekt",
|
||||
"hook": "Hook",
|
||||
"enabled": "Aktivert",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Vedvarende keepalive",
|
||||
"address": "IP-adresse",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Tillatte IP-er",
|
||||
"file": "Fil"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopiering støttes ikke",
|
||||
"copied": "Kopiert!",
|
||||
"failed": "Kopiering mislyktes",
|
||||
"copy": "Kopier"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Antall junk-pakker (Jc)",
|
||||
"jCDescription": "Antall junk-pakker som skal sendes (1-128, anbefalt: 4-12)",
|
||||
"jMinLabel": "Min. størrelse på junk-pakker (Jmin)",
|
||||
"jMinDescription": "Minimum størrelse på junk-pakker (0-1279*, anbefalt: 8, må være < Jmax)",
|
||||
"jMaxLabel": "Maks. størrelse på junk-pakker (Jmax)",
|
||||
"jMaxDescription": "Maksimal størrelse på junk-pakker (1-1280*, anbefalt: 80, må være > Jmin)",
|
||||
"s1Label": "Init-pakke junk-størrelse (S1)",
|
||||
"s1Description": "Init-pakke junk-størrelse (0-1132[1280* - 148 = 1132], anbefalt: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Svarpakke junk-størrelse (S2)",
|
||||
"s2Description": "Svarpakke junk-størrelse (0-1188[1280* - 92 = 1188], anbefalt: 15-150)",
|
||||
"s3Label": "Cookie-svarpakke junk-størrelse (S3)",
|
||||
"s3Description": "Cookie-svarpakke junk-størrelse",
|
||||
"s4Label": "Transportpakke junk-størrelse (S4)",
|
||||
"s4Description": "Transportpakke junk-størrelse",
|
||||
"i1Label": "Spesiell junk-pakke 1 (I1)",
|
||||
"i1Description": "Protokolllignende pakke i heksformat: <b 0x...>",
|
||||
"i2Label": "Spesiell junk-pakke 2 (I2)",
|
||||
"i2Description": "Protokolllignende pakke i heksformat: <b 0x...>",
|
||||
"i3Label": "Spesiell junk-pakke 3 (I3)",
|
||||
"i3Description": "Protokolllignende pakke i heksformat: <b 0x...>",
|
||||
"i4Label": "Spesiell junk-pakke 4 (I4)",
|
||||
"i4Description": "Protokolllignende pakke i heksformat: <b 0x...>",
|
||||
"i5Label": "Spesiell junk-pakke 5 (I5)",
|
||||
"i5Description": "Protokolllignende pakke i heksformat: <b 0x...>",
|
||||
"h1Label": "Init magisk header (H1)",
|
||||
"h1Description": "Init-pakke header-verdi (5-2147483647, må være unik fra H2-H4)",
|
||||
"h2Label": "Svar magisk header (H2)",
|
||||
"h2Description": "Svarpakke header-verdi (5-2147483647, må være unik fra H1, H3, H4)",
|
||||
"h3Label": "Cookie-svar magisk header (H3)",
|
||||
"h3Description": "Cookie-svarpakke header-verdi (5-2147483647, må være unik fra H1, H2, H4)",
|
||||
"h4Label": "Transport magisk header (H4)",
|
||||
"h4Description": "Transportpakke header-verdi (5-2147483647, må være unik fra H1-H3)",
|
||||
"mtuNote": "Verdier avhenger av MTU",
|
||||
"obfuscationParameters": "AmneziaWG obfuskasjonsparametere"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Account",
|
||||
"clients": "Cliënten",
|
||||
"admin": {
|
||||
"panel": "Admin-paneel",
|
||||
"general": "Algemeen",
|
||||
"config": "Config",
|
||||
"interface": "Interface",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "E-mail"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Huidig wachtwoord",
|
||||
"enable2fa": "Twee-factor-authenticatie inschakelen",
|
||||
"enable2faDesc": "Scan de QR-code met uw authenticator-app of voer de sleutel handmatig in.",
|
||||
"2faKey": "TOTP-sleutel",
|
||||
"2faCodeDesc": "Voer de code in van uw authenticator-app.",
|
||||
"disable2fa": "Twee-factor-authenticatie uitschakelen",
|
||||
"disable2faDesc": "Voer uw wachtwoord in om de twee-factor-authenticatie uit te schakelen."
|
||||
},
|
||||
"general": {
|
||||
"name": "Naam",
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"newPassword": "Nieuw wachtwoord",
|
||||
"updatePassword": "Wachtwoord bijwerken",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Toegestane IP's",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Aanhoudende verbinding",
|
||||
"logout": "Uitloggen",
|
||||
"continue": "Doorgaan",
|
||||
"host": "Host",
|
||||
"port": "Port",
|
||||
"yes": "Ja",
|
||||
"no": "Nee",
|
||||
"confirmPassword": "Wachtwoord bevestigen",
|
||||
"loading": "Laden...",
|
||||
"2fa": "Twee-factor-authenticatie uitschakelen",
|
||||
"2faCode": "TOTP-code"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Welkom bij uw eerste installatie van wg-easy",
|
||||
"welcomeDesc": "U hebt de gemakkelijkste manier gevonden om WireGuard op elke Linux-host te installeren en te beheren",
|
||||
"existingSetup": "Heeft u een bestaande installatie?",
|
||||
"createAdminDesc": "Voer eerst een beheerdersgebruikersnaam en een sterk veilig wachtwoord in. Deze gegevens worden gebruikt om in te loggen op uw beheerderspaneel.",
|
||||
"setupConfigDesc": "Voer alstublieft de host- en poortinformatie in. Dit wordt gebruikt voor de clientconfiguratie bij het instellen van WireGuard op hun apparaten.",
|
||||
"setupMigrationDesc": "Geef alstublieft het back-upbestand als u uw gegevens van uw vorige wg-easy-versie naar uw nieuwe installatie wilt overzetten.",
|
||||
"upload": "Uploaden",
|
||||
"migration": "Herstel de back-up:",
|
||||
"createAccount": "Account aanmaken",
|
||||
"successful": "Installatie succesvol",
|
||||
"hostDesc": "Publieke hostnaam waar clients verbinding mee maken",
|
||||
"portDesc": "Publieke UDP-poort waarop clients verbinding maken en waarop WireGuard luistert"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Er is een update beschikbaar!",
|
||||
"update": "Bijwerken"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Donker thema",
|
||||
"light": "Licht thema",
|
||||
"system": "Systeem-thema"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Grafieken tonen/verbergen",
|
||||
"donate": "Donatie"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Inloggen",
|
||||
"rememberMe": "Onthoud mij",
|
||||
"rememberMeDesc": "Ingelogd blijven na het sluiten van de browser",
|
||||
"insecure": "U kunt niet inloggen via een onveilige verbinding. Gebruik HTTPS.",
|
||||
"2faRequired": "Twee-factor-authenticatie is vereist",
|
||||
"2faWrong": "Twee-factor-authenticatiecode is fout"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Er zijn nog geen cliënten.",
|
||||
"newShort": "Nieuw",
|
||||
"sort": "Sortering",
|
||||
"create": "Cliënt aanmaken",
|
||||
"created": "Cliënt aangemaakt",
|
||||
"new": "Nieuwe cliënt",
|
||||
"name": "Naam",
|
||||
"expireDate": "Verloopdatum",
|
||||
"expireDateDesc": "Datum waarop de cliënt wordt uitgeschakeld. Laat leeg voor permanent.",
|
||||
"delete": "Verwijderen",
|
||||
"deleteClient": "Cliënt verwijderen",
|
||||
"deleteDialog1": "Weet u zeker dat u wilt verwijderen",
|
||||
"deleteDialog2": "Deze actie kan niet ongedaan worden gemaakt.",
|
||||
"enabled": "Ingeschakeld",
|
||||
"address": "Adres",
|
||||
"serverAllowedIps": "Toegestane IP's van de server",
|
||||
"otlDesc": "Korte eenmalige link genereren",
|
||||
"permanent": "Permanent",
|
||||
"createdOn": "Aangemaakt op ",
|
||||
"lastSeen": "Laatst gezien op ",
|
||||
"totalDownload": "Totaal gedownload: ",
|
||||
"totalUpload": "Totaal geüpload: ",
|
||||
"newClient": "Nieuwe cliënt",
|
||||
"disableClient": "Cliënt uitschakelen",
|
||||
"enableClient": "Cliënt inschakelen",
|
||||
"noPrivKey": "Deze cliënt heeft geen bekende privésleutel. Kan de configuratie niet aanmaken.",
|
||||
"showQR": "QR-code weergeven",
|
||||
"downloadConfig": "Configuratie downloaden",
|
||||
"allowedIpsDesc": "Welke IP's via de VPN worden geleid (overschrijft algemene instellingen)",
|
||||
"serverAllowedIpsDesc": "Naar welke IP's de server het cliëntverkeer zal routeren",
|
||||
"mtuDesc": "Stelt de maximale transmissie-eenheid (pakketgrootte) voor de VPN-tunnel in",
|
||||
"persistentKeepaliveDesc": "Stelt het interval (seconden) in voor keep-alive-pakketten. 0 schakelt dit uit",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks functioneren alleen met wg-quick",
|
||||
"hooksLeaveEmpty": "Alleen voor wg-quick. Anders leeg laten",
|
||||
"dnsDesc": "DNS-serverclients zullen gebruiken (overschrijft algemene instellingen)",
|
||||
"notConnected": "Cliënt niet verbonden",
|
||||
"endpoint": "Eindpunt",
|
||||
"endpointDesc": "IP van de cliënt vanaf welke de WireGuard-verbinding tot stand wordt gebracht",
|
||||
"search": "Cliënten zoeken...",
|
||||
"config": "Configuratie",
|
||||
"viewConfig": "Configuratie weergeven"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Wijzigen",
|
||||
"cancel": "Annuleren",
|
||||
"create": "Aanmaken"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Succes",
|
||||
"saved": "Opgeslagen",
|
||||
"error": "Fout"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Acties",
|
||||
"save": "Opslaan",
|
||||
"revert": "Terugzetten",
|
||||
"sectionGeneral": "Algemeen",
|
||||
"sectionAdvanced": "Geavanceerd",
|
||||
"noItems": "Geen items",
|
||||
"nullNoItems": "Geen items. Globale configuratie gebruiken",
|
||||
"add": "Toevoegen"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Sessie verlopen",
|
||||
"sessionTimeoutDesc": "Sessieduur voor Onthoud mij (sec.)",
|
||||
"metrics": "Metrics",
|
||||
"metricsPassword": "Wachtwoord",
|
||||
"metricsPasswordDesc": "Bearer-wachtwoord voor het metrics-eindpunt (wachtwoord of argon2-hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Route voor metrics in JSON-formaat",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Route voor Prometheus-metrics"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Verbinding",
|
||||
"hostDesc": "Publieke hostnaam waarmee cliënten verbinding maken (maakt configuratie ongedaan)",
|
||||
"portDesc": "Publieke UDP-poort waarmee clients verbinding maken (maakt configuratie ongedaan; u dient waarschijnlijk ook de interfacepoort te wijzigen)",
|
||||
"allowedIpsDesc": "Toegestane IP's die cliënten zullen gebruiken (algemene configuratie)",
|
||||
"dnsDesc": "DNS-server die cliënten zullen gebruiken (algemene configuratie)",
|
||||
"mtuDesc": "MTU die cliënten zullen gebruiken (alleen voor nieuwe cliënten)",
|
||||
"persistentKeepaliveDesc": "Interval in seconden om keepalives naar de server te sturen. 0 = uitgeschakeld (alleen voor nieuwe cliënten)",
|
||||
"suggest": "Voorstellen",
|
||||
"suggestDesc": "Kies een IP-adres of hostnaam voor het veld Host"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR gewijzigd",
|
||||
"device": "Apparaat",
|
||||
"deviceDesc": "Ethernet-apparaat waar het WireGuard-verkeer doorheen moet worden doorgestuurd",
|
||||
"mtuDesc": "MTU die WireGuard zal toepassen",
|
||||
"portDesc": "UDP-poort waarop WireGuard zal luisteren (u dient waarschijnlijk ook de Config-poort te wijzigen)",
|
||||
"changeCidr": "CIDR wijzigen",
|
||||
"restart": "Interface opnieuw starten",
|
||||
"restartDesc": "WireGuard-interface opnieuw starten",
|
||||
"restartWarn": "Weet u zeker dat u de interface wilt herstarten? Dit zal alle cliënten loskoppelen.",
|
||||
"restartSuccess": "Interface opnieuw gestart"
|
||||
},
|
||||
"introText": "Welkom bij het Admin-paneel.\n\nHier kunt u de algemene instellingen, de configuratie, de interface-instellingen en de hooks beheren.\n\nBegin met het kiezen van een van de secties in de zijbalk."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} is vereist",
|
||||
"validNumber": "{0} moet een geldig nummer zijn",
|
||||
"validString": "{0} moet een geldige tekenreeks zijn",
|
||||
"validBoolean": "{0} moet een geldige boolean zijn",
|
||||
"validArray": "{0} moet een geldige array zijn",
|
||||
"stringMin": "{0} moet minstens {1} teken bevatten",
|
||||
"numberMin": "{0} moet minstens {1} zijn"
|
||||
},
|
||||
"client": {
|
||||
"id": "Cliënt-ID",
|
||||
"name": "Naam",
|
||||
"expiresAt": "Verloopt op",
|
||||
"address4": "IPv4-adres",
|
||||
"address6": "IPv6-adres",
|
||||
"serverAllowedIps": "Toegestane IP's van de server"
|
||||
},
|
||||
"user": {
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"remember": "Onthouden",
|
||||
"name": "Naam",
|
||||
"email": "E-mail",
|
||||
"emailInvalid": "E-mail moet een geldig e-mailadres zijn",
|
||||
"passwordMatch": "Wachtwoorden moeten overeenkomen",
|
||||
"totpEnable": "TOTP inschakelen",
|
||||
"totpEnableTrue": "TOTP inschakelen moet waar zijn",
|
||||
"totpCode": "TOTP-code"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Host"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Sessie-verlooptijd",
|
||||
"metricsEnabled": "Metrics",
|
||||
"metricsPassword": "Metrics-wachtwoord"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Apparaat",
|
||||
"cidrValid": "CIDR moet geldig zijn"
|
||||
},
|
||||
"otl": "Eenmalige link",
|
||||
"stringMalformed": "Tekenreeks is beschadigd",
|
||||
"body": "Body moet een geldig object bevatten",
|
||||
"hook": "Hook",
|
||||
"enabled": "Ingeschakeld",
|
||||
"mtu": "MTU",
|
||||
"port": "Poort",
|
||||
"persistentKeepalive": "Aanhoudende verbinding",
|
||||
"address": "IP-adres",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Toegestane IP's",
|
||||
"file": "Bestand"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "Pre-Up",
|
||||
"postUp": "Post-Up",
|
||||
"preDown": "Pre-Down",
|
||||
"postDown": "Post-Down"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopiëren wordt niet ondersteund",
|
||||
"copied": "Gekopieerd!",
|
||||
"failed": "Kopiëren is mislukt",
|
||||
"copy": "Kopiëren"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Junk packet count (Jc)",
|
||||
"jCDescription": "Aantal te verzenden junk packets (1-128, aanbevolen: 4-12)",
|
||||
"jMinLabel": "Junk packet min size (Jmin)",
|
||||
"jMinDescription": "Minimale grootte van junk packets (0-1279*, aanbevolen: 8, moet zijn < Jmax)",
|
||||
"jMaxLabel": "Junk packet max size (Jmax)",
|
||||
"jMaxDescription": "Maximale grootte van junk packets (1-1280*, aanbevolen: 80, moet zijn > Jmin)",
|
||||
"s1Label": "Init packet junk size (S1)",
|
||||
"s1Description": "Grootte Init packet junk (0-1132[1280* - 148 = 1132], aanbevolen: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Response packet junk size (S2)",
|
||||
"s2Description": "Grootte Response packet junk (0-1188[1280* - 92 = 1188], aanbevolen: 15-150)",
|
||||
"s3Label": "Cookie reply packet junk size (S3)",
|
||||
"s3Description": "Grootte Cookie reply packet junk",
|
||||
"s4Label": "Transport packet junk size (S4)",
|
||||
"s4Description": "Grootte Transport packet junk",
|
||||
"i1Label": "Special junk packet 1 (I1)",
|
||||
"i1Description": "Protocol mimic packet in hex formaat: <b 0x...>",
|
||||
"i2Label": "Special junk packet 2 (I2)",
|
||||
"i2Description": "Protocol mimic packet in hex formaat: <b 0x...>",
|
||||
"i3Label": "Special junk packet 3 (I3)",
|
||||
"i3Description": "Protocol mimic packet in hex formaat: <b 0x...>",
|
||||
"i4Label": "Special junk packet 4 (I4)",
|
||||
"i4Description": "Protocol mimic packet in hex formaat: <b 0x...>",
|
||||
"i5Label": "Special junk packet 5 (I5)",
|
||||
"i5Description": "Protocol mimic packet in hex formaat: <b 0x...>",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Waarde Init packet header (5-2147483647, moet uniek zijn t.o.v. H2-H4)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Waarde Response packet header (5-2147483647, moet uniek zijn t.o.v. H1, H3, H4)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Waarde Cookie reply packet header (5-2147483647, moet uniek zijn t.o.v. H1, H2, H4)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Waarde Transport packet header (5-2147483647, moet uniek zijn t.o.v. H1-H3)",
|
||||
"mtuNote": "Waarden zijn afhankelijk van de MTU",
|
||||
"obfuscationParameters": "AmneziaWG Obfuscation Parameters"
|
||||
}
|
||||
}
|
||||
+117
-71
@@ -3,8 +3,8 @@
|
||||
"me": "Аккаунт",
|
||||
"clients": "Клиенты",
|
||||
"admin": {
|
||||
"panel": "Админ панель",
|
||||
"general": "Общие",
|
||||
"panel": "Админ-панель",
|
||||
"general": "Общие настройки",
|
||||
"config": "Конфигурация",
|
||||
"interface": "Интерфейс",
|
||||
"hooks": "Хуки"
|
||||
@@ -16,11 +16,11 @@
|
||||
"me": {
|
||||
"currentPassword": "Текущий пароль",
|
||||
"enable2fa": "Включить двухфакторную аутентификацию",
|
||||
"enable2faDesc": "Отсканируйте QR-код приложением-аутентификатором или введите ключ вручную.",
|
||||
"2faKey": "TOTP-ключ",
|
||||
"2faCodeDesc": "Введите код из приложения-аутентификатора.",
|
||||
"enable2faDesc": "Отсканируйте QR‑код с помощью приложения‑аутентификатора или введите ключ вручную.",
|
||||
"2faKey": "Ключ TOTP",
|
||||
"2faCodeDesc": "Введите код из приложения‑аутентификатора.",
|
||||
"disable2fa": "Отключить двухфакторную аутентификацию",
|
||||
"disable2faDesc": "Введите пароль, чтобы отключить двухфакторную аутентификацию"
|
||||
"disable2faDesc": "Введите пароль, чтобы отключить двухфакторную аутентификацию."
|
||||
},
|
||||
"general": {
|
||||
"name": "Имя",
|
||||
@@ -29,9 +29,9 @@
|
||||
"newPassword": "Новый пароль",
|
||||
"updatePassword": "Обновить пароль",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Разрешённые IP",
|
||||
"allowedIps": "Разрешённые IP‑адреса",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Постоянный keepalive",
|
||||
"persistentKeepalive": "Постоянное поддержание соединения",
|
||||
"logout": "Выйти",
|
||||
"continue": "Продолжить",
|
||||
"host": "Хост",
|
||||
@@ -41,21 +41,21 @@
|
||||
"confirmPassword": "Подтвердите пароль",
|
||||
"loading": "Загрузка...",
|
||||
"2fa": "Двухфакторная аутентификация",
|
||||
"2faCode": "TOTP‑код"
|
||||
"2faCode": "Код TOTP"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Добро пожаловать в первичную настройку wg-easy",
|
||||
"welcomeDesc": "Вы нашли самый простой способ установить и управлять WireGuard на любом Linux-хосте",
|
||||
"existingSetup": "У вас уже есть существующая установка?",
|
||||
"createAdminDesc": "Сначала введите имя администратора и надёжный пароль. Эти данные понадобятся для входа в панель управления",
|
||||
"setupConfigDesc": "Введите информацию о хосте и порте. Она будет использоваться в конфигурации клиента при установке WireGuard на устройствах",
|
||||
"setupMigrationDesc": "Укажите файл резервной копии, если хотите перенести данные из предыдущей версии wg-easy",
|
||||
"welcomeDesc": "Вы нашли самый простой способ установить и управлять WireGuard на любом Linux‑хосте",
|
||||
"existingSetup": "У вас уже есть существующая настройка?",
|
||||
"createAdminDesc": "Сначала введите имя администратора и надёжный пароль. Эти данные будут использоваться для входа в Админ-панель.",
|
||||
"setupConfigDesc": "Введите данные хоста и порта. Они будут использоваться для настройки клиента при установке WireGuard на устройствах.",
|
||||
"setupMigrationDesc": "Укажите файл резервной копии, если хотите перенести данные из предыдущей версии wg-easy.",
|
||||
"upload": "Загрузить",
|
||||
"migration": "Восстановить из резервной копии:",
|
||||
"createAccount": "Создать аккаунт",
|
||||
"successful": "Настройка успешна",
|
||||
"successful": "Настройка завершена успешно",
|
||||
"hostDesc": "Публичное имя хоста, к которому будут подключаться клиенты",
|
||||
"portDesc": "Публичный UDP‑порт для подключения клиентов и прослушивания WireGuard"
|
||||
"portDesc": "Публичный UDP‑порт, к которому будут подключаться клиенты и на котором будет слушать WireGuard"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Доступно обновление!",
|
||||
@@ -68,7 +68,7 @@
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Показать/скрыть графики",
|
||||
"donate": "Пожертвовать"
|
||||
"donate": "Поддержать"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Войти",
|
||||
@@ -87,18 +87,19 @@
|
||||
"new": "Новый клиент",
|
||||
"name": "Имя",
|
||||
"expireDate": "Дата отключения",
|
||||
"expireDateDesc": "Дата, когда клиент будет отключён. Пусто — бессрочно",
|
||||
"expireDateDesc": "Дата, когда клиент будет отключён. Оставьте пустым для бессрочного доступа",
|
||||
"delete": "Удалить",
|
||||
"deleteClient": "Удалить клиента",
|
||||
"deleteDialog1": "Вы уверены, что хотите удалить",
|
||||
"deleteDialog2": "Это действие необратимо.",
|
||||
"enabled": "Включен",
|
||||
"deleteDialog2": "Это действие нельзя отменить.",
|
||||
"enabled": "Включён",
|
||||
"address": "Адрес",
|
||||
"serverAllowedIps": "Разрешённые IP сервера",
|
||||
"otlDesc": "Сгенерировать одноразовую короткую ссылку",
|
||||
"permanent": "Постоянный",
|
||||
"serverAllowedIps": "Разрешённые IP‑адреса сервера",
|
||||
"otlDesc": "Сгенерировать короткую одноразовую ссылку",
|
||||
"permanent": "Бессрочный",
|
||||
"createdOn": "Создан ",
|
||||
"lastSeen": "Последнее подключение ",
|
||||
"totalDownload": "Всего загружено: ",
|
||||
"totalDownload": "Всего скачано: ",
|
||||
"totalUpload": "Всего отправлено: ",
|
||||
"newClient": "Новый клиент",
|
||||
"disableClient": "Отключить клиента",
|
||||
@@ -106,25 +107,28 @@
|
||||
"noPrivKey": "У этого клиента нет приватного ключа. Невозможно создать конфигурацию.",
|
||||
"showQR": "Показать QR‑код",
|
||||
"downloadConfig": "Скачать конфигурацию",
|
||||
"allowedIpsDesc": "Какие IP будут маршрутизироваться через VPN (перезаписывает общую конфигурацию)",
|
||||
"serverAllowedIpsDesc": "Какие IP сервер будет отправлять клиенту",
|
||||
"mtuDesc": "Максимальный размер пакета для VPN‑туннеля",
|
||||
"persistentKeepaliveDesc": "Интервал пакетов для поддержания соединения (в секундах). 0 — отключено.",
|
||||
"allowedIpsDesc": "Какие IP‑адреса будут маршрутизироваться через VPN (переопределяет глобальную конфигурацию)",
|
||||
"serverAllowedIpsDesc": "Какие IP‑адреса сервер будет отправлять клиенту",
|
||||
"mtuDesc": "Максимальный размер пакета (MTU) для VPN‑туннеля",
|
||||
"persistentKeepaliveDesc": "Устанавливает интервал (в секундах) для пакетов поддержания соединения. 0 — отключить",
|
||||
"hooks": "Хуки",
|
||||
"hooksDescription": "Хуки работают только с wg-quick",
|
||||
"hooksLeaveEmpty": "Только для wg-quick. Иначе оставьте пустым",
|
||||
"dnsDesc": "DNS‑сервер, который будут использовать клиенты (перезаписывает общую конфигурацию)",
|
||||
"hooksDescription": "Хуки работают только с wg‑quick",
|
||||
"hooksLeaveEmpty": "Только для wg‑quick. В остальных случаях оставьте пустым",
|
||||
"dnsDesc": "DNS‑сервер, который будут использовать клиенты (переопределяет глобальную конфигурацию)",
|
||||
"notConnected": "Клиент не подключен",
|
||||
"endpoint": "Конечная точка",
|
||||
"endpointDesc": "IP-адрес клиента, с которого установлено соединение WireGuard"
|
||||
"endpoint": "Точка подключения",
|
||||
"endpointDesc": "IP‑адрес клиента, с которого установлено соединение WireGuard",
|
||||
"search": "Поиск клиентов...",
|
||||
"config": "Конфигурация",
|
||||
"viewConfig": "Просмотреть конфигурацию"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Изменить",
|
||||
"cancel": "Отмена",
|
||||
"cancel": "Отменить",
|
||||
"create": "Создать"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Успех",
|
||||
"success": "Успешно",
|
||||
"saved": "Сохранено",
|
||||
"error": "Ошибка"
|
||||
},
|
||||
@@ -133,18 +137,18 @@
|
||||
"save": "Сохранить",
|
||||
"revert": "Отменить",
|
||||
"sectionGeneral": "Общие",
|
||||
"sectionAdvanced": "Дополнительно",
|
||||
"sectionAdvanced": "Расширенные",
|
||||
"noItems": "Нет элементов",
|
||||
"nullNoItems": "Нет элементов. Используется глобальная конфигурация",
|
||||
"add": "Добавить"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Тайм-аут сессии",
|
||||
"sessionTimeoutDesc": "Длительность сеанса для \"Запомнить меня\" (секунды)",
|
||||
"sessionTimeout": "Время жизни сессии",
|
||||
"sessionTimeoutDesc": "Длительность сессии для «Запомнить меня» (в секундах)",
|
||||
"metrics": "Метрики",
|
||||
"metricsPassword": "Пароль",
|
||||
"metricsPasswordDesc": "Пароль Bearer для эндпоинта метрик (пароль или хеш argon2)",
|
||||
"metricsPasswordDesc": "Пароль Bearer для конечной точки метрик (пароль или хэш argon2)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Путь для метрик в формате JSON",
|
||||
"prometheus": "Prometheus",
|
||||
@@ -152,83 +156,83 @@
|
||||
},
|
||||
"config": {
|
||||
"connection": "Соединение",
|
||||
"hostDesc": "Публичное имя хоста для подключения клиентов (сбросит конфигурацию)",
|
||||
"portDesc": "Публичный UDP‑порт для подключения клиентов (также стоит изменить порт интерфейса)",
|
||||
"allowedIpsDesc": "Разрешённые IP для клиентов (общая конфигурация)",
|
||||
"dnsDesc": "DNS‑сервер для клиентов (общая конфигурация)",
|
||||
"hostDesc": "Публичное имя хоста для подключения клиентов(обнуляет конфигурацию)",
|
||||
"portDesc": "Публичный UDP‑порт для подключения клиентов (также рекомендуется изменить порт интерфейса)",
|
||||
"allowedIpsDesc": "Разрешённые IP‑адреса для клиентов(глобальная конфигурация)",
|
||||
"dnsDesc": "DNS‑сервер для клиентов (глобальная конфигурация)",
|
||||
"mtuDesc": "MTU для клиентов (только для новых)",
|
||||
"persistentKeepaliveDesc": "Интервал отправки keepalive на сервер (секунды). 0 = отключено (только для новых)",
|
||||
"suggest": "Определить",
|
||||
"suggestDesc": "Выберите IP‑адрес или имя хоста для поля Host"
|
||||
"persistentKeepaliveDesc": "Интервал в секундах для отправки пакетов поддержания соединения на сервер. 0 = отключено (только для новых клиентов)",
|
||||
"suggest": "Предложить",
|
||||
"suggestDesc": "Выберите IP‑адрес или имя хоста для поля «Хост»"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR изменён",
|
||||
"device": "Устройство",
|
||||
"deviceDesc": "Сетевое устройство, через которое должен проходить трафик WireGuard",
|
||||
"mtuDesc": "MTU, который использует WireGuard",
|
||||
"portDesc": "UDP‑порт, на котором WireGuard будет слушать (возможно, нужно изменить и порт конфигурации)",
|
||||
"deviceDesc": "Сетевое устройство Ethernet, через которое должен проходить трафик WireGuard",
|
||||
"mtuDesc": "MTU, который будет использовать WireGuard",
|
||||
"portDesc": "UDP‑порт, на котором будет слушать WireGuard (возможно, нужно также изменить порт конфигурации)",
|
||||
"changeCidr": "Изменить CIDR",
|
||||
"restart": "Перезапустить интерфейс",
|
||||
"restartDesc": "Перезапустить интерфейс WireGuard",
|
||||
"restartWarn": "Вы уверены, что хотите перезапустить интерфейс? Все клиенты будут отключены.",
|
||||
"restartWarn": "Вы уверены, что хотите перезапустить интерфейс? Это приведёт к отключению всех клиентов.",
|
||||
"restartSuccess": "Интерфейс перезапущен"
|
||||
},
|
||||
"introText": "Добро пожаловать в панель администратора.\n\nЗдесь вы можете управлять общими настройками, конфигурацией, параметрами интерфейса и хуками.\n\nНачните с выбора раздела в боковой панели."
|
||||
"introText": "Добро пожаловать в панель администратора.\n\nЗдесь вы можете управлять общими настройками, конфигурацией, настройками интерфейса и хуками.\n\nНачните с выбора одного из разделов на боковой панели."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} обязательное поле",
|
||||
"validNumber": "{0} должен быть числом",
|
||||
"validString": "{0} должна быть строкой",
|
||||
"validBoolean": "{0} должен быть булевым значением",
|
||||
"validArray": "{0} должен быть массивом",
|
||||
"stringMin": "{0} должен содержать не менее {1} символов",
|
||||
"numberMin": "{0} должен быть не меньше {1}"
|
||||
"required": "{0} обязательно для заполнения",
|
||||
"validNumber": "{0} должно быть числом",
|
||||
"validString": "{0} должно быть строкой",
|
||||
"validBoolean": "{0} должно быть логическим значением",
|
||||
"validArray": "{0} должно быть массивом",
|
||||
"stringMin": "{0} должно содержать не менее {1} символа",
|
||||
"numberMin": "{0} должно быть не менее {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID клиента",
|
||||
"name": "Имя",
|
||||
"expiresAt": "Действителен до",
|
||||
"address4": "IPv4 адрес",
|
||||
"address6": "IPv6 адрес",
|
||||
"serverAllowedIps": "Разрешённые IP сервера"
|
||||
"expiresAt": "Дата окончания действия",
|
||||
"address4": "IPv4‑адрес",
|
||||
"address6": "IPv6‑адрес",
|
||||
"serverAllowedIps": "Разрешённые IP‑адреса сервера"
|
||||
},
|
||||
"user": {
|
||||
"username": "Имя пользователя",
|
||||
"password": "Пароль",
|
||||
"remember": "Запомнить",
|
||||
"name": "Имя",
|
||||
"email": "Email",
|
||||
"emailInvalid": "Email должен быть валидным",
|
||||
"email": "Электронная почта",
|
||||
"emailInvalid": "Адрес электронной почты должен быть корректным",
|
||||
"passwordMatch": "Пароли должны совпадать",
|
||||
"totpEnable": "Включить TOTP",
|
||||
"totpEnableTrue": "Необходимо включить TOTP",
|
||||
"totpCode": "TOTP‑код"
|
||||
"totpEnableTrue": "TOTP должен быть включён",
|
||||
"totpCode": "Код TOTP"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Хост"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Тайм-аут сессии",
|
||||
"sessionTimeout": "Время жизни сессии",
|
||||
"metricsEnabled": "Метрики",
|
||||
"metricsPassword": "Пароль для метрик"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Устройство",
|
||||
"cidrValid": "CIDR должен быть валидным"
|
||||
"cidrValid": "CIDR должен быть корректным"
|
||||
},
|
||||
"otl": "Одноразовая ссылка",
|
||||
"stringMalformed": "Строка имеет неверный формат",
|
||||
"body": "Тело должно быть объектом",
|
||||
"body": "Тело должно быть корректным объектом",
|
||||
"hook": "Хук",
|
||||
"enabled": "Включено",
|
||||
"mtu": "MTU",
|
||||
"port": "Порт",
|
||||
"persistentKeepalive": "Поддерживать соединение",
|
||||
"persistentKeepalive": "Постоянное поддержание соединения",
|
||||
"address": "IP‑адрес",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Разрешённые IP",
|
||||
"allowedIps": "Разрешённые IP‑адреса",
|
||||
"file": "Файл"
|
||||
},
|
||||
"hooks": {
|
||||
@@ -236,5 +240,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Копирование не поддерживается",
|
||||
"copied": "Скопировано!",
|
||||
"failed": "Ошибка копирования",
|
||||
"copy": "Копировать"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Количество мусорных пакетов (Jc)",
|
||||
"jCDescription": "Число мусорных пакетов для отправки (1-128, рекомендуется: 4-12)",
|
||||
"jMinLabel": "Минимальный размер мусорных пакетов (Jmin)",
|
||||
"jMinDescription": "Минимальный размер мусорных пакетов (0-1279*, рекомендуется: 8, должен быть < Jmax)",
|
||||
"jMaxLabel": "Максимальный размер мусорных пакетов (Jmax)",
|
||||
"jMaxDescription": "Максимальный размер мусорных пакетов (1-1280*, рекомендуется: 80, должен быть > Jmin)",
|
||||
"s1Label": "Размер мусорных данных в init-пакете (S1)",
|
||||
"s1Description": "Размер мусорных данных в init-пакете (0-1132[1280* - 148 = 1132], рекомендуется: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Размер мусорных данных в ответном пакете (S2)",
|
||||
"s2Description": "Размер мусорных данных в ответном пакете (0-1188[1280* - 92 = 1188], рекомендуется: 15-150)",
|
||||
"s3Label": "Размер мусорных данных в cookie-reply пакете (S3)",
|
||||
"s3Description": "Размер мусорных данных в cookie-reply пакете",
|
||||
"s4Label": "Размер мусорных данных в транспортном пакете (S4)",
|
||||
"s4Description": "Размер мусорных данных в транспортном пакете",
|
||||
"i1Label": "Специальный мусорный пакет 1 (I1)",
|
||||
"i1Description": "Пакет имитации протокола в hex формате: <b 0x...>",
|
||||
"i2Label": "Специальный мусорный пакет 2 (I2)",
|
||||
"i2Description": "Пакет имитации протокола в hex формате: <b 0x...>",
|
||||
"i3Label": "Специальный мусорный пакет 3 (I3)",
|
||||
"i3Description": "Пакет имитации протокола в hex формате: <b 0x...>",
|
||||
"i4Label": "Специальный мусорный пакет 4 (I4)",
|
||||
"i4Description": "Пакет имитации протокола в hex формате: <b 0x...>",
|
||||
"i5Label": "Специальный мусорный пакет 5 (I5)",
|
||||
"i5Description": "Пакет имитации протокола в hex формате: <b 0x...>",
|
||||
"h1Label": "Init magic заголовок (H1)",
|
||||
"h1Description": "Значение заголовка init-пакета (5-2147483647, должно отличаться от H2-H4)",
|
||||
"h2Label": "Response magic заголовок (H2)",
|
||||
"h2Description": "Значение заголовка ответного пакета (5-2147483647, должно отличаться от H1, H3, H4)",
|
||||
"h3Label": "Cookie reply magic заголовок (H3)",
|
||||
"h3Description": "Значение заголовка cookie-reply пакета (5-2147483647, должно отличаться от H1, H2, H4)",
|
||||
"h4Label": "Transport magic заголовок (H4)",
|
||||
"h4Description": "Значение заголовка транспортного пакета (5-2147483647, должно отличаться от H1-H3)",
|
||||
"mtuNote": "Значения зависят от MTU",
|
||||
"obfuscationParameters": "Параметры обфускации AmneziaWG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
"name": "Ім'я",
|
||||
"expireDate": "Термін дії",
|
||||
"expireDateDesc": "Дата, коли клієнт буде відключений. Порожнє для постійного користування",
|
||||
"delete": "Видалити",
|
||||
"deleteClient": "Видалити клієнта",
|
||||
"deleteDialog1": "Ви впевнені, що бажаєте видалити",
|
||||
"deleteDialog2": "Цю дію неможливо скасувати.",
|
||||
@@ -116,7 +117,10 @@
|
||||
"dnsDesc": "DNS сервер, який використовуватимуть клієнти (перевизначає глобальну конфігурацію)",
|
||||
"notConnected": "Клієнт не підключений",
|
||||
"endpoint": "Кінцева точка",
|
||||
"endpointDesc": "IP-адреса клієнта, з якої встановлюється з’єднання WireGuard"
|
||||
"endpointDesc": "IP-адреса клієнта, з якої встановлюється з’єднання WireGuard",
|
||||
"search": "Пошук клієнтів...",
|
||||
"config": "Конфігурація",
|
||||
"viewConfig": "Переглянути конфігурацію"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Змінити",
|
||||
@@ -236,5 +240,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Копіювання не підтримується",
|
||||
"copied": "Скопійовано!",
|
||||
"failed": "Не вдалося скопіювати",
|
||||
"copy": "Копіювати"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Кількість сміттєвих пакетів (Jc)",
|
||||
"jCDescription": "Кількість сміттєвих пакетів для відправки (1–128, рекомендовано: 4–12)",
|
||||
"jMinLabel": "Мінімальний розмір сміттєвого пакета (Jmin)",
|
||||
"jMinDescription": "Мінімальний розмір сміттєвих пакетів (0–1279*, рекомендовано: 8, має бути < Jmax)",
|
||||
"jMaxLabel": "Максимальний розмір сміттєвого пакета (Jmax)",
|
||||
"jMaxDescription": "Максимальний розмір сміттєвих пакетів (1–1280*, рекомендовано: 80, має бути > Jmin)",
|
||||
"s1Label": "Розмір сміттєвих даних у початковому пакеті (S1)",
|
||||
"s1Description": "Розмір сміттєвих даних у початковому пакеті (0–1132 [1280* - 148 = 1132], рекомендовано: 15–150, S1+56 ≠ S2)",
|
||||
"s2Label": "Розмір сміттєвих даних у пакеті відповіді (S2)",
|
||||
"s2Description": "Розмір сміттєвих даних у пакеті відповіді (0–1188 [1280* - 92 = 1188], рекомендовано: 15–150)",
|
||||
"s3Label": "Розмір сміттєвих даних у пакеті «cookie reply» (S3)",
|
||||
"s3Description": "Розмір сміттєвих даних у пакеті «cookie reply»",
|
||||
"s4Label": "Розмір сміттєвих даних у транспортному пакеті (S4)",
|
||||
"s4Description": "Розмір сміттєвих даних у транспортному пакеті",
|
||||
"i1Label": "Спеціальний сміттєвий пакет 1 (I1)",
|
||||
"i1Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"i2Label": "Спеціальний сміттєвий пакет 2 (I2)",
|
||||
"i2Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"i3Label": "Спеціальний сміттєвий пакет 3 (I3)",
|
||||
"i3Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"i4Label": "Спеціальний сміттєвий пакет 4 (I4)",
|
||||
"i4Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"i5Label": "Спеціальний сміттєвий пакет 5 (I5)",
|
||||
"i5Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"h1Label": "Початковий магічний заголовок (H1)",
|
||||
"h1Description": "Значення заголовка початкового пакета (5–2147483647, має бути унікальним від H2–H4)",
|
||||
"h2Label": "Магічний заголовок відповіді (H2)",
|
||||
"h2Description": "Значення заголовка пакета відповіді (5–2147483647, має бути унікальним від H1, H3, H4)",
|
||||
"h3Label": "Магічний заголовок «cookie reply» (H3)",
|
||||
"h3Description": "Значення заголовка пакета «cookie reply» (5–2147483647, має бути унікальним від H1, H2, H4)",
|
||||
"h4Label": "Магічний заголовок транспортного пакета (H4)",
|
||||
"h4Description": "Значення заголовка транспортного пакета (5–2147483647, має бути унікальним від H1–H3)",
|
||||
"mtuNote": "Значення залежать від MTU",
|
||||
"obfuscationParameters": "Параметри обфускації AmneziaWG"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +88,9 @@
|
||||
"name": "客户端名称",
|
||||
"expireDate": "过期日期",
|
||||
"expireDateDesc": "客户端将被自动禁用的日期。留空表示永久有效",
|
||||
"delete": "删除客户端",
|
||||
"deleteClient": "删除客户端",
|
||||
"deleteDialog1": "您确定要删除此客户端吗?",
|
||||
"deleteDialog1": "您确定要删除客户端",
|
||||
"deleteDialog2": "此操作无法撤销。",
|
||||
"enabled": "已启用",
|
||||
"address": "IP地址",
|
||||
@@ -113,7 +114,13 @@
|
||||
"hooks": "钩子脚本",
|
||||
"hooksDescription": "钩子脚本仅在使用wg-quick时有效",
|
||||
"hooksLeaveEmpty": "如果不使用wg-quick,请留空此字段",
|
||||
"search": "搜索客户端..."
|
||||
"dnsDesc": "客户端将使用的 DNS 服务器(将覆盖全局配置)",
|
||||
"notConnected": "客户端未连接",
|
||||
"endpoint": "端点",
|
||||
"endpointDesc": "建立 WireGuard 连接时客户端的 IP 地址",
|
||||
"search": "搜索客户端...",
|
||||
"config": "配置",
|
||||
"viewConfig": "查看配置文本"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "确认修改",
|
||||
@@ -233,5 +240,47 @@
|
||||
"postUp": "启动后脚本",
|
||||
"preDown": "停止前脚本",
|
||||
"postDown": "停止后脚本"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "不支持复制",
|
||||
"copied": "已复制!",
|
||||
"failed": "复制失败",
|
||||
"copy": "复制"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "垃圾数据包计数(Jc)",
|
||||
"jCDescription": "发送的垃圾数据包数量(范围:1-128,推荐值:4-12)",
|
||||
"jMinLabel": "垃圾数据包最小尺寸(Jmin)",
|
||||
"jMinDescription": "垃圾数据包的最小尺寸(范围:0-1279*,推荐值:8,必须小于 Jmax)",
|
||||
"jMaxLabel": "垃圾数据包最大尺寸(Jmax)",
|
||||
"jMaxDescription": "垃圾数据包的最大尺寸(范围:1-1280*,推荐值:80,必须大于 Jmin)",
|
||||
"s1Label": "初始数据包垃圾数据大小(S1)",
|
||||
"s1Description": "初始数据包中垃圾数据的大小(范围:0-1132[1280* - 148 = 1132],推荐值:15-150,S1+56 ≠ S2)",
|
||||
"s2Label": "响应数据包垃圾数据大小(S2)",
|
||||
"s2Description": "响应数据包中垃圾数据的大小(范围:0-1188[1280* - 92 = 1188],推荐值:15-150)",
|
||||
"s3Label": "Cookie 回复数据包垃圾数据大小(S3)",
|
||||
"s3Description": "Cookie 回复数据包中垃圾数据的大小",
|
||||
"s4Label": "传输数据包垃圾数据大小(S4)",
|
||||
"s4Description": "传输数据包中垃圾数据的大小",
|
||||
"i1Label": "特殊垃圾数据包 1(I1)",
|
||||
"i1Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"i2Label": "特殊垃圾数据包 2(I2)",
|
||||
"i2Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"i3Label": "特殊垃圾数据包 3(I3)",
|
||||
"i3Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"i4Label": "特殊垃圾数据包 4(I4)",
|
||||
"i4Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"i5Label": "特殊垃圾数据包 5(I5)",
|
||||
"i5Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"h1Label": "初始数据包魔术头部(H1)",
|
||||
"h1Description": "初始数据包头部值(范围:5-2147483647,必须与 H2-H4 不同)",
|
||||
"h2Label": "响应数据包魔术头部(H2)",
|
||||
"h2Description": "响应数据包头部值(范围:5-2147483647,必须与 H1、H3、H4 不同)",
|
||||
"h3Label": "Cookie 回复数据包魔术头部(H3)",
|
||||
"h3Description": "Cookie 回复数据包头部值(范围:5-2147483647,必须与 H1、H2、H4 不同)",
|
||||
"h4Label": "传输数据包魔术头部(H4)",
|
||||
"h4Description": "传输数据包头部值(范围:5-2147483647,必须与 H1-H3 不同)",
|
||||
"mtuNote": "具体数值取决于 MTU(最大传输单元)",
|
||||
"obfuscationParameters": "AmneziaWG 混淆参数"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "帳戶",
|
||||
"clients": "用戶端",
|
||||
"admin": {
|
||||
"panel": "管理面板",
|
||||
"general": "一般設定",
|
||||
"config": "組態設定",
|
||||
"interface": "介面設定",
|
||||
"hooks": "Hook 設定"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "電子郵件"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "目前密碼",
|
||||
"enable2fa": "啟用兩步驟驗證",
|
||||
"enable2faDesc": "請使用您的驗證碼應用程式掃描 QR Code,或手動輸入金鑰。",
|
||||
"2faKey": "TOTP 金鑰",
|
||||
"2faCodeDesc": "請輸入驗證碼應用程式提供的驗證碼。",
|
||||
"disable2fa": "停用兩步驟驗證",
|
||||
"disable2faDesc": "請輸入您的密碼以停用兩步驟驗證。"
|
||||
},
|
||||
"general": {
|
||||
"name": "名稱",
|
||||
"username": "使用者名稱",
|
||||
"password": "密碼",
|
||||
"newPassword": "新密碼",
|
||||
"updatePassword": "更新密碼",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "允許的 IP",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "保持連線",
|
||||
"logout": "登出",
|
||||
"continue": "繼續",
|
||||
"host": "主機",
|
||||
"port": "連接埠",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"confirmPassword": "確認密碼",
|
||||
"loading": "正在載入...",
|
||||
"2fa": "兩步驟驗證",
|
||||
"2faCode": "TOTP 驗證碼"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "歡迎首次設定您的 wg-easy",
|
||||
"welcomeDesc": "這是您在任何 Linux 主機上安裝與管理 WireGuard 最簡單的方式",
|
||||
"existingSetup": "您已有現存的設定了嗎?",
|
||||
"createAdminDesc": "請先輸入管理員使用者名稱與高強度密碼。此資訊將用於登入管理面板。",
|
||||
"setupConfigDesc": "請輸入主機與連接埠資訊。此資訊將用於設定用戶端的 WireGuard 連線。",
|
||||
"setupMigrationDesc": "若要從先前的 wg-easy 版本移轉資料,請提供備份檔案。",
|
||||
"upload": "上傳",
|
||||
"migration": "還原備份:",
|
||||
"createAccount": "建立帳戶",
|
||||
"successful": "設定成功",
|
||||
"hostDesc": "用戶端將連線的公開主機名稱",
|
||||
"portDesc": "用戶端將連線的公開 UDP 連接埠,且 WireGuard 會在此監聽"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "已有更新可供使用!",
|
||||
"update": "更新"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "深色佈景主題",
|
||||
"light": "淺色佈景主題",
|
||||
"system": "系統佈景主題"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "顯示/隱藏圖表",
|
||||
"donate": "贊助"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "登入",
|
||||
"rememberMe": "記住我",
|
||||
"rememberMeDesc": "關閉瀏覽器後仍保持登入狀態",
|
||||
"insecure": "您無法在不安全的連線下登入。請使用 HTTPS。",
|
||||
"2faRequired": "需要兩步驟驗證",
|
||||
"2faWrong": "兩步驟驗證碼不正確"
|
||||
},
|
||||
"client": {
|
||||
"empty": "尚無用戶端。",
|
||||
"newShort": "新增",
|
||||
"sort": "排序",
|
||||
"create": "建立用戶端",
|
||||
"created": "已建立用戶端",
|
||||
"new": "新增用戶端",
|
||||
"name": "名稱",
|
||||
"expireDate": "到期日",
|
||||
"expireDateDesc": "用戶端將被停用的日期。留白表示永久有效",
|
||||
"delete": "刪除",
|
||||
"deleteClient": "刪除用戶端",
|
||||
"deleteDialog1": "您確定要刪除",
|
||||
"deleteDialog2": "此動作無法復原。",
|
||||
"enabled": "啟用",
|
||||
"address": "位址",
|
||||
"serverAllowedIps": "伺服器允許的 IP",
|
||||
"otlDesc": "產生暫時性單次連結",
|
||||
"permanent": "永久",
|
||||
"createdOn": "建立於 ",
|
||||
"lastSeen": "上次連線於 ",
|
||||
"totalDownload": "總下載量: ",
|
||||
"totalUpload": "總上傳量: ",
|
||||
"newClient": "新增用戶端",
|
||||
"disableClient": "停用用戶端",
|
||||
"enableClient": "啟用用戶端",
|
||||
"noPrivKey": "此用戶端沒有已知的私密金鑰,無法建立設定。",
|
||||
"showQR": "顯示 QR Code",
|
||||
"downloadConfig": "下載組態設定檔",
|
||||
"allowedIpsDesc": "將透過 VPN 路由的 IP (會覆寫全域設定)",
|
||||
"serverAllowedIpsDesc": "伺服器將路由至用戶端的 IP",
|
||||
"mtuDesc": "設定 VPN 通道的最大傳輸單位 (封包大小)",
|
||||
"persistentKeepaliveDesc": "Keep-alive 封包的間隔秒數。0 表示停用",
|
||||
"hooks": "Hook 設定",
|
||||
"hooksDescription": "Hook 設定僅適用於 wg-quick",
|
||||
"hooksLeaveEmpty": "僅適用於 wg-quick,否則請保持空白",
|
||||
"dnsDesc": "用戶端使用的 DNS 伺服器 (會覆寫全域設定)",
|
||||
"notConnected": "用戶端未連線",
|
||||
"endpoint": "端點",
|
||||
"endpointDesc": "用戶端建立 WireGuard 連線的來源 IP",
|
||||
"search": "搜尋用戶端...",
|
||||
"config": "組態設定",
|
||||
"viewConfig": "檢視組態設定"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "變更",
|
||||
"cancel": "取消",
|
||||
"create": "建立"
|
||||
},
|
||||
"toast": {
|
||||
"success": "成功",
|
||||
"saved": "已儲存",
|
||||
"error": "錯誤"
|
||||
},
|
||||
"form": {
|
||||
"actions": "操作",
|
||||
"save": "儲存",
|
||||
"revert": "還原",
|
||||
"sectionGeneral": "一般設定",
|
||||
"sectionAdvanced": "進階設定",
|
||||
"noItems": "沒有項目",
|
||||
"nullNoItems": "沒有項目。使用全域設定",
|
||||
"add": "新增"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "工作階段逾時",
|
||||
"sessionTimeoutDesc": "「記住我」的工作階段持續時間 (秒)",
|
||||
"metrics": "計量",
|
||||
"metricsPassword": "密碼",
|
||||
"metricsPasswordDesc": "計量端點的 Bearer 密碼 (密碼或 argon2 雜湊)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "提供 JSON 格式計量的路由",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "提供 Prometheus 計量的路由"
|
||||
},
|
||||
"config": {
|
||||
"connection": "連線",
|
||||
"hostDesc": "用戶端將連線的公開主機名稱 (變更後會使目前組態設定檔失效)",
|
||||
"portDesc": "用戶端將連線的公開 UDP 連接埠 (變更後會使目前組態設定檔失效,您可能也需要變更介面連接埠)",
|
||||
"allowedIpsDesc": "用戶端將使用的允許 IP (全域設定)",
|
||||
"dnsDesc": "用戶端將使用的 DNS 伺服器 (全域設定)",
|
||||
"mtuDesc": "用戶端使用的 MTU (僅適用於新用戶端)",
|
||||
"persistentKeepaliveDesc": "傳送 keepalive 的間隔秒數。以 0 表示停用 (僅適用於新用戶端)",
|
||||
"suggest": "建議",
|
||||
"suggestDesc": "為主機欄位選擇 IP 位址或主機名稱"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "已變更 CIDR",
|
||||
"device": "裝置",
|
||||
"deviceDesc": "用於轉送 WireGuard 流量的乙太網路裝置",
|
||||
"mtuDesc": "WireGuard 將使用的 MTU",
|
||||
"portDesc": "WireGuard 監聽的 UDP 連接埠 (您可能也需要變更連接埠組態設定檔)",
|
||||
"changeCidr": "變更 CIDR",
|
||||
"restart": "重新啟動介面",
|
||||
"restartDesc": "重新啟動 WireGuard 介面",
|
||||
"restartWarn": "您確定要重新啟動介面嗎? 所有用戶端將被中斷連線。",
|
||||
"restartSuccess": "介面已重新啟動"
|
||||
},
|
||||
"introText": "歡迎使用管理面板。\n\n您可在此管理一般、組態、介面與 Hook 設定。\n\n請從側邊欄選擇任一項目開始。"
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} 為必填項目",
|
||||
"validNumber": "{0} 必須為有效的數字",
|
||||
"validString": "{0} 必須為有效的字串",
|
||||
"validBoolean": "{0} 必須為有效的布林值",
|
||||
"validArray": "{0} 必須為有效的陣列",
|
||||
"stringMin": "{0} 至少需要 {1} 個字元",
|
||||
"numberMin": "{0} 不能小於 {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "用戶端 ID",
|
||||
"name": "名稱",
|
||||
"expiresAt": "到期時間",
|
||||
"address4": "IPv4 位址",
|
||||
"address6": "IPv6 位址",
|
||||
"serverAllowedIps": "伺服器允許的 IP"
|
||||
},
|
||||
"user": {
|
||||
"username": "使用者名稱",
|
||||
"password": "密碼",
|
||||
"remember": "記住我",
|
||||
"name": "名稱",
|
||||
"email": "電子郵件",
|
||||
"emailInvalid": "電子郵件格式無效",
|
||||
"passwordMatch": "密碼必須一致",
|
||||
"totpEnable": "啟用 TOTP",
|
||||
"totpEnableTrue": "必須啟用 TOTP",
|
||||
"totpCode": "TOTP 驗證碼"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "主機"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "工作階段逾時",
|
||||
"metricsEnabled": "計量",
|
||||
"metricsPassword": "計量密碼"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "裝置",
|
||||
"cidrValid": "CIDR 格式無效"
|
||||
},
|
||||
"otl": "單次連結",
|
||||
"stringMalformed": "字串格式錯誤",
|
||||
"body": "Body 必須為有效的物件",
|
||||
"hook": "Hook",
|
||||
"enabled": "啟用",
|
||||
"mtu": "MTU",
|
||||
"port": "連接埠",
|
||||
"persistentKeepalive": "保持連線",
|
||||
"address": "IP 位址",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "允許的 IP",
|
||||
"file": "檔案"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "無法複製",
|
||||
"copied": "已複製!",
|
||||
"failed": "複製失敗",
|
||||
"copy": "複製"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "填充封包數量 (Jc)",
|
||||
"jCDescription": "要傳送的填充封包數量 (1-128,建議: 4-12)",
|
||||
"jMinLabel": "填充封包最小大小 (Jmin)",
|
||||
"jMinDescription": "填充封包的最小大小 (0-1279*,建議: 8,必須小於 Jmax)",
|
||||
"jMaxLabel": "填充封包最大大小 (Jmax)",
|
||||
"jMaxDescription": "填充封包的最大大小 (1-1280*,建議: 80,必須大於 Jmin)",
|
||||
"s1Label": "初始封包填充大小 (S1)",
|
||||
"s1Description": "初始封包填充大小 (0-1132 [1280* - 148 = 1132],建議: 15-150,S1+56 ≠ S2)",
|
||||
"s2Label": "回應封包填充大小 (S2)",
|
||||
"s2Description": "回應封包填充大小 (0-1188 [1280* - 92 = 1188],建議: 15-150)",
|
||||
"s3Label": "Cookie 回覆封包填充大小 (S3)",
|
||||
"s3Description": "Cookie 回覆封包填充大小",
|
||||
"s4Label": "傳輸封包填充大小 (S4)",
|
||||
"s4Description": "傳輸封包填充大小",
|
||||
"i1Label": "特殊填充封包 1 (I1)",
|
||||
"i1Description": "協定模仿封包 (16 進位格式): <b 0x...>",
|
||||
"i2Label": "特殊填充封包 2 (I2)",
|
||||
"i2Description": "協定模仿封包 (16 進位格式): <b 0x...>",
|
||||
"i3Label": "特殊填充封包 3 (I3)",
|
||||
"i3Description": "協定模仿封包 (16 進位格式): <b 0x...>",
|
||||
"i4Label": "特殊填充封包 4 (I4)",
|
||||
"i4Description": "協定模仿封包 (16 進位格式): <b 0x...>",
|
||||
"i5Label": "特殊填充封包 5 (I5)",
|
||||
"i5Description": "協定模仿封包 (16 進位格式): <b 0x...>",
|
||||
"h1Label": "初始特徵標頭 (H1)",
|
||||
"h1Description": "初始封包標頭值 (5-2147483647,必須與 H2-H4 不同)",
|
||||
"h2Label": "回應特徵標頭 (H2)",
|
||||
"h2Description": "回應封包標頭值 (5-2147483647,必須與 H1、H3、H4 不同)",
|
||||
"h3Label": "Cookie 回覆特徵標頭 (H3)",
|
||||
"h3Description": "Cookie 回覆封包標頭值 (5-2147483647,必須與 H1、H2、H4 不同)",
|
||||
"h4Label": "傳輸特徵標頭 (H4)",
|
||||
"h4Description": "傳輸封包標頭值 (5-2147483647,必須與 H1-H3 不同)",
|
||||
"mtuNote": "數值取決於 MTU",
|
||||
"obfuscationParameters": "AmneziaWG 混淆參數"
|
||||
}
|
||||
}
|
||||
+27
-1
@@ -5,7 +5,7 @@ export default defineNuxtConfig({
|
||||
future: {
|
||||
compatibilityVersion: 4,
|
||||
},
|
||||
compatibilityDate: '2025-02-04',
|
||||
compatibilityDate: '2026-02-06',
|
||||
devtools: { enabled: true },
|
||||
modules: [
|
||||
'@nuxtjs/i18n',
|
||||
@@ -15,6 +15,7 @@ export default defineNuxtConfig({
|
||||
'radix-vue/nuxt',
|
||||
'@vueuse/nuxt',
|
||||
'@nuxt/eslint',
|
||||
'@nuxt/test-utils/module',
|
||||
],
|
||||
colorMode: {
|
||||
preference: 'system',
|
||||
@@ -79,6 +80,11 @@ export default defineNuxtConfig({
|
||||
language: 'zh-HK',
|
||||
name: '繁體中文(香港)',
|
||||
},
|
||||
{
|
||||
code: 'zh-TW',
|
||||
language: 'zh-TW',
|
||||
name: '正體中文 (台灣)',
|
||||
},
|
||||
{
|
||||
code: 'pl',
|
||||
language: 'pl-PL',
|
||||
@@ -104,6 +110,26 @@ export default defineNuxtConfig({
|
||||
language: 'id-ID',
|
||||
name: 'Bahasa Indonesia',
|
||||
},
|
||||
{
|
||||
code: 'nl',
|
||||
language: 'nl-NL',
|
||||
name: 'Nederlands',
|
||||
},
|
||||
{
|
||||
code: 'nb',
|
||||
language: 'nb-NO',
|
||||
name: 'Norsk bokmål',
|
||||
},
|
||||
{
|
||||
code: 'bg',
|
||||
language: 'bg-BG',
|
||||
name: 'Български',
|
||||
},
|
||||
{
|
||||
code: 'gl',
|
||||
language: 'gl-ES',
|
||||
name: 'Galego',
|
||||
},
|
||||
],
|
||||
defaultLocale: 'en',
|
||||
vueI18n: './i18n.config.ts',
|
||||
|
||||
+32
-27
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wg-easy",
|
||||
"version": "15.2.0-beta.1",
|
||||
"version": "15.2.2",
|
||||
"description": "The easiest way to run WireGuard VPN + Web-based Admin UI.",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -17,57 +17,62 @@
|
||||
"check:all": "pnpm typecheck && pnpm lint && pnpm format:check && pnpm build",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"cli:build": "node cli/build.js",
|
||||
"cli:dev": "tsx cli/index.ts"
|
||||
"cli:dev": "tsx cli/index.ts",
|
||||
"test:unit": "vitest run --project unit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eschricht/nuxt-color-mode": "^1.2.0",
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@libsql/client": "^0.15.15",
|
||||
"@nuxtjs/i18n": "^10.2.0",
|
||||
"@libsql/client": "^0.17.0",
|
||||
"@nuxtjs/i18n": "^10.2.3",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@phc/format": "^1.0.0",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@vueuse/core": "^14.0.0",
|
||||
"@vueuse/nuxt": "^14.0.0",
|
||||
"@tailwindcss/forms": "^0.5.11",
|
||||
"@vueuse/core": "^14.2.0",
|
||||
"@vueuse/nuxt": "^14.2.0",
|
||||
"apexcharts": "^5.3.6",
|
||||
"argon2": "^0.44.0",
|
||||
"cidr-tools": "^11.0.3",
|
||||
"citty": "^0.1.6",
|
||||
"cidr-tools": "^11.0.6",
|
||||
"citty": "^0.2.0",
|
||||
"consola": "^3.4.2",
|
||||
"crc-32": "^1.2.2",
|
||||
"debug": "^4.4.3",
|
||||
"drizzle-orm": "^0.44.7",
|
||||
"ip-bigint": "^8.2.2",
|
||||
"is-cidr": "^6.0.1",
|
||||
"drizzle-orm": "^0.45.1",
|
||||
"ip-bigint": "^8.2.4",
|
||||
"is-cidr": "^6.0.2",
|
||||
"is-ip": "^5.0.1",
|
||||
"js-sha256": "^0.11.1",
|
||||
"nuxt": "^3.20.1",
|
||||
"otpauth": "^9.4.1",
|
||||
"nuxt": "^3.21.1",
|
||||
"otpauth": "^9.5.0",
|
||||
"pinia": "^3.0.4",
|
||||
"qr": "^0.5.2",
|
||||
"qr": "^0.5.4",
|
||||
"radix-vue": "^1.9.17",
|
||||
"semver": "^7.7.3",
|
||||
"tailwindcss": "^3.4.18",
|
||||
"semver": "^7.7.4",
|
||||
"tailwindcss": "^3.4.19",
|
||||
"timeago.js": "^4.0.2",
|
||||
"vue": "latest",
|
||||
"vue3-apexcharts": "^1.10.0",
|
||||
"zod": "^4.1.12"
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint": "^1.10.0",
|
||||
"@nuxt/eslint": "^1.14.0",
|
||||
"@nuxt/test-utils": "^3.23.0",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/phc__format": "^1.0.1",
|
||||
"@types/semver": "^7.7.1",
|
||||
"drizzle-kit": "^0.31.6",
|
||||
"esbuild": "^0.27.0",
|
||||
"eslint": "^9.39.1",
|
||||
"@vitest/coverage-v8": "^4.0.18",
|
||||
"@vitest/ui": "4.0.18",
|
||||
"drizzle-kit": "^0.31.8",
|
||||
"esbuild": "^0.27.3",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-tailwindcss": "^0.7.1",
|
||||
"tsx": "^4.20.6",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vue-tsc": "^3.1.3"
|
||||
"vitest": "^4.0.18",
|
||||
"vue-tsc": "^3.2.4"
|
||||
},
|
||||
"packageManager": "pnpm@10.21.0"
|
||||
"packageManager": "pnpm@10.29.2"
|
||||
}
|
||||
|
||||
Generated
+2982
-2142
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
||||
import type { SharedPublicUser } from '~~/shared/utils/permissions';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const session = await useWGSession(event);
|
||||
|
||||
if (!session.data.userId) {
|
||||
// not logged in
|
||||
return null;
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: 'Not authenticated',
|
||||
});
|
||||
}
|
||||
|
||||
const user = await Database.users.get(session.data.userId);
|
||||
@@ -21,5 +26,5 @@ export default defineEventHandler(async (event) => {
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
totpVerified: user.totpVerified,
|
||||
};
|
||||
} satisfies SharedPublicUser;
|
||||
});
|
||||
|
||||
@@ -16,6 +16,12 @@ function createPreparedStatement(db: DBType) {
|
||||
oneTimeLink: sql.placeholder('oneTimeLink'),
|
||||
expiresAt: sql.placeholder('expiresAt'),
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: oneTimeLink.id,
|
||||
set: {
|
||||
expiresAt: sql.placeholder('expiresAt') as never as string,
|
||||
},
|
||||
})
|
||||
.prepare(),
|
||||
erase: db
|
||||
.update(oneTimeLink)
|
||||
|
||||
@@ -3,7 +3,7 @@ export default defineEventHandler(async (event) => {
|
||||
const url = getRequestURL(event);
|
||||
|
||||
// User can't be logged in, and public routes can be accessed whenever
|
||||
if (url.pathname.startsWith('/api/')) {
|
||||
if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/_i18n/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ async function getPrometheusResponse() {
|
||||
const id = `interface="${wgInterface.name}"`;
|
||||
|
||||
const returnText = [
|
||||
'# HELP wg-easy and wireguard metrics',
|
||||
'',
|
||||
'# HELP wireguard_configured_peers',
|
||||
'# TYPE wireguard_configured_peers gauge',
|
||||
`wireguard_configured_peers{${id}} ${wireguardPeerCount}`,
|
||||
|
||||
@@ -166,11 +166,24 @@ class WireGuard {
|
||||
|
||||
async getClientQRCodeSVG({ clientId }: { clientId: ID }) {
|
||||
const config = await this.getClientConfiguration({ clientId });
|
||||
const ECMode = ['high', 'quartile', 'medium', 'low'] as const;
|
||||
for (const ecc of ECMode) {
|
||||
try {
|
||||
return encodeQR(config, 'svg', {
|
||||
ecc: 'high',
|
||||
ecc,
|
||||
scale: 2,
|
||||
encoding: 'byte',
|
||||
});
|
||||
} catch (err) {
|
||||
if (!(err instanceof Error && err.message === 'Capacity overflow')) {
|
||||
throw err;
|
||||
}
|
||||
// retry with lower ecc
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
'Failed to generate QR code: Capacity overflow at all ECC levels'
|
||||
);
|
||||
}
|
||||
|
||||
cleanClientFilename(name: string): string {
|
||||
@@ -200,7 +213,7 @@ class WireGuard {
|
||||
WG_DEBUG('New Wireguard Keys generated successfully.');
|
||||
}
|
||||
|
||||
if (WG_ENV.WG_EXECUTABLE === 'awg' && wgInterface.h1 === 0) {
|
||||
if (wgInterface.h1 === 0) {
|
||||
WG_DEBUG('Generating random AmneziaWG obfuscation parameters...');
|
||||
const headers = new Set<number>();
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ AllowedIPs = ${allowedIps.join(', ')}${extraLines.length ? `\n${extraLines.join(
|
||||
S2: wgInterface.s2,
|
||||
S3: wgInterface.s3,
|
||||
S4: wgInterface.s4,
|
||||
i1: wgInterface.i1,
|
||||
i2: wgInterface.i2,
|
||||
i3: wgInterface.i3,
|
||||
i4: wgInterface.i4,
|
||||
i5: wgInterface.i5,
|
||||
I1: wgInterface.i1,
|
||||
I2: wgInterface.i2,
|
||||
I3: wgInterface.i3,
|
||||
I4: wgInterface.i4,
|
||||
I5: wgInterface.i5,
|
||||
H1: wgInterface.h1,
|
||||
H2: wgInterface.h2,
|
||||
H3: wgInterface.h3,
|
||||
@@ -131,11 +131,11 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`;
|
||||
S2: wgInterface.s2,
|
||||
S3: wgInterface.s3,
|
||||
S4: wgInterface.s4,
|
||||
i1: client.i1,
|
||||
i2: client.i2,
|
||||
i3: client.i3,
|
||||
i4: client.i4,
|
||||
i5: client.i5,
|
||||
I1: client.i1,
|
||||
I2: client.i2,
|
||||
I3: client.i3,
|
||||
I4: client.i4,
|
||||
I5: client.i5,
|
||||
H1: wgInterface.h1,
|
||||
H2: wgInterface.h2,
|
||||
H3: wgInterface.h3,
|
||||
|
||||
@@ -45,6 +45,11 @@ type SharedUserType =
|
||||
| Pick<UserType, 'id' | 'role'>
|
||||
| (Pick<UserType, 'id'> & { role: BrandedNumber });
|
||||
|
||||
export type SharedPublicUser = Pick<
|
||||
UserType,
|
||||
'id' | 'username' | 'name' | 'email' | 'totpVerified'
|
||||
> & { role: BrandedNumber };
|
||||
|
||||
type PermissionCheck<Key extends keyof Permissions> =
|
||||
| boolean
|
||||
| ((user: SharedUserType, data: Permissions[Key]['dataType']) => boolean);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { expect, test, describe } from 'vitest';
|
||||
import {
|
||||
hashPassword,
|
||||
isPasswordValid,
|
||||
isValidPasswordHash,
|
||||
} from '../../server/utils/password';
|
||||
|
||||
describe('password', () => {
|
||||
test('password', async () => {
|
||||
const hash = await hashPassword('password');
|
||||
|
||||
await expect(isPasswordValid('password', hash)).resolves.toBe(true);
|
||||
await expect(isPasswordValid('wrong', hash)).resolves.toBe(false);
|
||||
|
||||
expect(isValidPasswordHash('not a hash')).toBe(false);
|
||||
expect(isValidPasswordHash(hash)).toBe(true);
|
||||
|
||||
expect(isValidPasswordHash(hash.replace('argon2', 'argon3'))).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
projects: [
|
||||
{
|
||||
test: {
|
||||
name: 'unit',
|
||||
include: ['test/unit/*.{test,spec}.ts'],
|
||||
environment: 'node',
|
||||
},
|
||||
},
|
||||
],
|
||||
coverage: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user