Compare commits

..

15 Commits

Author SHA1 Message Date
Bernd Storath 7964dc7993 Bump version to 15.2.0 2026-01-12 08:28:23 +01:00
RaffaelHold 0ac5d7d461 feat(docs): Extend docs for routed setup with nftables (#2380)
* Extend docs for routed setup with nftables

When using nftables in a routed setup different up and down hooks need to be used. 
To limit interaction with docker managed chains a custom WG_EASY chain is added as a jump target.
Since nft only supports deletion via handles awk is needed to get the handle of the jump rule for deletion

* Remove link to podman-nft

* Fix formatting according to prettier rules

* Add additional whitespace
2026-01-12 08:21:18 +01:00
Bernd Storath 826914a4f3 update packages 2026-01-12 08:19:01 +01:00
Bernd Storath 261da431e7 Fix: reset onetimelink expiration instead of failing (#2370)
* update expiresAt instead of failing

* add changelog
2025-12-29 19:12:53 +01:00
Bernd Storath 94b33abf5e Remove armv7 support (#2369)
remove armv7 support
2025-12-29 18:54:47 +01:00
Bernd Storath 8325056ccc update lockfile 2025-12-29 18:47:48 +01:00
Bernd Storath 81a1b2c907 update packages 2025-12-29 18:36:51 +01:00
dependabot[bot] fc8f89fb83 build(deps): bump actions/download-artifact from 6 to 7 (#2343)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 07:58:23 +01:00
dependabot[bot] d846c7745f build(deps): bump actions/upload-artifact from 5 to 6 (#2344)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-18 07:58:12 +01:00
Bernd Storath 61c6fd6c02 update packages 2025-12-15 08:03:25 +01:00
David DIVERRES abe5708058 Update fr.json (#2326)
Update fr.json - Add missing translations and improve existing ones

- Add missing keys: client.delete, client.search, client.config, client.viewConfig
- Add complete copy section (4 keys)
- Add complete awg section (27 keys for AmneziaWG parameters)
- Fix terminology: "double facteur" → "deux facteurs" (standard French)
- Fix zod.generic.validBoolean translation
- Fix zod.generic.stringMin capitalization and wording
- Translate zod.client.id to French
- Improve admin.general route descriptions
2025-12-08 08:51:38 +01:00
Bernd Storath 626339bddb update packages 2025-12-08 08:30:53 +01:00
Danya 381ae23c07 Update ru (#2324)
* Update ru.json

Full revision of the Russian localization for the AWG configuration block, including terminology corrections, improved consistency, and clarified parameter descriptions.

* Update ru.json

* fix formatting

---------

Co-authored-by: Bernd Storath <999999bst@gmail.com>
2025-12-05 15:59:12 +01:00
Nikolas 52382d1d7a Update uk.json (#2323) 2025-12-05 07:35:15 +01:00
Mike 68e5216d4b Update ru.json (#2319)
* Update ru.json

* format

---------

Co-authored-by: Bernd Storath <999999bst@gmail.com>
2025-12-02 12:26:04 +01:00
17 changed files with 1845 additions and 1586 deletions
+4 -4
View File
@@ -18,8 +18,8 @@ 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@v6
@@ -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-*
+4 -4
View File
@@ -25,8 +25,8 @@ 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@v6
with:
@@ -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-*
+2 -2
View File
@@ -21,8 +21,8 @@ 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@v6
+4 -4
View File
@@ -26,8 +26,8 @@ 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@v6
@@ -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-*
+9 -5
View File
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## Added
## [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)
@@ -15,13 +17,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- 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)
@@ -30,11 +32,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- 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
@@ -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
@@ -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
+16
View File
@@ -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
```
///
+1 -1
View File
@@ -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
+2 -2
View File
@@ -11,7 +11,7 @@
"format:check:docs": "prettier --check docs"
},
"devDependencies": {
"prettier": "^3.7.3"
"prettier": "^3.7.4"
},
"packageManager": "pnpm@10.24.0"
"packageManager": "pnpm@10.28.0"
}
+5 -5
View File
@@ -9,16 +9,16 @@ importers:
.:
devDependencies:
prettier:
specifier: ^3.7.3
version: 3.7.3
specifier: ^3.7.4
version: 3.7.4
packages:
prettier@3.7.3:
resolution: {integrity: sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==}
prettier@3.7.4:
resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
engines: {node: '>=14'}
hasBin: true
snapshots:
prettier@3.7.3: {}
prettier@3.7.4: {}
+59 -13
View File
@@ -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"
}
}
+117 -71
View File
@@ -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": "Хуки работают только с wgquick",
"hooksLeaveEmpty": "Только для wgquick. В остальных случаях оставьте пустым",
"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"
}
}
+1
View File
@@ -88,6 +88,7 @@
"name": "Ім'я",
"expireDate": "Термін дії",
"expireDateDesc": "Дата, коли клієнт буде відключений. Порожнє для постійного користування",
"delete": "Видалити",
"deleteClient": "Видалити клієнта",
"deleteDialog1": "Ви впевнені, що бажаєте видалити",
"deleteDialog2": "Цю дію неможливо скасувати.",
+16 -16
View File
@@ -1,6 +1,6 @@
{
"name": "wg-easy",
"version": "15.2.0-beta.3",
"version": "15.2.0",
"description": "The easiest way to run WireGuard VPN + Web-based Admin UI.",
"private": true,
"type": "module",
@@ -22,12 +22,12 @@
"dependencies": {
"@eschricht/nuxt-color-mode": "^1.2.0",
"@heroicons/vue": "^2.2.0",
"@libsql/client": "^0.15.15",
"@libsql/client": "^0.17.0",
"@nuxtjs/i18n": "^10.2.1",
"@nuxtjs/tailwindcss": "^6.14.0",
"@phc/format": "^1.0.0",
"@pinia/nuxt": "^0.11.3",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/forms": "^0.5.11",
"@vueuse/core": "^14.1.0",
"@vueuse/nuxt": "^14.1.0",
"apexcharts": "^5.3.6",
@@ -37,37 +37,37 @@
"consola": "^3.4.2",
"crc-32": "^1.2.2",
"debug": "^4.4.3",
"drizzle-orm": "^0.44.7",
"drizzle-orm": "^0.45.1",
"ip-bigint": "^8.2.2",
"is-cidr": "^6.0.1",
"is-ip": "^5.0.1",
"js-sha256": "^0.11.1",
"nuxt": "^3.20.1",
"nuxt": "^3.20.2",
"otpauth": "^9.4.1",
"pinia": "^3.0.4",
"qr": "^0.5.3",
"qr": "^0.5.4",
"radix-vue": "^1.9.17",
"semver": "^7.7.3",
"tailwindcss": "^3.4.18",
"tailwindcss": "^3.4.19",
"timeago.js": "^4.0.2",
"vue": "latest",
"vue3-apexcharts": "^1.10.0",
"zod": "^4.1.13"
"zod": "^4.3.5"
},
"devDependencies": {
"@nuxt/eslint": "^1.11.0",
"@nuxt/eslint": "^1.12.1",
"@types/debug": "^4.1.12",
"@types/phc__format": "^1.0.1",
"@types/semver": "^7.7.1",
"drizzle-kit": "^0.31.7",
"esbuild": "^0.27.0",
"eslint": "^9.39.1",
"drizzle-kit": "^0.31.8",
"esbuild": "^0.27.2",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.7.3",
"prettier-plugin-tailwindcss": "^0.7.1",
"prettier": "^3.7.4",
"prettier-plugin-tailwindcss": "^0.7.2",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vue-tsc": "^3.1.5"
"vue-tsc": "^3.2.2"
},
"packageManager": "pnpm@10.24.0"
"packageManager": "pnpm@10.28.0"
}
+1597 -1457
View File
File diff suppressed because it is too large Load Diff
@@ -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)