Compare commits
85 Commits
v15.2.1
...
8c70c24205
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c70c24205 | |||
| c70ad1d08b | |||
| d0566a1df9 | |||
| bc95a2851f | |||
| e03d743307 | |||
| 99357848e5 | |||
| c41ae0d4c5 | |||
| 66f8bde206 | |||
| b3afb9ac1b | |||
| 9581e6eacb | |||
| 90e2bbe0a6 | |||
| 7b5ba95938 | |||
| da90d67cc0 | |||
| a52da67b38 | |||
| e513090074 | |||
| 2dc8ba7792 | |||
| 4e8cccb4c7 | |||
| e57b0977d3 | |||
| b8be53c3f7 | |||
| 0794413191 | |||
| 261b0d6b8f | |||
| f656d57d20 | |||
| 46074fea1c | |||
| 05c655ede9 | |||
| ebcc42cc49 | |||
| be8d24e492 | |||
| 9682dedea7 | |||
| 5eb80fe3c1 | |||
| dd9da2a067 | |||
| 15111ecd62 | |||
| e9f4b4650b | |||
| e3e4049f8e | |||
| 3fb9adbf6f | |||
| cd9db1563d | |||
| b5c30f5dbe | |||
| 1eb9527175 | |||
| cd890c1f0f | |||
| 2a78b30aeb | |||
| 9a843087c3 | |||
| 483b63bba6 | |||
| 13942c97b2 | |||
| 82c64e506e | |||
| 9b3d919168 | |||
| 3eaf0d01dc | |||
| 414e9a114b | |||
| 2d28d87c5c | |||
| 76c2233e46 | |||
| abedf9f38e | |||
| 25f3fa3c0f | |||
| c3c51f8088 | |||
| 8ea2b635c1 | |||
| bc4dfd03df | |||
| 7cde04de81 | |||
| 5228734c98 | |||
| 47f81dd66a | |||
| e5b2c3d10b | |||
| 059a0ccffc | |||
| 8c9c54c8b2 | |||
| 02ce6f0a65 | |||
| 48682e1abd | |||
| 044dd34dcc | |||
| a469ac6897 | |||
| 1178d23659 | |||
| b3cc1ce839 | |||
| 71aaec93ef | |||
| 7a219b73d4 | |||
| c456c5e7dd | |||
| a5880cc0b8 | |||
| 5fca628ebd | |||
| 7ab297c366 | |||
| c5de8f0f44 | |||
| c0641889cf | |||
| 9141562f91 | |||
| d21af70df1 | |||
| 56ee86cc1c | |||
| f017b4968c | |||
| 6004457666 | |||
| 1a5a0180ea | |||
| c732f149e6 | |||
| 4819480eb0 | |||
| fc7ab0dc21 | |||
| eb6b96c0f1 | |||
| f62fad9c40 | |||
| e9a472c8f7 | |||
| 552e2b8cbf |
@@ -5,13 +5,3 @@ updates:
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
rebase-strategy: "auto"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
rebase-strategy: "auto"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/src/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
rebase-strategy: "auto"
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
@@ -38,21 +38,21 @@ jobs:
|
||||
latest=false
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ matrix.arch.platform }}
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -85,32 +85,32 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to Codeberg
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: codeberg.org
|
||||
username: ${{ secrets.CODEBERG_USER }}
|
||||
password: ${{ secrets.CODEBERG_PASS }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
@@ -47,21 +47,21 @@ jobs:
|
||||
latest=false
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ matrix.arch.platform }}
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -94,32 +94,32 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to Codeberg
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: codeberg.org
|
||||
username: ${{ secrets.CODEBERG_USER }}
|
||||
password: ${{ secrets.CODEBERG_PASS }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
|
||||
@@ -32,20 +32,20 @@ jobs:
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Docker Image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
@@ -46,21 +46,21 @@ jobs:
|
||||
latest=false
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ matrix.arch.platform }}
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
@@ -95,32 +95,32 @@ jobs:
|
||||
needs: docker-build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to Codeberg
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: codeberg.org
|
||||
username: ${{ secrets.CODEBERG_USER }}
|
||||
password: ${{ secrets.CODEBERG_PASS }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/wg-easy/wg-easy
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v6
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "lts/jod"
|
||||
node-version: "lts/krypton"
|
||||
check-latest: true
|
||||
cache: "pnpm"
|
||||
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v6
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "lts/jod"
|
||||
node-version: "lts/krypton"
|
||||
check-latest: true
|
||||
cache: "pnpm"
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
"aaron-bond.better-comments",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"antfu.goto-alias",
|
||||
"prettier.prettier-vscode",
|
||||
"esbenp.prettier-vscode",
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"vue.volar",
|
||||
|
||||
Vendored
+5
-5
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"editor.tabSize": 2,
|
||||
"editor.useTabStops": false,
|
||||
"editor.defaultFormatter": "prettier.prettier-vscode",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "always"
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "prettier.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "prettier.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "prettier.prettier-vscode"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[markdown]": {
|
||||
"editor.defaultFormatter": "prettier.prettier-vscode",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.tabSize": 4,
|
||||
"editor.useTabStops": false
|
||||
},
|
||||
|
||||
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- AWG: support for H1-H4 ranges (https://github.com/wg-easy/wg-easy/pull/2480)
|
||||
- Client Firewall (https://github.com/wg-easy/wg-easy/pull/2418)
|
||||
- CLI: Show QR code (https://github.com/wg-easy/wg-easy/pull/2518)
|
||||
- Copy QR code to clipboard / save as png (https://github.com/wg-easy/wg-easy/pull/2521)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add trailing newline to Prometheus metrics output (https://github.com/wg-easy/wg-easy/pull/2573)
|
||||
- Correctly use DEBUG env var (https://github.com/wg-easy/wg-easy/pull/2619)
|
||||
|
||||
### Changed
|
||||
|
||||
- Hooks are now Textareas (https://github.com/wg-easy/wg-easy/pull/2522)
|
||||
- Update to Node Krypton (24) (https://github.com/wg-easy/wg-easy/pull/2536)
|
||||
- Mobile UI (https://github.com/wg-easy/wg-easy/pull/2569)
|
||||
- Prevent enabling client when expired (https://github.com/wg-easy/wg-easy/pull/2594)
|
||||
|
||||
## [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
|
||||
|
||||
+23
-11
@@ -1,4 +1,4 @@
|
||||
FROM docker.io/library/node:jod-alpine AS build
|
||||
FROM docker.io/library/node:krypton-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
# update corepack
|
||||
@@ -7,7 +7,7 @@ RUN npm install --global corepack@latest
|
||||
RUN corepack enable pnpm
|
||||
|
||||
# Copy Web UI
|
||||
COPY src/package.json src/pnpm-lock.yaml ./
|
||||
COPY src/package.json src/pnpm-lock.yaml src/pnpm-workspace.yaml ./
|
||||
RUN pnpm install
|
||||
|
||||
# Build UI
|
||||
@@ -15,14 +15,22 @@ 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 && \
|
||||
make
|
||||
git clone https://github.com/amnezia-vpn/amneziawg-go && \
|
||||
cd amneziawg-go && \
|
||||
make && \
|
||||
cd ../amneziawg-tools/src && \
|
||||
make && \
|
||||
sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' ./wg-quick/linux.bash
|
||||
|
||||
FROM docker.io/library/node:krypton-alpine AS build-libsql
|
||||
WORKDIR /app
|
||||
RUN npm install --no-save --omit=dev libsql
|
||||
|
||||
# Copy build result to a new image.
|
||||
# This saves a lot of disk space.
|
||||
FROM docker.io/library/node:jod-alpine
|
||||
FROM docker.io/library/node:krypton-alpine
|
||||
WORKDIR /app
|
||||
|
||||
HEALTHCHECK --interval=1m --timeout=5s --retries=3 CMD /usr/bin/timeout 5s /bin/sh -c "/usr/bin/wg show | /bin/grep -q interface || exit 1"
|
||||
@@ -32,12 +40,14 @@ COPY --from=build /app/.output /app
|
||||
# Copy migrations
|
||||
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 cache clean --force
|
||||
COPY --from=build-libsql /app/node_modules /app/server/node_modules
|
||||
|
||||
# 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,7 +62,9 @@ RUN apk add --no-cache \
|
||||
nftables \
|
||||
kmod \
|
||||
iptables-legacy \
|
||||
wireguard-tools
|
||||
wireguard-go \
|
||||
wireguard-tools && \
|
||||
sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' /usr/bin/wg-quick
|
||||
|
||||
RUN mkdir -p /etc/amnezia
|
||||
RUN ln -s /etc/wireguard /etc/amnezia/amneziawg
|
||||
@@ -62,7 +74,7 @@ RUN update-alternatives --install /usr/sbin/iptables iptables /usr/sbin/iptables
|
||||
RUN update-alternatives --install /usr/sbin/ip6tables ip6tables /usr/sbin/ip6tables-legacy 10 --slave /usr/sbin/ip6tables-restore ip6tables-restore /usr/sbin/ip6tables-legacy-restore --slave /usr/sbin/ip6tables-save ip6tables-save /usr/sbin/ip6tables-legacy-save
|
||||
|
||||
# Set Environment
|
||||
ENV DEBUG=Server,WireGuard,Database,CMD
|
||||
ENV DEBUG=Server,WireGuard,Database,CMD,Firewall
|
||||
ENV PORT=51821
|
||||
ENV HOST=0.0.0.0
|
||||
ENV INSECURE=false
|
||||
|
||||
+4
-3
@@ -1,4 +1,4 @@
|
||||
FROM docker.io/library/node:jod-alpine
|
||||
FROM docker.io/library/node:krypton-alpine
|
||||
WORKDIR /app
|
||||
|
||||
# update corepack
|
||||
@@ -16,6 +16,7 @@ RUN apk add --no-cache \
|
||||
ip6tables \
|
||||
kmod \
|
||||
iptables-legacy \
|
||||
wireguard-go \
|
||||
wireguard-tools
|
||||
|
||||
# Use iptables-legacy
|
||||
@@ -23,7 +24,7 @@ RUN update-alternatives --install /usr/sbin/iptables iptables /usr/sbin/iptables
|
||||
RUN update-alternatives --install /usr/sbin/ip6tables ip6tables /usr/sbin/ip6tables-legacy 10 --slave /usr/sbin/ip6tables-restore ip6tables-restore /usr/sbin/ip6tables-legacy-restore --slave /usr/sbin/ip6tables-save ip6tables-save /usr/sbin/ip6tables-legacy-save
|
||||
|
||||
# Set Environment
|
||||
ENV DEBUG=Server,WireGuard,Database,CMD
|
||||
ENV DEBUG=Server,WireGuard,Database,CMD,Firewall
|
||||
ENV PORT=51821
|
||||
ENV HOST=0.0.0.0
|
||||
ENV INSECURE=true
|
||||
@@ -31,7 +32,7 @@ ENV INIT_ENABLED=false
|
||||
ENV DISABLE_IPV6=false
|
||||
|
||||
# Install Dependencies
|
||||
COPY src/package.json src/pnpm-lock.yaml ./
|
||||
COPY src/package.json src/pnpm-lock.yaml src/pnpm-workspace.yaml ./
|
||||
RUN pnpm install
|
||||
|
||||
# Copy Project
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
# WireGuard Easy
|
||||
|
||||
[](https://github.com/wg-easy/wg-easy/actions/workflows/deploy.yml)
|
||||
[](https://github.com/wg-easy/wg-easy/actions/workflows/deploy.yml)
|
||||
[](https://github.com/wg-easy/wg-easy/actions/workflows/lint.yml)
|
||||
[](https://github.com/wg-easy/wg-easy/stargazers)
|
||||
[](LICENSE)
|
||||
[](https://github.com/wg-easy/wg-easy/releases/latest)
|
||||
[](https://github.com/wg-easy/wg-easy/pkgs/container/wg-easy)
|
||||
[](https://github.com/wg-easy/wg-easy/pkgs/container/wg-easy)
|
||||
|
||||
You have found the easiest way to install & manage WireGuard on any Linux host!
|
||||
|
||||
<!-- TOOD: update screenshot -->
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/screenshot.png" width="802" alt="wg-easy Screenshot" />
|
||||
</p>
|
||||
@@ -33,6 +31,7 @@ You have found the easiest way to install & manage WireGuard on any Linux host!
|
||||
- IPv6 support
|
||||
- CIDR support
|
||||
- 2FA support
|
||||
- Per-client firewall filtering (requires iptables)
|
||||
|
||||
> [!NOTE]
|
||||
> To better manage documentation for this project, it has its own site here: [https://wg-easy.github.io/wg-easy/latest](https://wg-easy.github.io/wg-easy/latest)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"fill" : {
|
||||
"automatic-gradient" : "display-p3:0.48853,0.13220,0.12335,1.00000"
|
||||
},
|
||||
"groups" : [
|
||||
{
|
||||
"layers" : [
|
||||
{
|
||||
"fill" : {
|
||||
"automatic-gradient" : "srgb:1.00000,1.00000,1.00000,1.00000"
|
||||
},
|
||||
"image-name" : "wireguard-logo.png",
|
||||
"name" : "wireguard-logo",
|
||||
"position" : {
|
||||
"scale" : 0.5,
|
||||
"translation-in-points" : [
|
||||
255.828125,
|
||||
-225.5
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"fill-specializations" : [
|
||||
{
|
||||
"value" : {
|
||||
"automatic-gradient" : "srgb:1.00000,1.00000,1.00000,1.00000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"appearance" : "dark",
|
||||
"value" : {
|
||||
"automatic-gradient" : "display-p3:0.48853,0.13220,0.12335,1.00000"
|
||||
}
|
||||
}
|
||||
],
|
||||
"image-name" : "ticket.png",
|
||||
"name" : "ticket",
|
||||
"position" : {
|
||||
"scale" : 1.2,
|
||||
"translation-in-points" : [
|
||||
-119.91562499999998,
|
||||
165.65625
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"shadow" : {
|
||||
"kind" : "neutral",
|
||||
"opacity" : 0.5
|
||||
},
|
||||
"translucency" : {
|
||||
"enabled" : true,
|
||||
"value" : 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"supported-platforms" : {
|
||||
"circles" : [
|
||||
"watchOS"
|
||||
],
|
||||
"squares" : "shared"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 167 KiB |
@@ -50,23 +50,23 @@ If a parameter is not set, it will not be added to the configuration. If all Amn
|
||||
|
||||
## Client Applications
|
||||
|
||||
To be able to connect to wg-easy if AmneziaWG is enabled, you must have an AmneziaWG-compatible client. Currently, only WG Tunnel and Amnezia VPN supports AmneziaWG 1.5/2.0! AmneziaWG clients require building from source code.
|
||||
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:
|
||||
|
||||
- [Amnezia VPN](https://play.google.com/store/apps/details?id=org.amnezia.vpn) - Amnezia VPN 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:
|
||||
|
||||
- [Amnezia VPN](https://apps.apple.com/us/app/amneziavpn/id1600529900) - Amnezia VPN 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) - AmneziaWG Official Client (Requires building from source code)
|
||||
- [Amnezia VPN](https://amnezia.org/downloads) - Amnezia VPN Official Client
|
||||
- [AmneziaWG](https://github.com/amnezia-vpn/amneziawg-windows-client/releases) - AmneziaWG Official Client
|
||||
|
||||
Linux:
|
||||
|
||||
|
||||
@@ -5,11 +5,12 @@ title: Optional Configuration
|
||||
You can set these environment variables to configure the container. They are not required, but can be useful in some cases.
|
||||
|
||||
| Env | Default | Example | Description |
|
||||
| -------------- | --------- | ----------- | ---------------------------------- |
|
||||
| ----------------------- | --------- | ----------- | --------------------------------------- |
|
||||
| `PORT` | `51821` | `6789` | TCP port for Web UI. |
|
||||
| `HOST` | `0.0.0.0` | `localhost` | IP address web UI binds to. |
|
||||
| `INSECURE` | `false` | `true` | If access over http is allowed |
|
||||
| `DISABLE_IPV6` | `false` | `true` | If IPv6 support should be disabled |
|
||||
| `DISABLE_VERSION_CHECK` | `false` | `true` | If wg-easy should check for new updates |
|
||||
|
||||
/// note | IPv6 Caveats
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -6,6 +6,20 @@ hide:
|
||||
|
||||
Here are some frequently asked questions or errors about `wg-easy`. If you have a question that is not answered here, please feel free to open a discussion on GitHub.
|
||||
|
||||
## How do I restrict client access to specific networks or servers?
|
||||
|
||||
Use the **Per-Client Firewall** feature to enforce server-side restrictions on what each client can access.
|
||||
|
||||
**Requirements:** This feature requires `iptables` (and `ip6tables` for IPv6) to be installed on the host system.
|
||||
|
||||
1. Enable "Per-Client Firewall" in **Admin Panel → Interface**
|
||||
2. Edit a client and configure "Firewall Allowed IPs"
|
||||
3. Specify which destinations the client should be allowed to access
|
||||
|
||||
Unlike "Allowed IPs" which only controls client-side routing, firewall rules are enforced by the server and cannot be bypassed.
|
||||
|
||||
See the [Admin Panel Guide](./guides/admin.md#per-client-firewall) and [Client Guide](./guides/clients.md#firewall-allowed-ips) for detailed configuration.
|
||||
|
||||
## Error: WireGuard exited with the error: Cannot find device "wg0"
|
||||
|
||||
This error indicates that the WireGuard interface `wg0` does not exist. This can happen if the WireGuard kernel module is not loaded or if the interface was not created properly.
|
||||
@@ -95,3 +109,31 @@ To resolve this issue, you can try the following steps:
|
||||
```shell
|
||||
echo "ip6table_filter" | sudo tee -a /etc/modules
|
||||
```
|
||||
|
||||
## Clients lose connectivity after restarting the container when using multiple networks?
|
||||
|
||||
When you attach multiple Docker networks (e.g., `wg` and a reverse proxy network like `traefik` or `nginx`) to the `wg-easy` container, Docker might assign the network interfaces randomly (e.g., swapping `eth0` and `eth1`). Since `wg-easy` expects the wireguard interface to act as `eth0` and configures `POSTROUTING` rules for it, connectivity will break if the interfaces are swapped upon container restart.
|
||||
|
||||
To solve this, specify the `interface_name` and `gw_priority` explicitly in your `docker-compose.yml` file to guarantee that the `wg` network always binds to `eth0` and acts as the default gateway.
|
||||
|
||||
**Example `docker-compose.yml`:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
wg-easy:
|
||||
# ... other configuration ...
|
||||
networks:
|
||||
wg:
|
||||
interface_name: eth0
|
||||
gw_priority: 1
|
||||
ipv4_address: 10.42.42.42
|
||||
nginx:
|
||||
interface_name: eth1
|
||||
gw_priority: 0
|
||||
|
||||
networks:
|
||||
wg:
|
||||
# ... wg network config ...
|
||||
nginx:
|
||||
external: true
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,4 +2,42 @@
|
||||
title: Admin Panel
|
||||
---
|
||||
|
||||
TODO
|
||||
## Interface Settings
|
||||
|
||||
### Per-Client Firewall
|
||||
|
||||
Enable server-side firewall filtering to enforce network access restrictions per client.
|
||||
|
||||
When enabled, each client can have custom "Firewall Allowed IPs" configured that restrict which destinations they can access through the VPN. These restrictions are enforced by the server using iptables/ip6tables and cannot be bypassed by the client.
|
||||
|
||||
/// warning | Experimental Feature
|
||||
|
||||
This feature is currently experimental. While functional, it should be thoroughly tested in your environment before relying on it for production security requirements. Always verify that firewall rules are working as expected using test traffic or by manually inspecting the rules.
|
||||
|
||||
///
|
||||
|
||||
**Requirements:**
|
||||
|
||||
- `iptables` must be installed on the host system
|
||||
- `ip6tables` must be installed if IPv6 is enabled (default)
|
||||
- The feature cannot be enabled if these tools are not available
|
||||
|
||||
/// note
|
||||
Most Linux distributions include iptables by default. If you're running in a minimal container environment, you may need to install the `iptables` package on the host system.
|
||||
///
|
||||
|
||||
**Enable this feature if you want to:**
|
||||
|
||||
- Restrict certain clients to only access specific servers or networks
|
||||
- Prevent clients from accessing the internet while allowing LAN access
|
||||
- Enforce port-based restrictions (e.g., only allow HTTP/HTTPS)
|
||||
- Separate routing configuration from security enforcement
|
||||
|
||||
**How it works:**
|
||||
|
||||
1. Enable "Per-Client Firewall" in Admin Panel → Interface
|
||||
2. Edit any client to see the new "Firewall Allowed IPs" field
|
||||
3. Specify allowed destinations (IPs, subnets, ports) for that client
|
||||
4. Server enforces these rules automatically
|
||||
|
||||
See [Edit Client → Firewall Allowed IPs](./clients.md#firewall-allowed-ips) for detailed configuration syntax and examples.
|
||||
|
||||
@@ -41,3 +41,31 @@ docker compose exec -it wg-easy cli db:admin:reset --password <new_password>
|
||||
```
|
||||
|
||||
This will reset the password for the admin user to the new password you provided. If you include special characters in the password, make sure to escape them properly.
|
||||
|
||||
### Show Clients
|
||||
|
||||
List all clients that are currently configured with details such as client ID, Name, Public Key, and enabled status.
|
||||
|
||||
```shell
|
||||
cli clients:list
|
||||
```
|
||||
|
||||
### Show Client QR Code
|
||||
|
||||
Display the QR code for a specific client, which can be scanned by a compatible app to import the client's configuration.
|
||||
|
||||
```shell
|
||||
cli clients:qr <client_id>
|
||||
```
|
||||
|
||||
Replace `<client_id>` with the actual client ID you want to show the QR code for.
|
||||
|
||||
/// warning | IPv6 Support
|
||||
|
||||
IPv6 support is enabled by default, even if you disabled it using environment variables. To disable it pass the `--no-ipv6` flag when running the CLI.
|
||||
|
||||
```shell
|
||||
cli clients:qr <client_id> --no-ipv6
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -19,7 +19,58 @@ Which IPs will be routed through the VPN.
|
||||
|
||||
This will not prevent the user from modifying it locally and accessing IP ranges that they should not be able to access.
|
||||
|
||||
Use firewall rules to prevent access to IP ranges that the user should not be able to access.
|
||||
Use the Firewall Allowed IPs feature to prevent access to IP ranges that the user should not be able to access.
|
||||
|
||||
## Firewall Allowed IPs
|
||||
|
||||
/// note | Attention
|
||||
|
||||
This field only appears when **Per-Client Firewall** is enabled in the Admin Panel → Interface settings.
|
||||
|
||||
///
|
||||
|
||||
Server-side firewall rules that restrict which destinations the client can access, regardless of their local configuration.
|
||||
|
||||
Unlike "Allowed IPs" which only controls routing on the client side, these rules are enforced by the server using iptables/ip6tables and cannot be bypassed by the client.
|
||||
|
||||
**Supported Formats:**
|
||||
|
||||
- `10.10.0.3`, `2001:db8::1` - Allow access to a single IP address
|
||||
- `10.10.0.0/24`, `2001:db8::/32` - Allow access to an entire subnet
|
||||
- `192.168.1.5:443` - Allow access to specific port (TCP+UDP)
|
||||
- `192.168.1.5:443/tcp` - Allow access to specific port (TCP only)
|
||||
- `192.168.1.5:443/udp` - Allow access to specific port (UDP only)
|
||||
- `10.10.0.0/24:443` - Allow access to an entire subnet on a specific port (TCP+UDP)
|
||||
- `10.10.0.0/24:443/tcp` - Allow access to an entire subnet on a specific port (TCP only)
|
||||
- `10.10.0.0/24:443/udp` - Allow access to an entire subnet on a specific port (UDP only)
|
||||
- `[2001:db8::1]:443` - IPv6 address with port (brackets required)
|
||||
- `[2001:db8::/32]:443/tcp` - IPv6 CIDR with port and protocol
|
||||
|
||||
/// warning | Invalid Formats
|
||||
|
||||
Protocol specifiers (`/tcp` or `/udp`) require a port number. The following formats are **not supported** and will result in an error:
|
||||
|
||||
- `10.10.0.3/tcp` (use `10.10.0.3:443/tcp` instead)
|
||||
- `10.10.0.0/24/udp` (use `10.10.0.0/24:53/udp` instead)
|
||||
|
||||
///
|
||||
|
||||
**Behavior:**
|
||||
|
||||
- **Empty**: Falls back to the client's "Allowed IPs" setting
|
||||
- **Specified**: Only listed destinations are accessible (allow-only, everything else is blocked)
|
||||
- **Disable for specific client**: To disable firewall filtering for a single client while keeping it enabled for others, add `0.0.0.0/0, ::/0` to allow all traffic
|
||||
|
||||
/// note
|
||||
To allow clients to reach the VPN server itself (e.g. for DNS), include the server's VPN address in the firewall allowed IPs.
|
||||
///
|
||||
|
||||
**Use Case Examples**:
|
||||
|
||||
- Allow only specific servers: `10.10.0.5`
|
||||
- Allow only internal network: `10.10.0.0/24, 192.168.1.0/24`
|
||||
- Allow only web browsing: `0.0.0.0/0:80, 0.0.0.0/0:443, [::/0]:80, [::/0]:443`
|
||||
- Block internet, allow LAN: Leave "Allowed IPs" as `0.0.0.0/0, ::/0` but set Firewall IPs to `10.0.0.0/8, 192.168.0.0/16`
|
||||
|
||||
## Server Allowed IPs
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
"format:check:docs": "prettier --check docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.7.4"
|
||||
"prettier": "^3.8.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.28.0"
|
||||
"packageManager": "pnpm@11.5.0"
|
||||
}
|
||||
|
||||
Generated
+5
-5
@@ -9,16 +9,16 @@ importers:
|
||||
.:
|
||||
devDependencies:
|
||||
prettier:
|
||||
specifier: ^3.7.4
|
||||
version: 3.7.4
|
||||
specifier: ^3.8.3
|
||||
version: 3.8.3
|
||||
|
||||
packages:
|
||||
|
||||
prettier@3.7.4:
|
||||
resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
|
||||
prettier@3.8.3:
|
||||
resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
prettier@3.7.4: {}
|
||||
prettier@3.8.3: {}
|
||||
|
||||
@@ -23,4 +23,6 @@ logs
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
coverage/
|
||||
|
||||
wg-easy.db
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
setups.@nuxt/test-utils="4.0.3"
|
||||
@@ -0,0 +1,7 @@
|
||||
:root {
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
>
|
||||
<slot name="description" />
|
||||
</DialogDescription>
|
||||
<div class="mt-6 flex justify-end gap-2">
|
||||
<div class="mt-6 flex flex-wrap justify-end gap-2">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<textarea
|
||||
v-model="data"
|
||||
class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const data = defineModel<string>();
|
||||
</script>
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ApexOptions } from 'apexcharts';
|
||||
import type { ApexChart, ApexOptions } from 'apexcharts';
|
||||
|
||||
defineProps<{
|
||||
client: LocalClient;
|
||||
|
||||
@@ -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" />
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex flex-grow flex-col gap-1">
|
||||
<ClientCardName :client="client" />
|
||||
<div
|
||||
class="flex flex-col pb-1 text-xs text-gray-500 md:inline-block md:pb-0 dark:text-neutral-400"
|
||||
class="flex flex-col text-xs text-gray-500 dark:text-neutral-400"
|
||||
>
|
||||
<div>
|
||||
<ClientCardAddress :client="client" />
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
class="block pb-1 text-xs text-gray-500 md:inline-block md:pb-0 dark:text-neutral-400"
|
||||
>
|
||||
<div class="block text-xs text-gray-500 dark:text-neutral-400">
|
||||
<span class="inline-block">{{ expiredDateFormat(client.expiresAt) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
class="text-sm text-gray-700 md:text-base dark:text-neutral-200"
|
||||
class="break-all text-sm text-gray-700 md:text-base dark:text-neutral-200"
|
||||
:title="$t('client.createdOn') + $d(new Date(client.createdAt))"
|
||||
>
|
||||
<span class="border-b-2 border-t-2 border-transparent">
|
||||
{{ client.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -14,10 +14,11 @@ const props = defineProps<{ client: LocalClient }>();
|
||||
const clientsStore = useClientsStore();
|
||||
|
||||
const _showOneTimeLink = useSubmit(
|
||||
`/api/client/${props.client.id}/generateOneTimeLink`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/client/${props.client.id}/generateOneTimeLink`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
await clientsStore.refresh();
|
||||
|
||||
@@ -18,10 +18,11 @@ const enabled = ref(props.client.enabled);
|
||||
const clientsStore = useClientsStore();
|
||||
|
||||
const _disableClient = useSubmit(
|
||||
`/api/client/${props.client.id}/disable`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/client/${props.client.id}/disable`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
await clientsStore.refresh();
|
||||
@@ -31,10 +32,11 @@ const _disableClient = useSubmit(
|
||||
);
|
||||
|
||||
const _enableClient = useSubmit(
|
||||
`/api/client/${props.client.id}/enable`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/client/${props.client.id}/enable`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
await clientsStore.refresh();
|
||||
|
||||
@@ -43,10 +43,11 @@ function createClient() {
|
||||
}
|
||||
|
||||
const _createClient = useSubmit(
|
||||
'/api/client',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/client', {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: () => clientsStore.refresh(),
|
||||
successMsg: t('client.created'),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{ $t('client.empty') }}<br /><br />
|
||||
<ClientsCreateDialog>
|
||||
<BaseSecondaryButton as="span">
|
||||
<IconsPlus class="w-4 md:mr-2" />
|
||||
<IconsPlus class="mr-2 w-4" />
|
||||
<span class="text-sm">{{ $t('client.new') }}</span>
|
||||
</BaseSecondaryButton>
|
||||
</ClientsCreateDialog>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<ClientsCreateDialog>
|
||||
<BaseSecondaryButton as="span">
|
||||
<IconsPlus class="w-4 md:mr-2" />
|
||||
<span class="text-sm max-md:hidden">{{ $t('client.newShort') }}</span>
|
||||
<IconsPlus class="mr-2 w-4" />
|
||||
<span class="text-sm">{{ $t('client.newShort') }}</span>
|
||||
</BaseSecondaryButton>
|
||||
</ClientsCreateDialog>
|
||||
</template>
|
||||
|
||||
@@ -5,10 +5,24 @@
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="bg-white">
|
||||
<img :src="qrCode" />
|
||||
<img ref="img" :src="qrCode" />
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<BaseSecondaryButton
|
||||
class="flex items-center gap-2"
|
||||
:title="$t('client.copyPng')"
|
||||
@click="copyPng"
|
||||
>
|
||||
<IconsCopy class="size-5" /> PNG
|
||||
</BaseSecondaryButton>
|
||||
<BaseSecondaryButton
|
||||
class="flex items-center gap-2"
|
||||
:title="$t('client.downloadPng')"
|
||||
@click="downloadPng"
|
||||
>
|
||||
<IconsDownload class="size-5" /> PNG
|
||||
</BaseSecondaryButton>
|
||||
<DialogClose as-child>
|
||||
<BaseSecondaryButton>{{ $t('dialog.cancel') }}</BaseSecondaryButton>
|
||||
</DialogClose>
|
||||
@@ -18,4 +32,87 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ qrCode: string }>();
|
||||
|
||||
const toast = useToast();
|
||||
const img = useTemplateRef('img');
|
||||
|
||||
async function svgToPng() {
|
||||
if (!img.value || !img.value.complete || img.value.naturalWidth === 0) {
|
||||
throw new Error('image is not loaded');
|
||||
}
|
||||
|
||||
const width = 1000;
|
||||
const height = 1000;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) {
|
||||
throw new Error('was not able to create 2d context');
|
||||
}
|
||||
ctx.drawImage(img.value!, 0, 0, width, height);
|
||||
|
||||
return new Promise<Blob>((res, rej) => {
|
||||
canvas.toBlob((blob) => {
|
||||
if (!blob) {
|
||||
return rej(new Error('was not able to create blob'));
|
||||
}
|
||||
return res(blob);
|
||||
}, 'image/png');
|
||||
});
|
||||
}
|
||||
|
||||
async function downloadPng() {
|
||||
try {
|
||||
const blob = await svgToPng();
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'client-config.png';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
} catch (e) {
|
||||
console.error('failed to download png', e);
|
||||
toast.showToast({
|
||||
type: 'error',
|
||||
message: $t('toast.unknown'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function copyPng() {
|
||||
const blob = await svgToPng().catch((e) => {
|
||||
console.error('failed to convert svg to png', e);
|
||||
toast.showToast({
|
||||
type: 'error',
|
||||
message: $t('toast.unknown'),
|
||||
});
|
||||
});
|
||||
if (!blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
[blob.type]: blob,
|
||||
}),
|
||||
]);
|
||||
|
||||
toast.showToast({
|
||||
type: 'success',
|
||||
message: $t('copy.copied'),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('failed to copy png', e);
|
||||
toast.showToast({
|
||||
type: 'error',
|
||||
message: $t('copy.failed'),
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative w-60 md:mr-2">
|
||||
<div class="relative">
|
||||
<div class="relative flex h-full items-center">
|
||||
<IconsMagnifyingGlass
|
||||
class="absolute left-2.5 h-4 w-4 text-gray-400 dark:text-neutral-500"
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
<template>
|
||||
<BasePrimaryButton @click="toggleSort">
|
||||
<IconsArrowDown
|
||||
v-if="globalStore.sortClient === true"
|
||||
class="w-4 md:mr-2"
|
||||
/>
|
||||
<IconsArrowUp v-else class="w-4 md:mr-2" />
|
||||
<span class="text-sm max-md:hidden"> {{ $t('client.sort') }}</span>
|
||||
<IconsArrowDown v-if="globalStore.sortClient === true" class="mr-2 w-4" />
|
||||
<IconsArrowUp v-else class="mr-2 w-4" />
|
||||
<span class="text-sm">{{ $t('client.sort') }}</span>
|
||||
</BasePrimaryButton>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -12,23 +12,15 @@
|
||||
class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
|
||||
@input="update($event, i)"
|
||||
/>
|
||||
<BaseSecondaryButton
|
||||
as="input"
|
||||
type="button"
|
||||
class="rounded-lg"
|
||||
value="-"
|
||||
@click="del(i)"
|
||||
/>
|
||||
<BaseSecondaryButton type="button" class="rounded-lg" @click="del(i)">
|
||||
{{ '-' }}
|
||||
</BaseSecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<BasePrimaryButton
|
||||
as="input"
|
||||
type="button"
|
||||
class="rounded-lg"
|
||||
:value="$t('form.add')"
|
||||
@click="add"
|
||||
/>
|
||||
<BasePrimaryButton type="button" class="rounded-lg" @click="add">
|
||||
{{ $t('form.add') }}
|
||||
</BasePrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<h4 class="col-span-full flex items-center py-6 text-2xl">
|
||||
<h3 class="col-span-full flex items-center py-6 text-2xl">
|
||||
<slot />
|
||||
<BaseTooltip v-if="description" :text="description">
|
||||
<IconsInfo class="size-4" />
|
||||
</BaseTooltip>
|
||||
</h4>
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<RLabel :for="props.for" class="md:align-middle md:leading-10"
|
||||
><slot
|
||||
/></RLabel>
|
||||
<RLabel :for="props.for" class="md:leading-[2.75rem]">
|
||||
<slot />
|
||||
</RLabel>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -12,23 +12,15 @@
|
||||
class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
|
||||
@input="update($event, i)"
|
||||
/>
|
||||
<BaseSecondaryButton
|
||||
as="input"
|
||||
type="button"
|
||||
class="rounded-lg"
|
||||
value="-"
|
||||
@click="del(i)"
|
||||
/>
|
||||
<BaseSecondaryButton type="button" class="rounded-lg" @click="del(i)">
|
||||
{{ '-' }}
|
||||
</BaseSecondaryButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<BasePrimaryButton
|
||||
as="input"
|
||||
type="button"
|
||||
class="rounded-lg"
|
||||
:value="$t('form.add')"
|
||||
@click="add"
|
||||
/>
|
||||
<BasePrimaryButton type="button" class="rounded-lg" @click="add">
|
||||
{{ $t('form.add') }}
|
||||
</BasePrimaryButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
<IconsInfo class="size-4" />
|
||||
</BaseTooltip>
|
||||
</div>
|
||||
<div class="my-auto">
|
||||
<BaseSwitch :id="id" v-model="data" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<FormLabel :for="id">
|
||||
{{ label }}
|
||||
</FormLabel>
|
||||
<BaseTooltip v-if="description" :text="description">
|
||||
<IconsInfo class="size-4" />
|
||||
</BaseTooltip>
|
||||
</div>
|
||||
<BaseTextArea
|
||||
:id="id"
|
||||
v-model.trim="data"
|
||||
:name="id"
|
||||
:autocomplete="autocomplete"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
id: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
autocomplete?: string;
|
||||
disabled?: boolean;
|
||||
}>();
|
||||
|
||||
const data = defineModel<string>();
|
||||
</script>
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<Toggle
|
||||
:pressed="globalStore.uiShowCharts"
|
||||
class="group inline-flex h-8 w-8 cursor-pointer items-center justify-center whitespace-nowrap rounded-full bg-gray-200 transition hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600"
|
||||
class="group flex h-8 w-8 items-center justify-center rounded-full bg-gray-200 transition hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600"
|
||||
:title="$t('layout.toggleCharts')"
|
||||
@update:pressed="globalStore.toggleCharts"
|
||||
>
|
||||
<IconsChart
|
||||
class="h-5 w-5 fill-gray-400 transition group-data-[state=on]:fill-gray-600 dark:fill-neutral-600 dark:group-data-[state=on]:fill-neutral-400"
|
||||
class="h-5 w-5 transition group-data-[state=on]:fill-gray-600 dark:text-neutral-400 dark:group-data-[state=on]:fill-gray-300"
|
||||
/>
|
||||
</Toggle>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NuxtLink to="/" class="mb-4">
|
||||
<NuxtLink to="/" class="max-sm:mb-4">
|
||||
<h1 class="text-4xl font-medium dark:text-neutral-200">
|
||||
<img
|
||||
src="/logo.png"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
authStore.userData &&
|
||||
hasPermissions(authStore.userData, 'admin', 'any')
|
||||
"
|
||||
class="font-small mb-10 rounded-md bg-red-800 p-4 text-sm text-white shadow-lg dark:bg-red-100 dark:text-red-600"
|
||||
class="font-small rounded-md bg-red-800 p-4 text-sm text-white shadow-lg dark:bg-red-100 dark:text-red-600"
|
||||
:title="`v${globalStore.information.currentRelease} → v${globalStore.information.latestRelease.version}`"
|
||||
>
|
||||
<div class="container mx-auto flex flex-auto flex-row items-center">
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<ClipboardDocumentIcon />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ClipboardDocumentIcon from '@heroicons/vue/24/outline/esm/ClipboardDocumentIcon';
|
||||
</script>
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="container mx-auto max-w-3xl">
|
||||
<div
|
||||
class="container mx-auto max-w-3xl overflow-hidden rounded-lg bg-white px-3 text-gray-700 shadow-md md:px-0 dark:bg-neutral-700 dark:text-neutral-200"
|
||||
class="mx-3 overflow-hidden rounded-lg bg-white text-gray-700 shadow-md dark:bg-neutral-700 dark:text-neutral-200"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex flex-shrink-0 items-center space-x-2">
|
||||
<div class="flex flex-shrink-0 flex-col items-center gap-2 sm:flex-row">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-auto flex-grow flex-row items-center border-b-2 border-gray-100 p-3 px-5 dark:border-neutral-600"
|
||||
class="flex flex-col items-center gap-2 border-b-2 border-gray-100 p-3 px-5 sm:flex-row dark:border-neutral-600"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
<template>
|
||||
<h2 class="flex-1 text-2xl font-medium">
|
||||
{{ text }}
|
||||
<h2 class="flex-1 break-all text-2xl font-medium">
|
||||
<slot />
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { text } = defineProps<{
|
||||
text: string;
|
||||
}>();
|
||||
</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"
|
||||
|
||||
@@ -70,10 +70,11 @@ const authStore = useAuthStore();
|
||||
const toggleState = ref(false);
|
||||
|
||||
const _submit = useSubmit(
|
||||
'/api/session',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/session', {
|
||||
method: 'delete',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
await navigateTo('/login');
|
||||
|
||||
@@ -1,49 +1,24 @@
|
||||
import type {
|
||||
NitroFetchRequest,
|
||||
NitroFetchOptions,
|
||||
TypedInternalResponse,
|
||||
ExtractedRouteMethod,
|
||||
} from 'nitropack/types';
|
||||
import { FetchError } from 'ofetch';
|
||||
|
||||
type RevertFn<
|
||||
R extends NitroFetchRequest,
|
||||
T = unknown,
|
||||
O extends NitroFetchOptions<R> = NitroFetchOptions<R>,
|
||||
> = (
|
||||
success: boolean,
|
||||
data:
|
||||
| TypedInternalResponse<
|
||||
R,
|
||||
T,
|
||||
NitroFetchOptions<R> extends O ? 'get' : ExtractedRouteMethod<R, O>
|
||||
>
|
||||
| undefined
|
||||
) => Promise<void>;
|
||||
type RevertFn<T> = (success: boolean, data: T | undefined) => Promise<void>;
|
||||
|
||||
type SubmitOpts<
|
||||
R extends NitroFetchRequest,
|
||||
T = unknown,
|
||||
O extends NitroFetchOptions<R> = NitroFetchOptions<R>,
|
||||
> = {
|
||||
revert: RevertFn<R, T, O>;
|
||||
type SubmitOpts<T> = {
|
||||
revert: RevertFn<T>;
|
||||
successMsg?: string;
|
||||
noSuccessToast?: boolean;
|
||||
};
|
||||
|
||||
export function useSubmit<
|
||||
R extends NitroFetchRequest,
|
||||
O extends NitroFetchOptions<R> & { body?: never },
|
||||
T = unknown,
|
||||
>(url: R, options: O, opts: SubmitOpts<R, T, O>) {
|
||||
type Body = Record<string, unknown> | null | undefined;
|
||||
|
||||
export function useSubmit<T>(
|
||||
fetcher: (data: Body) => Promise<T>,
|
||||
opts: SubmitOpts<T>
|
||||
) {
|
||||
const toast = useToast();
|
||||
|
||||
return async (data: unknown) => {
|
||||
return async (data: Body) => {
|
||||
try {
|
||||
const res = await $fetch(url, {
|
||||
...options,
|
||||
body: data,
|
||||
});
|
||||
const res = await fetcher(data);
|
||||
|
||||
if (!opts.noSuccessToast) {
|
||||
toast.showToast({
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<header class="mx-auto mt-4 flex max-w-3xl flex-col justify-center">
|
||||
<header
|
||||
class="mx-auto my-4 flex max-w-3xl flex-col justify-center max-md:px-3"
|
||||
>
|
||||
<div
|
||||
class="mb-5 w-full"
|
||||
:class="
|
||||
@@ -17,7 +19,7 @@
|
||||
<UiUserMenu v-if="loggedIn" />
|
||||
</div>
|
||||
</div>
|
||||
<HeaderUpdate class="mt-4" />
|
||||
<HeaderUpdate class="my-4" />
|
||||
</header>
|
||||
<slot />
|
||||
<UiFooter />
|
||||
|
||||
+19
-7
@@ -2,13 +2,18 @@
|
||||
<div>
|
||||
<div class="container mx-auto p-4">
|
||||
<div class="flex flex-col gap-4 lg:flex-row">
|
||||
<div class="rounded-lg bg-white p-4 lg:w-64 dark:bg-neutral-700">
|
||||
<div
|
||||
class="overflow-hidden rounded-lg bg-white text-gray-700 shadow-md lg:w-64 dark:bg-neutral-700 dark:text-neutral-200"
|
||||
>
|
||||
<PanelHead>
|
||||
<PanelHeadTitle>
|
||||
<NuxtLink to="/admin">
|
||||
<h2 class="mb-4 text-xl font-bold dark:text-neutral-200">
|
||||
{{ t('pages.admin.panel') }}
|
||||
</h2>
|
||||
</NuxtLink>
|
||||
<div class="flex flex-col space-y-2">
|
||||
</PanelHeadTitle>
|
||||
</PanelHead>
|
||||
<PanelBody>
|
||||
<nav class="flex flex-col gap-2">
|
||||
<NuxtLink
|
||||
v-for="(item, index) in menuItems"
|
||||
:key="index"
|
||||
@@ -23,14 +28,21 @@
|
||||
{{ item.name }}
|
||||
</BaseSecondaryButton>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</nav>
|
||||
</PanelBody>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex-1 rounded-lg bg-white p-6 dark:bg-neutral-700 dark:text-neutral-200"
|
||||
class="flex-1 overflow-hidden rounded-lg bg-white text-gray-700 shadow-md dark:bg-neutral-700 dark:text-neutral-200"
|
||||
>
|
||||
<h1 class="mb-6 text-3xl font-bold">{{ activeMenuItem.name }}</h1>
|
||||
<PanelHead>
|
||||
<PanelHeadTitle>
|
||||
{{ activeMenuItem.name }}
|
||||
</PanelHeadTitle>
|
||||
</PanelHead>
|
||||
<PanelBody>
|
||||
<NuxtPage />
|
||||
</PanelBody>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -121,10 +121,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/userconfig`, {
|
||||
const data = toRef(_data.value);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/admin/userconfig`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/userconfig`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{ revert }
|
||||
);
|
||||
|
||||
|
||||
@@ -46,10 +46,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/general`, {
|
||||
const data = toRef(_data.value);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/admin/general`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/general`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{ revert }
|
||||
);
|
||||
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
<main v-if="data">
|
||||
<FormElement @submit.prevent="submit">
|
||||
<FormGroup>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PreUp"
|
||||
v-model="data.preUp"
|
||||
:label="$t('hooks.preUp')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PostUp"
|
||||
v-model="data.postUp"
|
||||
:label="$t('hooks.postUp')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PreDown"
|
||||
v-model="data.preDown"
|
||||
:label="$t('hooks.preDown')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PostDown"
|
||||
v-model="data.postDown"
|
||||
:label="$t('hooks.postDown')"
|
||||
@@ -40,10 +40,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/hooks`, {
|
||||
const data = toRef(_data.value);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/admin/hooks`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/hooks`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{ revert }
|
||||
);
|
||||
|
||||
|
||||
@@ -69,6 +69,30 @@
|
||||
:label="$t('awg.s4Label')"
|
||||
:description="$t('awg.s4Description')"
|
||||
/>
|
||||
<FormNullTextField
|
||||
id="h1"
|
||||
v-model="data.h1"
|
||||
:label="$t('awg.h1Label')"
|
||||
:description="$t('awg.h1Description')"
|
||||
/>
|
||||
<FormNullTextField
|
||||
id="h2"
|
||||
v-model="data.h2"
|
||||
:label="$t('awg.h2Label')"
|
||||
:description="$t('awg.h2Description')"
|
||||
/>
|
||||
<FormNullTextField
|
||||
id="h3"
|
||||
v-model="data.h3"
|
||||
:label="$t('awg.h3Label')"
|
||||
:description="$t('awg.h3Description')"
|
||||
/>
|
||||
<FormNullTextField
|
||||
id="h4"
|
||||
v-model="data.h4"
|
||||
:label="$t('awg.h4Label')"
|
||||
:description="$t('awg.h4Description')"
|
||||
/>
|
||||
<FormNullTextField
|
||||
id="i1"
|
||||
v-model="data.i1"
|
||||
@@ -99,29 +123,14 @@
|
||||
:label="$t('awg.i5Label')"
|
||||
:description="$t('awg.i5Description')"
|
||||
/>
|
||||
<FormNullNumberField
|
||||
id="h1"
|
||||
v-model="data.h1"
|
||||
:label="$t('awg.h1Label')"
|
||||
:description="$t('awg.h1Description')"
|
||||
/>
|
||||
<FormNullNumberField
|
||||
id="h2"
|
||||
v-model="data.h2"
|
||||
:label="$t('awg.h2Label')"
|
||||
:description="$t('awg.h2Description')"
|
||||
/>
|
||||
<FormNullNumberField
|
||||
id="h3"
|
||||
v-model="data.h3"
|
||||
:label="$t('awg.h3Label')"
|
||||
:description="$t('awg.h3Description')"
|
||||
/>
|
||||
<FormNullNumberField
|
||||
id="h4"
|
||||
v-model="data.h4"
|
||||
:label="$t('awg.h4Label')"
|
||||
:description="$t('awg.h4Description')"
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormHeading>{{ $t('admin.interface.firewall') }}</FormHeading>
|
||||
<FormSwitchField
|
||||
id="firewallEnabled"
|
||||
v-model="data.firewallEnabled"
|
||||
:label="$t('admin.interface.firewallEnabled')"
|
||||
:description="$t('admin.interface.firewallEnabledDesc')"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
@@ -167,11 +176,20 @@ const { data: _data, refresh } = await useFetch(`/api/admin/interface`, {
|
||||
const data = toRef(_data.value);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/admin/interface`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/interface`, {
|
||||
method: 'post',
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success) => {
|
||||
await revert();
|
||||
if (success) {
|
||||
// Refresh global store information after successful save
|
||||
await globalStore.refreshInformation();
|
||||
}
|
||||
},
|
||||
{ revert }
|
||||
}
|
||||
);
|
||||
|
||||
function submit() {
|
||||
@@ -184,10 +202,11 @@ async function revert() {
|
||||
}
|
||||
|
||||
const _changeCidr = useSubmit(
|
||||
`/api/admin/interface/cidr`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/interface/cidr`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert,
|
||||
successMsg: t('admin.interface.cidrSuccess'),
|
||||
@@ -199,10 +218,11 @@ async function changeCidr(ipv4Cidr: string, ipv6Cidr: string) {
|
||||
}
|
||||
|
||||
const _restartInterface = useSubmit(
|
||||
`/api/admin/interface/restart`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/admin/interface/restart`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert,
|
||||
successMsg: t('admin.interface.restartSuccess'),
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<main v-if="data">
|
||||
<Panel>
|
||||
<PanelHead>
|
||||
<PanelHeadTitle :text="data.name" />
|
||||
<PanelHeadTitle>
|
||||
{{ data.name }}
|
||||
</PanelHeadTitle>
|
||||
</PanelHead>
|
||||
<PanelBody>
|
||||
<FormElement @submit.prevent="submit">
|
||||
@@ -61,6 +63,12 @@
|
||||
name="serverAllowedIps"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup v-if="globalStore.information?.firewallEnabled">
|
||||
<FormHeading :description="$t('client.firewallIpsDesc')">
|
||||
{{ $t('client.firewallIps') }}
|
||||
</FormHeading>
|
||||
<FormNullArrayField v-model="data.firewallIps" name="firewallIps" />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormHeading :description="$t('client.dnsDesc')">
|
||||
{{ $t('general.dns') }}
|
||||
@@ -141,25 +149,25 @@
|
||||
<FormHeading :description="$t('client.hooksDescription')">
|
||||
{{ $t('client.hooks') }}
|
||||
</FormHeading>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PreUp"
|
||||
v-model="data.preUp"
|
||||
:description="$t('client.hooksLeaveEmpty')"
|
||||
:label="$t('hooks.preUp')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PostUp"
|
||||
v-model="data.postUp"
|
||||
:description="$t('client.hooksLeaveEmpty')"
|
||||
:label="$t('hooks.postUp')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PreDown"
|
||||
v-model="data.preDown"
|
||||
:description="$t('client.hooksLeaveEmpty')"
|
||||
:label="$t('hooks.preDown')"
|
||||
/>
|
||||
<FormTextField
|
||||
<FormTextArea
|
||||
id="PostDown"
|
||||
v-model="data.postDown"
|
||||
:description="$t('client.hooksLeaveEmpty')"
|
||||
@@ -217,10 +225,11 @@ const { data: _data, refresh } = await useFetch(`/api/client/${id}`, {
|
||||
const data = toRef(_data.value);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/client/${id}`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/client/${id}`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success) => {
|
||||
if (success) {
|
||||
@@ -242,10 +251,11 @@ async function revert() {
|
||||
}
|
||||
|
||||
const _deleteClient = useSubmit(
|
||||
`/api/client/${id}`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/client/${id}`, {
|
||||
method: 'delete',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
await navigateTo('/');
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
<main>
|
||||
<Panel>
|
||||
<PanelHead>
|
||||
<PanelHeadTitle :text="$t('pages.clients')" />
|
||||
<PanelHeadTitle>
|
||||
{{ $t('pages.clients') }}
|
||||
</PanelHeadTitle>
|
||||
<PanelHeadBoat>
|
||||
<ClientsSearch />
|
||||
<div class="flex gap-2">
|
||||
<ClientsSort />
|
||||
<ClientsNew />
|
||||
</div>
|
||||
</PanelHeadBoat>
|
||||
</PanelHead>
|
||||
|
||||
|
||||
@@ -78,10 +78,11 @@ const totpRequired = ref(false);
|
||||
const totp = ref<string>('');
|
||||
|
||||
const _submit = useSubmit(
|
||||
'/api/session',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/session', {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success, data) => {
|
||||
if (success) {
|
||||
|
||||
+23
-16
@@ -2,7 +2,9 @@
|
||||
<main>
|
||||
<Panel>
|
||||
<PanelHead>
|
||||
<PanelHeadTitle :text="$t('pages.me')" />
|
||||
<PanelHeadTitle>
|
||||
{{ $t('pages.me') }}
|
||||
</PanelHeadTitle>
|
||||
</PanelHead>
|
||||
<PanelBody class="dark:text-neutral-200">
|
||||
<FormElement @submit.prevent="submit">
|
||||
@@ -125,10 +127,11 @@ const name = ref(authStore.userData?.name);
|
||||
const email = ref(authStore.userData?.email);
|
||||
|
||||
const _submit = useSubmit(
|
||||
`/api/me`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/me`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: () => {
|
||||
return authStore.update();
|
||||
@@ -145,10 +148,11 @@ const newPassword = ref('');
|
||||
const confirmPassword = ref('');
|
||||
|
||||
const _updatePassword = useSubmit(
|
||||
`/api/me/password`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/me/password`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async () => {
|
||||
currentPassword.value = '';
|
||||
@@ -169,10 +173,11 @@ function updatePassword() {
|
||||
const twofa = ref<{ key: string; qrcode: string } | null>(null);
|
||||
|
||||
const _setup2fa = useSubmit(
|
||||
`/api/me/totp`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/me/totp`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success, data) => {
|
||||
if (success && data?.type === 'setup') {
|
||||
@@ -197,10 +202,11 @@ async function setup2fa() {
|
||||
const code = ref<string>('');
|
||||
|
||||
const _enable2fa = useSubmit(
|
||||
`/api/me/totp`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/me/totp`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success, data) => {
|
||||
if (success && data?.type === 'created') {
|
||||
@@ -222,10 +228,11 @@ async function enable2fa() {
|
||||
const disable2faPassword = ref('');
|
||||
|
||||
const _disable2fa = useSubmit(
|
||||
`/api/me/totp`,
|
||||
{
|
||||
(data) =>
|
||||
$fetch(`/api/me/totp`, {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success, data) => {
|
||||
if (success && data?.type === 'deleted') {
|
||||
|
||||
@@ -50,10 +50,11 @@ const password = ref<string>('');
|
||||
const confirmPassword = ref<string>('');
|
||||
|
||||
const _submit = useSubmit(
|
||||
'/api/setup/2',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/setup/2', {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success) => {
|
||||
if (success) {
|
||||
|
||||
@@ -43,10 +43,11 @@ const host = ref<null | string>(null);
|
||||
const port = ref<number>(51820);
|
||||
|
||||
const _submit = useSubmit(
|
||||
'/api/setup/4',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/setup/4', {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success) => {
|
||||
if (success) {
|
||||
|
||||
@@ -36,10 +36,11 @@ function onChangeFile(evt: Event) {
|
||||
}
|
||||
|
||||
const _submit = useSubmit(
|
||||
'/api/setup/migrate',
|
||||
{
|
||||
(data) =>
|
||||
$fetch('/api/setup/migrate', {
|
||||
method: 'post',
|
||||
},
|
||||
body: data,
|
||||
}),
|
||||
{
|
||||
revert: async (success) => {
|
||||
if (success) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
export const useGlobalStore = defineStore('Global', () => {
|
||||
const { data: information } = useFetch('/api/information', {
|
||||
const { data: information, refresh: refreshInformation } = useFetch(
|
||||
'/api/information',
|
||||
{
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const sortClient = ref(true); // Sort clients by name, true = asc, false = desc
|
||||
|
||||
@@ -22,6 +25,7 @@ export const useGlobalStore = defineStore('Global', () => {
|
||||
return {
|
||||
sortClient,
|
||||
information,
|
||||
refreshInformation,
|
||||
uiShowCharts,
|
||||
toggleCharts,
|
||||
uiChartType,
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { defineCommand } from 'citty';
|
||||
import { consola } from 'consola';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import { db, schema } from '../db';
|
||||
import { hashPassword } from '../../server/utils/password';
|
||||
|
||||
export default defineCommand({
|
||||
meta: {
|
||||
name: 'db:admin:reset',
|
||||
description: 'Reset the admin user password and TOTP settings',
|
||||
},
|
||||
args: {
|
||||
password: {
|
||||
type: 'string',
|
||||
description: 'New password for the admin user',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
async run(ctx) {
|
||||
let password = ctx.args.password || undefined;
|
||||
if (!password) {
|
||||
password = await consola.prompt('Please enter a new password:', {
|
||||
type: 'text',
|
||||
});
|
||||
}
|
||||
if (!password) {
|
||||
consola.error('Password is required');
|
||||
return;
|
||||
}
|
||||
if (password.length < 12) {
|
||||
consola.error('Password must be at least 12 characters long');
|
||||
return;
|
||||
}
|
||||
consola.info('Setting new password for admin user...');
|
||||
const hash = await hashPassword(password);
|
||||
|
||||
const user = await db.transaction(async (tx) => {
|
||||
const user = await tx
|
||||
.select()
|
||||
.from(schema.user)
|
||||
.where(eq(schema.user.id, 1))
|
||||
.get();
|
||||
|
||||
if (!user) {
|
||||
consola.error('Admin user not found');
|
||||
return;
|
||||
}
|
||||
|
||||
await tx
|
||||
.update(schema.user)
|
||||
.set({
|
||||
password: hash,
|
||||
totpVerified: false,
|
||||
totpKey: null,
|
||||
})
|
||||
.where(eq(schema.user.id, 1));
|
||||
|
||||
return user;
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
consola.error('Failed to update admin user');
|
||||
return;
|
||||
}
|
||||
|
||||
consola.success(
|
||||
`Successfully updated admin user ${user.id} (${user.username})`
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { defineCommand } from 'citty';
|
||||
import { consola } from 'consola';
|
||||
|
||||
import { db } from '../db';
|
||||
|
||||
export default defineCommand({
|
||||
meta: {
|
||||
name: 'clients:list',
|
||||
description: 'List all clients',
|
||||
},
|
||||
async run() {
|
||||
consola.info('Listing all clients...');
|
||||
const clients = await db.query.client.findMany({
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
publicKey: true,
|
||||
enabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (clients.length === 0) {
|
||||
consola.info('No clients found');
|
||||
return;
|
||||
}
|
||||
|
||||
console.table(clients);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { defineCommand } from 'citty';
|
||||
import { consola } from 'consola';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import { wg } from '../../server/utils/wgHelper';
|
||||
import { encodeQRCodeTerm } from '../../server/utils/qr';
|
||||
import { db, schema } from '../db';
|
||||
|
||||
export default defineCommand({
|
||||
meta: {
|
||||
name: 'clients:qr',
|
||||
description: 'Generate QR code for a client',
|
||||
},
|
||||
args: {
|
||||
id: {
|
||||
required: true,
|
||||
type: 'positional',
|
||||
},
|
||||
ipv6: {
|
||||
required: false,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
async run(ctx) {
|
||||
const clientId = Number(ctx.args.id);
|
||||
const enableIpv6 = ctx.args.ipv6;
|
||||
|
||||
if (Number.isNaN(clientId)) {
|
||||
consola.error('Invalid client ID');
|
||||
return;
|
||||
}
|
||||
|
||||
consola.info('Generating QR code for client...');
|
||||
|
||||
const wgInterface = await db.query.wgInterface.findFirst({
|
||||
where: eq(schema.wgInterface.name, 'wg0'),
|
||||
});
|
||||
if (!wgInterface) {
|
||||
consola.error('WireGuard interface not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const userConfig = await db.query.userConfig.findFirst({
|
||||
where: eq(schema.userConfig.id, 'wg0'),
|
||||
});
|
||||
if (!userConfig) {
|
||||
consola.error('User config not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const client = await db.query.client.findFirst({
|
||||
where: eq(schema.client.id, clientId),
|
||||
});
|
||||
if (!client) {
|
||||
consola.error(`Client with ID ${clientId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
const clientConfig = wg.generateClientConfig(
|
||||
wgInterface,
|
||||
userConfig,
|
||||
client,
|
||||
{
|
||||
enableIpv6,
|
||||
}
|
||||
);
|
||||
|
||||
consola.log(encodeQRCodeTerm(clientConfig));
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createClient } from '@libsql/client';
|
||||
import { drizzle } from 'drizzle-orm/libsql';
|
||||
|
||||
import * as schema from '../server/database/schema';
|
||||
|
||||
//const client = createClient({ url: 'file:../data/wg-easy.db' });
|
||||
const client = createClient({ url: 'file:/etc/wireguard/wg-easy.db' });
|
||||
export const db = drizzle({ client, schema });
|
||||
|
||||
export { schema };
|
||||
+24
-70
@@ -1,82 +1,38 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// ! Auto Imports are not supported in this file
|
||||
|
||||
import { drizzle } from 'drizzle-orm/libsql';
|
||||
import { createClient } from '@libsql/client';
|
||||
import type { Resolvable, SubCommandsDef } from 'citty';
|
||||
import { defineCommand, runMain } from 'citty';
|
||||
import { consola } from 'consola';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import packageJson from '../package.json';
|
||||
import * as schema from '../server/database/schema';
|
||||
import { hashPassword } from '../server/utils/password';
|
||||
|
||||
const client = createClient({ url: 'file:/etc/wireguard/wg-easy.db' });
|
||||
const db = drizzle({ client, schema });
|
||||
// Commands
|
||||
import dbAdminReset from './admin/reset';
|
||||
import clientsList from './clients/list';
|
||||
import clientsQr from './clients/qr';
|
||||
const subCommands = [dbAdminReset, clientsList, clientsQr] as const;
|
||||
|
||||
const dbAdminReset = defineCommand({
|
||||
meta: {
|
||||
name: 'db:admin:reset',
|
||||
description: 'Reset the admin user',
|
||||
},
|
||||
args: {
|
||||
password: {
|
||||
type: 'string',
|
||||
description: 'New password for the admin user',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
async run(ctx) {
|
||||
let password = ctx.args.password || undefined;
|
||||
if (!password) {
|
||||
password = await consola.prompt('Please enter a new password:', {
|
||||
type: 'text',
|
||||
});
|
||||
}
|
||||
if (!password) {
|
||||
consola.error('Password is required');
|
||||
return;
|
||||
}
|
||||
if (password.length < 12) {
|
||||
consola.error('Password must be at least 12 characters long');
|
||||
return;
|
||||
}
|
||||
console.info('Setting new password for admin user...');
|
||||
const hash = await hashPassword(password);
|
||||
|
||||
const user = await db.transaction(async (tx) => {
|
||||
const user = await tx
|
||||
.select()
|
||||
.from(schema.user)
|
||||
.where(eq(schema.user.id, 1))
|
||||
.get();
|
||||
|
||||
if (!user) {
|
||||
consola.error('Admin user not found');
|
||||
return;
|
||||
// from citty
|
||||
function resolveValue<T>(input: Resolvable<T>): T | Promise<T> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return typeof input === 'function' ? (input as any)() : input;
|
||||
}
|
||||
|
||||
await tx
|
||||
.update(schema.user)
|
||||
.set({
|
||||
password: hash,
|
||||
})
|
||||
.where(eq(schema.user.id, 1));
|
||||
async function generateSubCommands(): Promise<SubCommandsDef> {
|
||||
const subCommandsMap: Record<string, SubCommandsDef[string]> = {};
|
||||
|
||||
return user;
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
consola.error('Failed to update admin user');
|
||||
return;
|
||||
for (const cmd of subCommands) {
|
||||
const cmdMeta = await resolveValue(cmd.meta || {});
|
||||
if (!cmdMeta.name) {
|
||||
console.warn('Skipping command without name:', cmd);
|
||||
continue;
|
||||
}
|
||||
subCommandsMap[cmdMeta.name] = cmd;
|
||||
}
|
||||
|
||||
consola.success(
|
||||
`Successfully updated admin user ${user.id} (${user.username})`
|
||||
);
|
||||
},
|
||||
});
|
||||
return subCommandsMap;
|
||||
}
|
||||
|
||||
const subCommandsMap = await generateSubCommands();
|
||||
|
||||
const main = defineCommand({
|
||||
meta: {
|
||||
@@ -84,9 +40,7 @@ const main = defineCommand({
|
||||
version: packageJson.version,
|
||||
description: 'Command Line Interface',
|
||||
},
|
||||
subCommands: {
|
||||
'db:admin:reset': dbAdminReset,
|
||||
},
|
||||
subCommands: subCommandsMap,
|
||||
});
|
||||
|
||||
runMain(main);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"module": "esnext",
|
||||
"target": "es2024",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import uk from './locales/uk.json';
|
||||
import fr from './locales/fr.json';
|
||||
import de from './locales/de.json';
|
||||
import it from './locales/it.json';
|
||||
import ja from './locales/ja.json';
|
||||
import ru from './locales/ru.json';
|
||||
import zhhk from './locales/zh-HK.json';
|
||||
import zhcn from './locales/zh-CN.json';
|
||||
@@ -14,6 +15,13 @@ 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 hi from './locales/hi.json';
|
||||
import gl from './locales/gl.json';
|
||||
import cs from './locales/cs.json';
|
||||
import vi from './locales/vi.json';
|
||||
|
||||
export default defineI18nConfig(() => ({
|
||||
legacy: false,
|
||||
@@ -25,6 +33,7 @@ export default defineI18nConfig(() => ({
|
||||
fr,
|
||||
de,
|
||||
it,
|
||||
ja,
|
||||
ru,
|
||||
'zh-HK': zhhk,
|
||||
'zh-CN': zhcn,
|
||||
@@ -35,5 +44,12 @@ export default defineI18nConfig(() => ({
|
||||
tr,
|
||||
bn,
|
||||
id,
|
||||
nl,
|
||||
nb,
|
||||
bg,
|
||||
hi,
|
||||
gl,
|
||||
cs,
|
||||
vi,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -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 в транспортния пакет",
|
||||
"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)",
|
||||
"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...>",
|
||||
"mtuNote": "Стойностите зависят от MTU",
|
||||
"obfuscationParameters": "Параметри за обфускация на AmneziaWG"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Účet",
|
||||
"clients": "Klienti",
|
||||
"admin": {
|
||||
"panel": "Administrace",
|
||||
"general": "Obecné",
|
||||
"config": "Konfigurace",
|
||||
"interface": "Rozhraní",
|
||||
"hooks": "Nastavení reakcí"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "E-mail"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Aktuální heslo",
|
||||
"enable2fa": "Zapnout dvoufázové ověření (2FA)",
|
||||
"enable2faDesc": "Naskenujte QR kód ve své autentizační aplikaci nebo zadejte klíč ručně.",
|
||||
"2faKey": "TOTP klíč",
|
||||
"2faCodeDesc": "Zadejte kód z vaší autentizační aplikace.",
|
||||
"disable2fa": "Vypnout dvoufázové ověření",
|
||||
"disable2faDesc": "Pro vypnutí dvoufázového ověření zadejte své heslo."
|
||||
},
|
||||
"general": {
|
||||
"name": "Jméno",
|
||||
"username": "Uživatelské jméno",
|
||||
"password": "Heslo",
|
||||
"newPassword": "Nové heslo",
|
||||
"updatePassword": "Aktualizovat heslo",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Povolené IP adresy",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Persistent Keepalive",
|
||||
"logout": "Odhlásit se",
|
||||
"continue": "Pokračovat",
|
||||
"host": "Hostitel",
|
||||
"port": "Port",
|
||||
"yes": "Ano",
|
||||
"no": "Ne",
|
||||
"confirmPassword": "Potvrdit heslo",
|
||||
"loading": "Načítání...",
|
||||
"2fa": "Dvoufázové ověření",
|
||||
"2faCode": "TOTP kód"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Vítejte u první instalace wg-easy",
|
||||
"welcomeDesc": "Našli jste nejjednodušší způsob, jak instalovat a spravovat WireGuard na jakémkoliv Linuxovém hostiteli",
|
||||
"existingSetup": "Máte již existující nastavení?",
|
||||
"createAdminDesc": "Nejprve zadejte uživatelské jméno administrátora a silné heslo. Tyto údaje budou použity pro přihlášení do administrace.",
|
||||
"setupConfigDesc": "Zadejte údaje o hostiteli a portu. Tyto informace budou použity pro konfiguraci klientů při nastavování WireGuard na jejich zařízeních.",
|
||||
"setupMigrationDesc": "Pokud chcete migrovat data z předchozí verze wg-easy do nové instalace, nahrajte soubor se zálohou.",
|
||||
"upload": "Nahrát",
|
||||
"migration": "Obnovit zálohu:",
|
||||
"createAccount": "Vytvořit účet",
|
||||
"successful": "Nastavení bylo úspěšné",
|
||||
"hostDesc": "Veřejný název hostitele, ke kterému se budou klienti připojovat",
|
||||
"portDesc": "Veřejný UDP port, ke kterému se budou klienti připojovat a na kterém bude WireGuard naslouchat"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Je k dispozici aktualizace!",
|
||||
"update": "Aktualizovat"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Tmavý režim",
|
||||
"light": "Světlý režim",
|
||||
"system": "Systémové nastavení"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Zobrazit/skrýt grafy",
|
||||
"donate": "Přispět"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Přihlásit se",
|
||||
"rememberMe": "Zapamatovat si mě",
|
||||
"rememberMeDesc": "Zůstat přihlášen i po zavření prohlížeče",
|
||||
"insecure": "Nemůžete se přihlásit přes nezabezpečené připojení. Použijte HTTPS.",
|
||||
"2faRequired": "Je vyžadováno dvoufázové ověření",
|
||||
"2faWrong": "Neplatný kód dvoufázového ověření"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Zatím zde nejsou žádní klienti.",
|
||||
"newShort": "Nový",
|
||||
"sort": "Seřadit",
|
||||
"create": "Vytvořit klienta",
|
||||
"created": "Klient vytvořen",
|
||||
"new": "Nový klient",
|
||||
"name": "Jméno",
|
||||
"expireDate": "Datum vypršení",
|
||||
"expireDateDesc": "Datum, kdy bude klient deaktivován. Ponechte prázdné pro trvalý přístup.",
|
||||
"delete": "Smazat",
|
||||
"deleteClient": "Smazat klienta",
|
||||
"deleteDialog1": "Opravdu chcete smazat uživatele",
|
||||
"deleteDialog2": "Tuto akci nelze vzít zpět.",
|
||||
"enabled": "Aktivní",
|
||||
"address": "Adresa",
|
||||
"serverAllowedIps": "Povolené IP adresy serveru",
|
||||
"otlDesc": "Generovat krátký jednorázový odkaz",
|
||||
"permanent": "Trvalý",
|
||||
"createdOn": "Vytvořeno dne ",
|
||||
"lastSeen": "Naposledy viděn ",
|
||||
"totalDownload": "Celkem staženo: ",
|
||||
"totalUpload": "Celkem nahráno: ",
|
||||
"newClient": "Nový klient",
|
||||
"disableClient": "Deaktivovat klienta",
|
||||
"enableClient": "Aktivovat klienta",
|
||||
"noPrivKey": "Tento klient nemá známý soukromý klíč. Nelze vytvořit konfiguraci.",
|
||||
"showQR": "Zobrazit QR kód",
|
||||
"downloadConfig": "Stáhnout konfiguraci",
|
||||
"allowedIpsDesc": "Které IP adresy budou směrovány přes VPN (přebíjí globální nastavení)",
|
||||
"serverAllowedIpsDesc": "Které IP adresy bude server směrovat ke klientovi",
|
||||
"mtuDesc": "Nastavuje maximální velikost přenášeného paketu (MTU) pro VPN tunel",
|
||||
"persistentKeepaliveDesc": "Nastavuje interval (v sekundách) pro udržovací pakety. 0 pro vypnutí",
|
||||
"hooks": "Hooky",
|
||||
"hooksDescription": "Hooky fungují pouze s wg-quick",
|
||||
"hooksLeaveEmpty": "Pouze pro wg-quick. Jinak ponechte prázdné",
|
||||
"dnsDesc": "DNS server, který budou klienti používat (přebíjí globální nastavení)",
|
||||
"notConnected": "Klient není připojen",
|
||||
"endpoint": "Koncový bod",
|
||||
"endpointDesc": "IP adresa klienta, ze které je navázáno spojení WireGuard",
|
||||
"search": "Hledat klienty...",
|
||||
"config": "Konfigurace",
|
||||
"viewConfig": "Zobrazit konfiguraci"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Změnit",
|
||||
"cancel": "Zrušit",
|
||||
"create": "Vytvořit"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Úspěch",
|
||||
"saved": "Uloženo",
|
||||
"error": "Chyba"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Akce",
|
||||
"save": "Uložit",
|
||||
"revert": "Vrátit změny",
|
||||
"sectionGeneral": "Obecné",
|
||||
"sectionAdvanced": "Pokročilé",
|
||||
"noItems": "Žádné položky",
|
||||
"nullNoItems": "Žádné položky. Používá se globální konfigurace",
|
||||
"add": "Přidat"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Vypršení relace",
|
||||
"sessionTimeoutDesc": "Doba trvání relace pro 'Zapamatovat si mě' (sekundy)",
|
||||
"metrics": "Metriky",
|
||||
"metricsPassword": "Heslo",
|
||||
"metricsPasswordDesc": "Bearer heslo pro koncový bod metrik (heslo nebo argon2 hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Cesta pro metriky ve formátu JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Cesta pro metriky Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Připojení",
|
||||
"hostDesc": "Veřejný název hostitele, ke kterému se klienti připojují (zneplatní stávající konfigurace)",
|
||||
"portDesc": "Veřejný UDP port, ke kterému se klienti připojují (zneplatní stávající konfigurace, pravděpodobně budete chtít změnit i Port rozhraní)",
|
||||
"allowedIpsDesc": "Povolené IP adresy, které budou klienti používat (globální nastavení)",
|
||||
"dnsDesc": "DNS server, který budou klienti používat (globální nastavení)",
|
||||
"mtuDesc": "MTU, které budou klienti používat (pouze pro nové klienty)",
|
||||
"persistentKeepaliveDesc": "Interval v sekundách pro odesílání udržovacích paketů na server. 0 = vypnuto (pouze pro nové klienty)",
|
||||
"suggest": "Navrhnout",
|
||||
"suggestDesc": "Vyberte IP adresu nebo název hostitele pro pole Hostitel"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR změněn",
|
||||
"device": "Zařízení",
|
||||
"deviceDesc": "Ethernetové zařízení, přes které má být provoz WireGuard přeposílán",
|
||||
"mtuDesc": "MTU, které bude WireGuard používat",
|
||||
"portDesc": "UDP port, na kterém bude WireGuard naslouchat (pravděpodobně budete chtít změnit i Konfigurační port)",
|
||||
"changeCidr": "Změnit CIDR",
|
||||
"restart": "Restartovat rozhraní",
|
||||
"restartDesc": "Restartovat rozhraní WireGuard",
|
||||
"restartWarn": "Opravdu chcete restartovat rozhraní? Dojde k odpojení všech klientů.",
|
||||
"restartSuccess": "Rozhraní bylo restartováno"
|
||||
},
|
||||
"introText": "Vítejte v administraci.\n\nZde můžete spravovat obecná nastavení, konfiguraci, nastavení rozhraní a hooky.\n\nZačněte výběrem jedné ze sekcí v bočním panelu."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "Pole {0} je povinné",
|
||||
"validNumber": "{0} musí být platné číslo",
|
||||
"validNumberRange": "{0} musí být platné číslo nebo rozsah čísel",
|
||||
"validString": "{0} musí být platný řetězec",
|
||||
"validBoolean": "{0} musí být platná logická hodnota",
|
||||
"validArray": "{0} musí být platné pole",
|
||||
"stringMin": "{0} musí mít alespoň {1} znak(ů)",
|
||||
"numberMin": "{0} musí být alespoň {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID klienta",
|
||||
"name": "Jméno",
|
||||
"expiresAt": "Vyprší dne",
|
||||
"address4": "IPv4 adresa",
|
||||
"address6": "IPv6 adresa",
|
||||
"serverAllowedIps": "Povolené IP adresy serveru"
|
||||
},
|
||||
"user": {
|
||||
"username": "Uživatelské jméno",
|
||||
"password": "Heslo",
|
||||
"remember": "Pamatovat si",
|
||||
"name": "Jméno",
|
||||
"email": "E-mail",
|
||||
"emailInvalid": "E-mail musí být platná e-mailová adresa",
|
||||
"passwordMatch": "Hesla se musí shodovat",
|
||||
"totpEnable": "Zapnout TOTP",
|
||||
"totpEnableTrue": "Zapnutí TOTP musí být potvrzeno",
|
||||
"totpCode": "TOTP kód"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Hostitel"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Vypršení relace",
|
||||
"metricsEnabled": "Metriky",
|
||||
"metricsPassword": "Heslo k metrikám"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Zařízení",
|
||||
"cidrValid": "CIDR musí být platný"
|
||||
},
|
||||
"otl": "Jednorázový odkaz",
|
||||
"stringMalformed": "Řetězec má nesprávný formát",
|
||||
"body": "Tělo požadavku musí být platný objekt",
|
||||
"hook": "Hook",
|
||||
"enabled": "Aktivní",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Persistent Keepalive",
|
||||
"address": "IP adresa",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Povolené IP adresy",
|
||||
"file": "Soubor"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopírování není podporováno",
|
||||
"copied": "Zkopírováno!",
|
||||
"failed": "Kopírování selhalo",
|
||||
"copy": "Kopírovat"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Počet junk paketů (Jc)",
|
||||
"jCDescription": "Počet odesílaných junk paketů (1-128, doporučeno: 4-12)",
|
||||
"jMinLabel": "Min. velikost junk paketu (Jmin)",
|
||||
"jMinDescription": "Minimální velikost junk paketů (0-1279*, doporučeno: 8, musí být < Jmax)",
|
||||
"jMaxLabel": "Max. velikost junk paketu (Jmax)",
|
||||
"jMaxDescription": "Maximální velikost junk paketů (1-1280*, doporučeno: 80, musí být > Jmin)",
|
||||
"s1Label": "Velikost junk dat u Init paketu (S1)",
|
||||
"s1Description": "Velikost junk dat u Init paketu (0-1132, doporučeno: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Velikost junk dat u Response paketu (S2)",
|
||||
"s2Description": "Velikost junk dat u Response paketu (0-1188, doporučeno: 15-150)",
|
||||
"s3Label": "Velikost junk dat u Cookie reply paketu (S3)",
|
||||
"s3Description": "Velikost junk dat u paketu s odpovědí na cookie",
|
||||
"s4Label": "Velikost junk dat u Transport paketu (S4)",
|
||||
"s4Description": "Velikost junk dat u transportního paketu",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Hodnota nebo rozsah hlavičky Init paketu (X nebo X-Y, kde X<Y. Min 5, max 2147483647. Nesmí se překrývat s ostatními hlavičkami)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Hodnota nebo rozsah hlavičky Response paketu (X nebo X-Y, kde X<Y. Min 5, max 2147483647. Nesmí se překrývat s ostatními hlavičkami)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Hodnota nebo rozsah hlavičky Cookie reply paketu (X nebo X-Y, kde X<Y. Min 5, max 2147483647. Nesmí se překrývat s ostatními hlavičkami)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Hodnota nebo rozsah hlavičky Transport paketu (X nebo X-Y, kde X<Y. Min 5, max 2147483647. Nesmí se překrývat s ostatními hlavičkami)",
|
||||
"i1Label": "Speciální junk paket 1 (I1)",
|
||||
"i1Description": "Paket pro napodobení protokolu v hex formátu: <b 0x...>",
|
||||
"i2Label": "Speciální junk paket 2 (I2)",
|
||||
"i2Description": "Paket pro napodobení protokolu v hex formátu: <b 0x...>",
|
||||
"i3Label": "Speciální junk paket 3 (I3)",
|
||||
"i3Description": "Paket pro napodobení protokolu v hex formátu: <b 0x...>",
|
||||
"i4Label": "Speciální junk paket 4 (I4)",
|
||||
"i4Description": "Paket pro napodobení protokolu v hex formátu: <b 0x...>",
|
||||
"i5Label": "Speciální junk paket 5 (I5)",
|
||||
"i5Description": "Paket pro napodobení protokolu v hex formátu: <b 0x...>",
|
||||
"mtuNote": "Hodnoty závisí na nastavení MTU",
|
||||
"obfuscationParameters": "AmneziaWG parametry obfuskace"
|
||||
}
|
||||
}
|
||||
+24
-13
@@ -88,6 +88,7 @@
|
||||
"name": "Name",
|
||||
"expireDate": "Ablaufdatum",
|
||||
"expireDateDesc": "Datum, an dem der Client deaktiviert wird. Leer lassen für dauerhaft aktiv.",
|
||||
"delete": "Löschen",
|
||||
"deleteClient": "Client löschen",
|
||||
"deleteDialog1": "Sind Sie sicher, dass Sie diesen Client löschen möchten",
|
||||
"deleteDialog2": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
@@ -114,13 +115,16 @@
|
||||
"hooksDescription": "Hooks funktionieren nur mit wg-quick",
|
||||
"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"
|
||||
"viewConfig": "Konfiguration anzeigen",
|
||||
"firewallIps": "Firewall erlaubte IPs",
|
||||
"firewallIpsDesc": "Ziel-IPs/CIDRs, auf die dieser Client zugreifen darf (serverseitig erzwingen). Lassen Sie das Feld leer, um die Liste der zugelassenen IPs zu verwenden. Unterstützt optionale Port- und Protokollfilterung. Die Syntax finden Sie in der Dokumentation.",
|
||||
"downloadPng": "Herunterladen PNG",
|
||||
"copyPng": "Kopieren PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Ändern",
|
||||
@@ -130,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Erfolg",
|
||||
"saved": "Gespeichert",
|
||||
"error": "Fehler"
|
||||
"error": "Fehler",
|
||||
"unknown": "Unbekannter Fehler. Weitere Informationen finden Sie in der Konsole."
|
||||
},
|
||||
"form": {
|
||||
"actions": "Aktionen",
|
||||
@@ -175,7 +180,10 @@
|
||||
"restart": "Interface neu starten",
|
||||
"restartDesc": "Das WireGuard-Interface neu starten",
|
||||
"restartWarn": "Sind Sie sicher, dass Sie das Interface neu starten möchten? Dies wird die Verbindungen aller Clients trennen.",
|
||||
"restartSuccess": "Interface neu gestartet"
|
||||
"restartSuccess": "Interface neu gestartet",
|
||||
"firewall": "Datenverkehr Filterung",
|
||||
"firewallEnabled": "Firewall pro Client aktivieren",
|
||||
"firewallEnabledDesc": "Beschränken Sie den Client-Datenverkehr mithilfe von iptables auf bestimmte Ziel-IP-Adressen. Bei Aktivierung kann für jeden Client eine Liste der zulässigen Ziele konfiguriert werden."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0} ist erforderlich",
|
||||
"validNumber": "{0} muss eine Zahl sein",
|
||||
"validNumberRange": "{0} muss eine gültige Zahl oder ein gültiger Zahlenbereich sein",
|
||||
"validString": "{0} muss eine Zeichenkette sein",
|
||||
"validBoolean": "{0} muss ein Wahrheitswert sein",
|
||||
"validArray": "{0} muss eine Liste sein",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "Läuft ab am",
|
||||
"address4": "IPv4-Adresse",
|
||||
"address6": "IPv6-Adresse",
|
||||
"serverAllowedIps": "Serverseitig erlaubte IP-Adressen"
|
||||
"serverAllowedIps": "Serverseitig erlaubte IP-Adressen",
|
||||
"firewallIps": "Von der Firewall zugelassene IP-Adressen",
|
||||
"firewallIpsInvalid": "Ungültiger IP-Eintrag in der Firewall. Informationen zur unterstützten Syntax finden Sie in der Dokumentation."
|
||||
},
|
||||
"user": {
|
||||
"username": "Benutzername",
|
||||
@@ -262,6 +273,14 @@
|
||||
"s3Description": "Junk-Paketgröße des Cookie-Antwort-Pakets",
|
||||
"s4Label": "Junk-Paketgröße des Transport-Pakets (S4)",
|
||||
"s4Description": "Junk-Paketgröße des Transport-Pakets",
|
||||
"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)",
|
||||
"i1Label": "Spezial-Junk-Paket 1 (I1)",
|
||||
"i1Description": "Protokoll-Nachahmungspaket im Hex-Format: <b 0x...>",
|
||||
"i2Label": "Spezial-Junk-Paket 2 (I2)",
|
||||
@@ -272,14 +291,6 @@
|
||||
"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"
|
||||
}
|
||||
|
||||
+23
-12
@@ -120,7 +120,11 @@
|
||||
"endpointDesc": "IP of the client from which the WireGuard connection is established",
|
||||
"search": "Search clients...",
|
||||
"config": "Configuration",
|
||||
"viewConfig": "View Configuration"
|
||||
"viewConfig": "View Configuration",
|
||||
"firewallIps": "Firewall Allowed IPs",
|
||||
"firewallIpsDesc": "Destination IPs/CIDRs this client can access (server-side enforcement). Leave empty to use Allowed IPs. Supports optional port and protocol filtering. See docs for syntax.",
|
||||
"downloadPng": "Download PNG",
|
||||
"copyPng": "Copy PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Change",
|
||||
@@ -130,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Success",
|
||||
"saved": "Saved",
|
||||
"error": "Error"
|
||||
"error": "Error",
|
||||
"unknown": "Unknown error. See console for more details"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Actions",
|
||||
@@ -175,7 +180,10 @@
|
||||
"restart": "Restart Interface",
|
||||
"restartDesc": "Restart the WireGuard interface",
|
||||
"restartWarn": "Are you sure to restart the interface? This will disconnect all clients.",
|
||||
"restartSuccess": "Interface restarted"
|
||||
"restartSuccess": "Interface restarted",
|
||||
"firewall": "Traffic Filtering",
|
||||
"firewallEnabled": "Enable Per-Client Firewall",
|
||||
"firewallEnabledDesc": "Restrict client traffic to specific destination IPs using iptables. When enabled, each client can be configured with allowed destinations."
|
||||
},
|
||||
"introText": "Welcome to the admin panel.\n\nHere you can manage the general settings, the configuration, the interface settings and the hooks.\n\nStart by choosing one of the sections in the sidebar."
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0} is required",
|
||||
"validNumber": "{0} must be a valid number",
|
||||
"validNumberRange": "{0} must be a valid number or number range",
|
||||
"validString": "{0} must be a valid string",
|
||||
"validBoolean": "{0} must be a valid boolean",
|
||||
"validArray": "{0} must be a valid array",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "Expires At",
|
||||
"address4": "IPv4 Address",
|
||||
"address6": "IPv6 Address",
|
||||
"serverAllowedIps": "Server Allowed IPs"
|
||||
"serverAllowedIps": "Server Allowed IPs",
|
||||
"firewallIps": "Firewall Allowed IPs",
|
||||
"firewallIpsInvalid": "Invalid firewall IP entry. See docs for supported syntax."
|
||||
},
|
||||
"user": {
|
||||
"username": "Username",
|
||||
@@ -262,6 +273,14 @@
|
||||
"s3Description": "Cookie reply packet junk size",
|
||||
"s4Label": "Transport packet junk size (S4)",
|
||||
"s4Description": "Transport packet junk size",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Init packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Response packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Cookie reply packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Transport packet header value or range (X or X-Y, where X<Y. Min 5, max 2147483647. Value or range must not overlap with other headers)",
|
||||
"i1Label": "Special junk packet 1 (I1)",
|
||||
"i1Description": "Protocol mimic packet in hex format: <b 0x...>",
|
||||
"i2Label": "Special junk packet 2 (I2)",
|
||||
@@ -272,14 +291,6 @@
|
||||
"i4Description": "Protocol mimic packet in hex format: <b 0x...>",
|
||||
"i5Label": "Special junk packet 5 (I5)",
|
||||
"i5Description": "Protocol mimic packet in hex format: <b 0x...>",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Init packet header value (5-2147483647, must be unique from H2-H4)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Response packet header value (5-2147483647, must be unique from H1, H3, H4)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Cookie reply packet header value (5-2147483647, must be unique from H1, H2, H4)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Transport packet header value (5-2147483647, must be unique from H1-H3)",
|
||||
"mtuNote": "Values depend on the MTU",
|
||||
"obfuscationParameters": "AmneziaWG Obfuscation Parameters"
|
||||
}
|
||||
|
||||
@@ -116,7 +116,14 @@
|
||||
"dnsDesc": "Servidor DNS que usarán los clientes (anula la configuración global)",
|
||||
"notConnected": "Cliente no conectado",
|
||||
"endpoint": "Punto de conexión",
|
||||
"endpointDesc": "IP del cliente desde donde se establece la conexión WireGuard"
|
||||
"endpointDesc": "IP del cliente desde donde se establece la conexión WireGuard",
|
||||
"search": "Buscar clientes...",
|
||||
"config": "Configuración",
|
||||
"viewConfig": "Ver configuración",
|
||||
"firewallIps": "IPs permitidas del cortafuegos",
|
||||
"firewallIpsDesc": "IPs/CIDRs de destino a las que este cliente puede acceder (aplicado en el servidor). Deja vacío para usar IPs permitidas. Admite filtrado opcional de puertos y protocolos. Consulta la documentación para la sintaxis.",
|
||||
"downloadPng": "Descargar PNG",
|
||||
"copyPng": "Copiar PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Cambiar",
|
||||
@@ -126,7 +133,8 @@
|
||||
"toast": {
|
||||
"success": "Éxito",
|
||||
"saved": "Guardado",
|
||||
"error": "Error"
|
||||
"error": "Error",
|
||||
"unknown": "Error desconocido. Revisa la consola para más detalles"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Acciones",
|
||||
@@ -171,7 +179,10 @@
|
||||
"restart": "Reiniciar interfaz",
|
||||
"restartDesc": "Reiniciar la interfaz de WireGuard",
|
||||
"restartWarn": "¿Estás seguro de reiniciar la interfaz? Esto desconectará a todos los clientes.",
|
||||
"restartSuccess": "Interfaz reiniciada"
|
||||
"restartSuccess": "Interfaz reiniciada",
|
||||
"firewall": "Filtrado de tráfico",
|
||||
"firewallEnabled": "Habilitar cortafuegos por cliente",
|
||||
"firewallEnabledDesc": "Restringe el tráfico del cliente a IPs de destino específicas usando iptables. Cuando está activado, cada cliente puede configurarse con destinos permitidos."
|
||||
},
|
||||
"introText": "Bienvenido al panel de administración.\n\nAquí puedes gestionar los ajustes generales, la configuración, la interfaz y los hooks.\n\nEmpieza eligiendo una de las secciones en la barra lateral."
|
||||
},
|
||||
@@ -179,6 +190,7 @@
|
||||
"generic": {
|
||||
"required": "{0} es obligatorio",
|
||||
"validNumber": "{0} debe ser un número válido",
|
||||
"validNumberRange": "{0} debe ser un número válido o un rango de números",
|
||||
"validString": "{0} debe ser una cadena válida",
|
||||
"validBoolean": "{0} debe ser un booleano válido",
|
||||
"validArray": "{0} debe ser una lista válida",
|
||||
@@ -191,7 +203,9 @@
|
||||
"expiresAt": "Expira el",
|
||||
"address4": "Dirección IPv4",
|
||||
"address6": "Dirección IPv6",
|
||||
"serverAllowedIps": "IPs permitidas del servidor"
|
||||
"serverAllowedIps": "IPs permitidas del servidor",
|
||||
"firewallIps": "IPs permitidas del cortafuegos",
|
||||
"firewallIpsInvalid": "Entrada de IP de cortafuegos no válida. Consulta la documentación para la sintaxis compatible."
|
||||
},
|
||||
"user": {
|
||||
"username": "Usuario",
|
||||
@@ -236,5 +250,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "La copia no es compatible",
|
||||
"copied": "¡Copiado!",
|
||||
"failed": "Error al copiar",
|
||||
"copy": "Copiar"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Número de paquetes basura (Jc)",
|
||||
"jCDescription": "Número de paquetes basura a enviar (1-128, recomendado: 4-12)",
|
||||
"jMinLabel": "Tamaño mínimo de paquete basura (Jmin)",
|
||||
"jMinDescription": "Tamaño mínimo de los paquetes basura (0-1279*, recomendado: 8, debe ser < Jmax)",
|
||||
"jMaxLabel": "Tamaño máximo de paquete basura (Jmax)",
|
||||
"jMaxDescription": "Tamaño máximo de los paquetes basura (1-1280*, recomendado: 80, debe ser > Jmin)",
|
||||
"s1Label": "Tamaño de basura del paquete Init (S1)",
|
||||
"s1Description": "Tamaño de basura del paquete Init (0-1132[1280* - 148 = 1132], recomendado: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Tamaño de basura del paquete de respuesta (S2)",
|
||||
"s2Description": "Tamaño de basura del paquete de respuesta (0-1188[1280* - 92 = 1188], recomendado: 15-150)",
|
||||
"s3Label": "Tamaño de basura del paquete de respuesta de cookie (S3)",
|
||||
"s3Description": "Tamaño de basura del paquete de respuesta de cookie",
|
||||
"s4Label": "Tamaño de basura del paquete de transporte (S4)",
|
||||
"s4Description": "Tamaño de basura del paquete de transporte",
|
||||
"h1Label": "Cabecera mágica Init (H1)",
|
||||
"h1Description": "Valor o rango de cabecera del paquete Init (X o X-Y, donde X<Y. Mín 5, máx 2147483647. El valor o rango no debe solaparse con otras cabeceras)",
|
||||
"h2Label": "Cabecera mágica de respuesta (H2)",
|
||||
"h2Description": "Valor o rango de cabecera del paquete de respuesta (X o X-Y, donde X<Y. Mín 5, máx 2147483647. El valor o rango no debe solaparse con otras cabeceras)",
|
||||
"h3Label": "Cabecera mágica de respuesta de cookie (H3)",
|
||||
"h3Description": "Valor o rango de cabecera del paquete de respuesta de cookie (X o X-Y, donde X<Y. Mín 5, máx 2147483647. El valor o rango no debe solaparse con otras cabeceras)",
|
||||
"h4Label": "Cabecera mágica de transporte (H4)",
|
||||
"h4Description": "Valor o rango de cabecera del paquete de transporte (X o X-Y, donde X<Y. Mín 5, máx 2147483647. El valor o rango no debe solaparse con otras cabeceras)",
|
||||
"i1Label": "Paquete basura especial 1 (I1)",
|
||||
"i1Description": "Paquete que imita protocolo en formato hex: <b 0x...>",
|
||||
"i2Label": "Paquete basura especial 2 (I2)",
|
||||
"i2Description": "Paquete que imita protocolo en formato hex: <b 0x...>",
|
||||
"i3Label": "Paquete basura especial 3 (I3)",
|
||||
"i3Description": "Paquete que imita protocolo en formato hex: <b 0x...>",
|
||||
"i4Label": "Paquete basura especial 4 (I4)",
|
||||
"i4Description": "Paquete que imita protocolo en formato hex: <b 0x...>",
|
||||
"i5Label": "Paquete basura especial 5 (I5)",
|
||||
"i5Description": "Paquete que imita protocolo en formato hex: <b 0x...>",
|
||||
"mtuNote": "Los valores dependen de la MTU",
|
||||
"obfuscationParameters": "Parámetros de ofuscación AmneziaWG"
|
||||
}
|
||||
}
|
||||
|
||||
+24
-13
@@ -88,12 +88,13 @@
|
||||
"name": "Nom",
|
||||
"expireDate": "Date d'expiration",
|
||||
"expireDateDesc": "Date à laquelle le client sera désactivé. Vide pour permanent",
|
||||
"delete": "Supprimer",
|
||||
"deleteClient": "Supprimer le client",
|
||||
"deleteDialog1": "Êtes-vous sûr de vouloir supprimer",
|
||||
"deleteDialog2": "Cette action ne peut être annulée.",
|
||||
"enabled": "Activé",
|
||||
"address": "Adresse",
|
||||
"serverAllowedIps": "Serveur IPs autorisées",
|
||||
"serverAllowedIps": "IPs autorisées par le serveur",
|
||||
"otlDesc": "Générer un lien court et unique",
|
||||
"permanent": "Permanent",
|
||||
"createdOn": "Créé le ",
|
||||
@@ -120,7 +121,10 @@
|
||||
"search": "Rechercher des clients...",
|
||||
"config": "Configuration",
|
||||
"viewConfig": "Voir la configuration",
|
||||
"delete": "Supprimer"
|
||||
"firewallIps": "IPs autorisées par le pare-feu",
|
||||
"firewallIpsDesc": "IPs/CIDRs de destination auxquels ce client peut accéder (application côté serveur). Laissez vide pour utiliser les IPs autorisées. Prend en charge le filtrage optionnel par port et protocole. Voir la documentation pour la syntaxe.",
|
||||
"downloadPng": "Télécharger le PNG",
|
||||
"copyPng": "Copier le PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Modifier",
|
||||
@@ -130,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Réussite",
|
||||
"saved": "Sauvegardé",
|
||||
"error": "Erreur"
|
||||
"error": "Erreur",
|
||||
"unknown": "Erreur inconnue. Consultez la console pour plus de détails"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Actions",
|
||||
@@ -175,7 +180,10 @@
|
||||
"restart": "Redémarrer l'interface",
|
||||
"restartDesc": "Redémarre l'interface WireGuard",
|
||||
"restartWarn": "Êtes-vous sûr de redémarrer l'interface ? Cela déconnectera tous les clients.",
|
||||
"restartSuccess": "Interface redémarrée"
|
||||
"restartSuccess": "Interface redémarrée",
|
||||
"firewall": "Filtrage du trafic",
|
||||
"firewallEnabled": "Activer le pare-feu par client",
|
||||
"firewallEnabledDesc": "Restreindre le trafic des clients à des IPs de destination spécifiques via iptables. Lorsqu'il est activé, chaque client peut être configuré avec des destinations autorisées."
|
||||
},
|
||||
"introText": "Bienvenue dans le panel d'administration.\n\nVous pouvez y gérer les paramètres généraux, la configuration, les paramètres de l'interface et les hooks.\n\nCommencez par choisir l'une des sections de la barre latérale."
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0} est requis",
|
||||
"validNumber": "{0} doit être un nombre valide",
|
||||
"validNumberRange": "{0} doit être un nombre ou une plage de nombres valide",
|
||||
"validString": "{0} doit être une chaîne de caractères valide",
|
||||
"validBoolean": "{0} doit être un booléen valide",
|
||||
"validArray": "{0} doit être un tableau valide",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "Expire le",
|
||||
"address4": "Adresse IPv4",
|
||||
"address6": "Adresse IPv6",
|
||||
"serverAllowedIps": "Serveur IPs autorisées"
|
||||
"serverAllowedIps": "IPs autorisées par le serveur",
|
||||
"firewallIps": "IPs autorisées par le pare-feu",
|
||||
"firewallIpsInvalid": "Entrée d'IP de pare-feu invalide. Voir la documentation pour la syntaxe supportée."
|
||||
},
|
||||
"user": {
|
||||
"username": "Nom d'utilisateur",
|
||||
@@ -262,6 +273,14 @@
|
||||
"s3Description": "Taille parasite du paquet de réponse cookie",
|
||||
"s4Label": "Taille parasite du paquet transport (S4)",
|
||||
"s4Description": "Taille parasite du paquet de transport",
|
||||
"h1Label": "En-tête magique init (H1)",
|
||||
"h1Description": "Valeur ou plage de l'en-tête du paquet init (X ou X-Y, où X<Y. Min 5, max 2147483647. La valeur ou la plage ne doit pas chevaucher les autres en-têtes)",
|
||||
"h2Label": "En-tête magique réponse (H2)",
|
||||
"h2Description": "Valeur ou plage de l'en-tête du paquet réponse (X ou X-Y, où X<Y. Min 5, max 2147483647. La valeur ou la plage ne doit pas chevaucher les autres en-têtes)",
|
||||
"h3Label": "En-tête magique cookie reply (H3)",
|
||||
"h3Description": "Valeur ou plage de l'en-tête du paquet cookie reply (X ou X-Y, où X<Y. Min 5, max 2147483647. La valeur ou la plage ne doit pas chevaucher les autres en-têtes)",
|
||||
"h4Label": "En-tête magique transport (H4)",
|
||||
"h4Description": "Valeur ou plage de l'en-tête du paquet transport (X ou X-Y, où X<Y. Min 5, max 2147483647. La valeur ou la plage ne doit pas chevaucher les autres en-têtes)",
|
||||
"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)",
|
||||
@@ -272,14 +291,6 @@
|
||||
"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,296 @@
|
||||
{
|
||||
"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",
|
||||
"firewallIps": "IPs permitidas do cortalumes",
|
||||
"firewallIpsDesc": "IPs/CIDRs de destino aos que este cliente pode acceder (aplicado no lado do servidor). Déixao baleiro para usar as IPs permitidas. Admite filtrado opcional por porto e protocolo. Consulta a documentación para a sintaxe.",
|
||||
"downloadPng": "Descargar PNG",
|
||||
"copyPng": "Copiar PNG"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Tempo límite da sesión",
|
||||
"sessionTimeoutDesc": "Duración da sesión para Lembrarme (segundos)",
|
||||
"metrics": "Métricas",
|
||||
"metricsPassword": "Contrasinal",
|
||||
"metricsPasswordDesc": "Contrasinal Bearer para o endpoint de métricas (contrasinal ou hash argon2)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Ruta para as métricas en formato JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Ruta para as métricas de Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Conexión",
|
||||
"hostDesc": "Nome de host público ao que se conectarán os clientes (invalida a configuración)",
|
||||
"portDesc": "Porto UDP público ao que se conectarán os clientes (invalida a configuración; probablemente tamén queiras cambiar o Porto da interface)",
|
||||
"allowedIpsDesc": "IPs permitidas que usarán os clientes (configuración global)",
|
||||
"dnsDesc": "Servidor DNS que usarán os clientes (configuración global)",
|
||||
"mtuDesc": "MTU que usarán os clientes (só para clientes novos)",
|
||||
"persistentKeepaliveDesc": "Intervalo en segundos para enviar keepalives ao servidor. 0 = desactivado (só para clientes novos)",
|
||||
"suggest": "Suxerir",
|
||||
"suggestDesc": "Escolle un enderezo IP ou nome de host para o campo Host"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR cambiado",
|
||||
"device": "Dispositivo",
|
||||
"deviceDesc": "Dispositivo Ethernet polo que se redirixirá o tráfico de WireGuard",
|
||||
"mtuDesc": "MTU que usará WireGuard",
|
||||
"portDesc": "Porto UDP no que WireGuard escoitará (probablemente tamén queiras cambiar o Porto da configuración)",
|
||||
"changeCidr": "Cambiar CIDR",
|
||||
"restart": "Reiniciar interface",
|
||||
"restartDesc": "Reiniciar a interface de WireGuard",
|
||||
"restartWarn": "Seguro que queres reiniciar a interface? Isto desconectará todos os clientes.",
|
||||
"restartSuccess": "Interface reiniciada",
|
||||
"firewall": "Filtrado de tráfico",
|
||||
"firewallEnabled": "Activar devasa por cliente",
|
||||
"firewallEnabledDesc": "Restrinxir o tráfico dos clientes a IPs de destino específicas usando iptables. Cando está activado, cada cliente pode configurarse con destinos permitidos."
|
||||
},
|
||||
"introText": "Benvido ao panel de administración.\n\nAquí podes xestionar a configuración xeral, a configuración, os axustes da interface e os hooks.\n\nComeza escollendo unha das seccións na barra lateral."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} é obrigatorio",
|
||||
"validNumber": "{0} debe ser un número válido",
|
||||
"validNumberRange": "{0} debe ser un número válido ou un rango de números",
|
||||
"validString": "{0} debe ser unha cadea válida",
|
||||
"validBoolean": "{0} debe ser un booleano válido",
|
||||
"validArray": "{0} debe ser un array válido",
|
||||
"stringMin": "{0} debe ter polo menos {1} carácter",
|
||||
"numberMin": "{0} debe ser polo menos {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID do cliente",
|
||||
"name": "Nome",
|
||||
"expiresAt": "Caduca o",
|
||||
"address4": "Enderezo IPv4",
|
||||
"address6": "Enderezo IPv6",
|
||||
"serverAllowedIps": "IPs permitidas do servidor",
|
||||
"firewallIps": "IPs permitidas da devasa",
|
||||
"firewallIpsInvalid": "Entrada de IP da devasa non válida. Consulta a documentación para a sintaxe admitida."
|
||||
},
|
||||
"user": {
|
||||
"username": "Nome de usuario",
|
||||
"password": "Contrasinal",
|
||||
"remember": "Lembrar",
|
||||
"name": "Nome",
|
||||
"email": "Correo electrónico",
|
||||
"emailInvalid": "O correo electrónico debe ser válido",
|
||||
"passwordMatch": "Os contrasinais deben coincidir",
|
||||
"totpEnable": "Activar TOTP",
|
||||
"totpEnableTrue": "Activar TOTP debe ser verdadeiro",
|
||||
"totpCode": "Código TOTP"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Host"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Tempo límite da sesión",
|
||||
"metricsEnabled": "Métricas",
|
||||
"metricsPassword": "Contrasinal das métricas"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Dispositivo",
|
||||
"cidrValid": "O CIDR debe ser válido"
|
||||
},
|
||||
"otl": "Ligazón dun só uso",
|
||||
"stringMalformed": "A cadea está mal formada",
|
||||
"body": "O corpo debe ser un obxecto válido",
|
||||
"hook": "Hook",
|
||||
"enabled": "Activado",
|
||||
"mtu": "MTU",
|
||||
"port": "Porto",
|
||||
"persistentKeepalive": "Keepalive persistente",
|
||||
"address": "Enderezo IP",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "IPs permitidas",
|
||||
"file": "Ficheiro"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Copiar non é compatible",
|
||||
"copied": "Copiado!",
|
||||
"failed": "Erro ao copiar",
|
||||
"copy": "Copiar"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Número de paquetes lixo (Jc)",
|
||||
"jCDescription": "Número de paquetes lixo para enviar (1-128, recomendado: 4-12)",
|
||||
"jMinLabel": "Tamaño mínimo dos paquetes lixo (Jmin)",
|
||||
"jMinDescription": "Tamaño mínimo dos paquetes lixo (0-1279*, recomendado: 8, debe ser < Jmax)",
|
||||
"jMaxLabel": "Tamaño máximo dos paquetes lixo (Jmax)",
|
||||
"jMaxDescription": "Tamaño máximo dos paquetes lixo (1-1280*, recomendado: 80, debe ser > Jmin)",
|
||||
"s1Label": "Tamaño lixo do paquete de inicio (S1)",
|
||||
"s1Description": "Tamaño lixo do paquete de inicio (0-1132[1280* - 148 = 1132], recomendado: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Tamaño lixo do paquete de resposta (S2)",
|
||||
"s2Description": "Tamaño lixo do paquete de resposta (0-1188[1280* - 92 = 1188], recomendado: 15-150)",
|
||||
"s3Label": "Tamaño lixo do paquete de resposta cookie (S3)",
|
||||
"s3Description": "Tamaño lixo do paquete de resposta cookie",
|
||||
"s4Label": "Tamaño lixo do paquete de transporte (S4)",
|
||||
"s4Description": "Tamaño lixo do paquete de transporte",
|
||||
"h1Label": "Cabeceira máxica de inicio (H1)",
|
||||
"h1Description": "Valor ou rango da cabeceira do paquete de inicio (X ou X-Y, onde X<Y. Mín 5, máx 2147483647. O valor ou rango non debe solaparse con outras cabeceiras)",
|
||||
"h2Label": "Cabeceira máxica de resposta (H2)",
|
||||
"h2Description": "Valor ou rango da cabeceira do paquete de resposta (X ou X-Y, onde X<Y. Mín 5, máx 2147483647. O valor ou rango non debe solaparse con outras cabeceiras)",
|
||||
"h3Label": "Cabeceira máxica da resposta cookie (H3)",
|
||||
"h3Description": "Valor ou rango da cabeceira do paquete de resposta cookie (X ou X-Y, onde X<Y. Mín 5, máx 2147483647. O valor ou rango non debe solaparse con outras cabeceiras)",
|
||||
"h4Label": "Cabeceira máxica de transporte (H4)",
|
||||
"h4Description": "Valor ou rango da cabeceira do paquete de transporte (X ou X-Y, onde X<Y. Mín 5, máx 2147483647. O valor ou rango non debe solaparse con outras cabeceiras)",
|
||||
"i1Label": "Paquete lixo especial 1 (I1)",
|
||||
"i1Description": "Paquete de simulación de protocolo en formato hexadecimal: <b 0x...>",
|
||||
"i2Label": "Paquete lixo especial 2 (I2)",
|
||||
"i2Description": "Paquete de simulación de protocolo en formato hexadecimal: <b 0x...>",
|
||||
"i3Label": "Paquete lixo especial 3 (I3)",
|
||||
"i3Description": "Paquete de simulación de protocolo en formato hexadecimal: <b 0x...>",
|
||||
"i4Label": "Paquete lixo especial 4 (I4)",
|
||||
"i4Description": "Paquete de simulación de protocolo en formato hexadecimal: <b 0x...>",
|
||||
"i5Label": "Paquete lixo especial 5 (I5)",
|
||||
"i5Description": "Paquete de simulación de protocolo en formato hexadecimal: <b 0x...>",
|
||||
"mtuNote": "Os valores dependen da MTU",
|
||||
"obfuscationParameters": "Parámetros de ofuscación de AmneziaWG"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "खाता",
|
||||
"clients": "क्लाइंट",
|
||||
"admin": {
|
||||
"panel": "एडमिन पैनल",
|
||||
"general": "सामान्य",
|
||||
"config": "कॉन्फ़िगरेशन",
|
||||
"interface": "इंटरफ़ेस",
|
||||
"hooks": "हुक्स"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "ई-मेल"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "वर्तमान पासवर्ड",
|
||||
"enable2fa": "दो-कारक प्रमाणीकरण सक्षम करें",
|
||||
"enable2faDesc": "अपने प्रमाणक ऐप से QR कोड स्कैन करें या कुंजी मैन्युअल रूप से दर्ज करें।",
|
||||
"2faKey": "TOTP कुंजी",
|
||||
"2faCodeDesc": "अपने प्रमाणक ऐप से कोड दर्ज करें।",
|
||||
"disable2fa": "दो-कारक प्रमाणीकरण अक्षम करें",
|
||||
"disable2faDesc": "दो-कारक प्रमाणीकरण अक्षम करने के लिए अपना पासवर्ड दर्ज करें।"
|
||||
},
|
||||
"general": {
|
||||
"name": "नाम",
|
||||
"username": "उपयोगकर्ता नाम",
|
||||
"password": "पासवर्ड",
|
||||
"newPassword": "नया पासवर्ड",
|
||||
"updatePassword": "पासवर्ड अपडेट करें",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "अनुमत IPs",
|
||||
"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": "सर्वर द्वारा अनुमत IPs",
|
||||
"otlDesc": "छोटा एकबारगी लिंक उत्पन्न करें",
|
||||
"permanent": "स्थायी",
|
||||
"createdOn": "बनाया गया ",
|
||||
"lastSeen": "अंतिम बार देखा गया ",
|
||||
"totalDownload": "कुल डाउनलोड: ",
|
||||
"totalUpload": "कुल अपलोड: ",
|
||||
"newClient": "नया क्लाइंट",
|
||||
"disableClient": "क्लाइंट अक्षम करें",
|
||||
"enableClient": "क्लाइंट सक्षम करें",
|
||||
"noPrivKey": "इस क्लाइंट की कोई ज्ञात निजी कुंजी नहीं है। कॉन्फ़िगरेशन नहीं बना सकते।",
|
||||
"showQR": "QR कोड दिखाएं",
|
||||
"downloadConfig": "कॉन्फ़िगरेशन डाउनलोड करें",
|
||||
"allowedIpsDesc": "कौन से IPs VPN के माध्यम से रूट होंगे (वैश्विक कॉन्फ़िगरेशन को ओवरराइड करता है)",
|
||||
"serverAllowedIpsDesc": "कौन से IPs सर्वर क्लाइंट को रूट करेगा",
|
||||
"mtuDesc": "VPN टनल के लिए अधिकतम ट्रांसमिशन इकाई (पैकेट आकार) सेट करता है",
|
||||
"persistentKeepaliveDesc": "कीप-अलाइव पैकेट के लिए अंतराल (सेकंड में) सेट करता है। 0 इसे अक्षम करता है",
|
||||
"hooks": "हुक्स",
|
||||
"hooksDescription": "हुक्स केवल wg-quick के साथ काम करते हैं",
|
||||
"hooksLeaveEmpty": "केवल wg-quick के लिए। अन्यथा, खाली छोड़ें",
|
||||
"dnsDesc": "DNS सर्वर जिसे क्लाइंट उपयोग करेंगे (वैश्विक कॉन्फ़िगरेशन को ओवरराइड करता है)",
|
||||
"notConnected": "क्लाइंट कनेक्ट नहीं है",
|
||||
"endpoint": "एंडपॉइंट",
|
||||
"endpointDesc": "क्लाइंट का IP पता जहाँ से WireGuard कनेक्शन स्थापित होता है",
|
||||
"search": "क्लाइंट खोजें...",
|
||||
"config": "कॉन्फ़िगरेशन",
|
||||
"viewConfig": "कॉन्फ़िगरेशन देखें",
|
||||
"firewallIps": "फ़ायरवॉल द्वारा अनुमत IPs",
|
||||
"firewallIpsDesc": "गंतव्य IPs/CIDRs जिन तक यह क्लाइंट पहुँच सकता है (सर्वर-साइड नियंत्रण)। अनुमत IPs उपयोग करने के लिए खाली छोड़ें। वैकल्पिक पोर्ट और प्रोटोकॉल फ़िल्टरिंग का समर्थन करता है। सिंटैक्स के लिए दस्तावेज़ देखें।",
|
||||
"downloadPng": "PNG डाउनलोड करें",
|
||||
"copyPng": "PNG कॉपी करें"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "बदलें",
|
||||
"cancel": "रद्द करें",
|
||||
"create": "बनाएं"
|
||||
},
|
||||
"toast": {
|
||||
"success": "सफल",
|
||||
"saved": "सहेजा गया",
|
||||
"error": "त्रुटि",
|
||||
"unknown": "अज्ञात त्रुटि। अधिक जानकारी के लिए कंसोल देखें"
|
||||
},
|
||||
"form": {
|
||||
"actions": "क्रियाएं",
|
||||
"save": "सहेजें",
|
||||
"revert": "पूर्ववत करें",
|
||||
"sectionGeneral": "सामान्य",
|
||||
"sectionAdvanced": "उन्नत",
|
||||
"noItems": "कोई आइटम नहीं",
|
||||
"nullNoItems": "कोई आइटम नहीं। वैश्विक कॉन्फ़िगरेशन उपयोग में है",
|
||||
"add": "जोड़ें"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "सत्र समय समाप्ति",
|
||||
"sessionTimeoutDesc": "रिमेम्बर मी के लिए सत्र अवधि (सेकंड में)",
|
||||
"metrics": "मेट्रिक्स",
|
||||
"metricsPassword": "पासवर्ड",
|
||||
"metricsPasswordDesc": "मेट्रिक्स एंडपॉइंट के लिए बियरर पासवर्ड (पासवर्ड या argon2 हैश)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "JSON फ़ॉर्मेट में मेट्रिक्स का मार्ग",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Prometheus मेट्रिक्स का मार्ग"
|
||||
},
|
||||
"config": {
|
||||
"connection": "कनेक्शन",
|
||||
"hostDesc": "सार्वजनिक होस्टनाम जिससे क्लाइंट कनेक्ट होंगे (कॉन्फ़िगरेशन को अमान्य करता है)",
|
||||
"portDesc": "सार्वजनिक UDP पोर्ट जिससे क्लाइंट कनेक्ट होंगे (कॉन्फ़िगरेशन को अमान्य करता है, शायद आप इंटरफ़ेस पोर्ट भी बदलना चाहें)",
|
||||
"allowedIpsDesc": "क्लाइंट द्वारा उपयोग किए जाने वाले अनुमत IPs (वैश्विक कॉन्फ़िगरेशन)",
|
||||
"dnsDesc": "क्लाइंट द्वारा उपयोग किया जाने वाला DNS सर्वर (वैश्विक कॉन्फ़िगरेशन)",
|
||||
"mtuDesc": "क्लाइंट द्वारा उपयोग किया जाने वाला MTU (केवल नए क्लाइंट के लिए)",
|
||||
"persistentKeepaliveDesc": "सर्वर को कीपअलाइव भेजने का अंतराल सेकंड में। 0 = अक्षम (केवल नए क्लाइंट के लिए)",
|
||||
"suggest": "सुझाएं",
|
||||
"suggestDesc": "होस्ट फ़ील्ड के लिए IP पता या होस्टनाम चुनें"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR बदला गया",
|
||||
"device": "डिवाइस",
|
||||
"deviceDesc": "ईथरनेट डिवाइस जिसके माध्यम से WireGuard ट्रैफ़िक फ़ॉरवर्ड किया जाना चाहिए",
|
||||
"mtuDesc": "MTU जिसे WireGuard उपयोग करेगा",
|
||||
"portDesc": "UDP पोर्ट जिस पर WireGuard सुनेगा (शायद आप कॉन्फ़िग पोर्ट भी बदलना चाहें)",
|
||||
"changeCidr": "CIDR बदलें",
|
||||
"restart": "इंटरफ़ेस रीस्टार्ट करें",
|
||||
"restartDesc": "WireGuard इंटरफ़ेस को रीस्टार्ट करें",
|
||||
"restartWarn": "क्या आप वाकई इंटरफ़ेस रीस्टार्ट करना चाहते हैं? इससे सभी क्लाइंट डिस्कनेक्ट हो जाएंगे।",
|
||||
"restartSuccess": "इंटरफ़ेस रीस्टार्ट हो गया",
|
||||
"firewall": "ट्रैफ़िक फ़िल्टरिंग",
|
||||
"firewallEnabled": "प्रति-क्लाइंट फ़ायरवॉल सक्षम करें",
|
||||
"firewallEnabledDesc": "iptables का उपयोग करके क्लाइंट ट्रैफ़िक को विशिष्ट गंतव्य IPs तक सीमित करें। सक्षम होने पर, प्रत्येक क्लाइंट को अनुमत गंतव्यों के साथ कॉन्फ़िगर किया जा सकता है।"
|
||||
},
|
||||
"introText": "एडमिन पैनल में आपका स्वागत है।\n\nयहाँ आप सामान्य सेटिंग्स, कॉन्फ़िगरेशन, इंटरफ़ेस सेटिंग्स और हुक्स प्रबंधित कर सकते हैं।\n\nसाइडबार में किसी एक अनुभाग को चुनकर शुरू करें।"
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} आवश्यक है",
|
||||
"validNumber": "{0} एक वैध संख्या होनी चाहिए",
|
||||
"validNumberRange": "{0} एक वैध संख्या या संख्या श्रेणी होनी चाहिए",
|
||||
"validString": "{0} एक वैध स्ट्रिंग होनी चाहिए",
|
||||
"validBoolean": "{0} एक वैध बूलियन होना चाहिए",
|
||||
"validArray": "{0} एक वैध ऐरे होना चाहिए",
|
||||
"stringMin": "{0} कम से कम {1} अक्षर का होना चाहिए",
|
||||
"numberMin": "{0} कम से कम {1} होना चाहिए"
|
||||
},
|
||||
"client": {
|
||||
"id": "क्लाइंट ID",
|
||||
"name": "नाम",
|
||||
"expiresAt": "समाप्ति तिथि",
|
||||
"address4": "IPv4 पता",
|
||||
"address6": "IPv6 पता",
|
||||
"serverAllowedIps": "सर्वर द्वारा अनुमत IPs",
|
||||
"firewallIps": "फ़ायरवॉल द्वारा अनुमत IPs",
|
||||
"firewallIpsInvalid": "अमान्य फ़ायरवॉल 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": "बॉडी एक वैध ऑब्जेक्ट होनी चाहिए",
|
||||
"hook": "हुक",
|
||||
"enabled": "सक्षम",
|
||||
"mtu": "MTU",
|
||||
"port": "पोर्ट",
|
||||
"persistentKeepalive": "स्थायी कीपअलाइव",
|
||||
"address": "IP पता",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "अनुमत IPs",
|
||||
"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": "कुकी रिप्लाई पैकेट जंक आकार (S3)",
|
||||
"s3Description": "कुकी रिप्लाई पैकेट जंक आकार",
|
||||
"s4Label": "ट्रांसपोर्ट पैकेट जंक आकार (S4)",
|
||||
"s4Description": "ट्रांसपोर्ट पैकेट जंक आकार",
|
||||
"h1Label": "इनिट मैजिक हेडर (H1)",
|
||||
"h1Description": "इनिट पैकेट हेडर मान या श्रेणी (X या X-Y, जहाँ X<Y। न्यूनतम 5, अधिकतम 2147483647। मान या श्रेणी अन्य हेडर से ओवरलैप नहीं होनी चाहिए)",
|
||||
"h2Label": "रिस्पॉन्स मैजिक हेडर (H2)",
|
||||
"h2Description": "रिस्पॉन्स पैकेट हेडर मान या श्रेणी (X या X-Y, जहाँ X<Y। न्यूनतम 5, अधिकतम 2147483647। मान या श्रेणी अन्य हेडर से ओवरलैप नहीं होनी चाहिए)",
|
||||
"h3Label": "कुकी रिप्लाई मैजिक हेडर (H3)",
|
||||
"h3Description": "कुकी रिप्लाई पैकेट हेडर मान या श्रेणी (X या X-Y, जहाँ X<Y। न्यूनतम 5, अधिकतम 2147483647। मान या श्रेणी अन्य हेडर से ओवरलैप नहीं होनी चाहिए)",
|
||||
"h4Label": "ट्रांसपोर्ट मैजिक हेडर (H4)",
|
||||
"h4Description": "ट्रांसपोर्ट पैकेट हेडर मान या श्रेणी (X या X-Y, जहाँ X<Y। न्यूनतम 5, अधिकतम 2147483647। मान या श्रेणी अन्य हेडर से ओवरलैप नहीं होनी चाहिए)",
|
||||
"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...>",
|
||||
"mtuNote": "मान MTU पर निर्भर करते हैं",
|
||||
"obfuscationParameters": "AmneziaWG ऑबफस्केशन पैरामीटर"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "アカウント",
|
||||
"clients": "クライアント",
|
||||
"admin": {
|
||||
"panel": "管理パネル",
|
||||
"general": "一般",
|
||||
"config": "構成",
|
||||
"interface": "インターフェイス",
|
||||
"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": "永続的 Keepalive",
|
||||
"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": "クライアントが接続し、WireGuard が待ち受ける公開 UDP ポート"
|
||||
},
|
||||
"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": "VPN 経由でルーティングされる IP (グローバル設定を上書き)",
|
||||
"serverAllowedIpsDesc": "サーバーがこのクライアントへルーティングする IP",
|
||||
"mtuDesc": "VPN トンネルの最大転送単位 (パケットサイズ) を設定します",
|
||||
"persistentKeepaliveDesc": "Keepalive パケットを送信する間隔 (秒) を設定します。0 で無効化します",
|
||||
"hooks": "フック",
|
||||
"hooksDescription": "フックは wg-quick でのみ動作します",
|
||||
"hooksLeaveEmpty": "wg-quick 専用です。それ以外の場合は空のままにしてください",
|
||||
"dnsDesc": "クライアントが使用する DNS サーバー (グローバル設定を上書き)",
|
||||
"notConnected": "クライアントは接続されていません",
|
||||
"endpoint": "エンドポイント",
|
||||
"endpointDesc": "WireGuard 接続が確立されているクライアントの IP",
|
||||
"search": "クライアントを検索...",
|
||||
"config": "構成",
|
||||
"viewConfig": "構成を表示",
|
||||
"firewallIps": "ファイアウォール許可 IP",
|
||||
"firewallIpsDesc": "このクライアントがアクセスできる宛先 IP/CIDR (サーバー側で強制)。空欄の場合は Allowed IPs を使用します。任意のポートとプロトコルによるフィルタリングに対応しています。構文はドキュメントを参照してください。",
|
||||
"downloadPng": "PNG をダウンロード",
|
||||
"copyPng": "PNG をコピー"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "変更",
|
||||
"cancel": "キャンセル",
|
||||
"create": "作成"
|
||||
},
|
||||
"toast": {
|
||||
"success": "成功",
|
||||
"saved": "保存しました",
|
||||
"error": "エラー",
|
||||
"unknown": "不明なエラーです。詳細はコンソールを確認してください"
|
||||
},
|
||||
"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 トラフィックを転送する Ethernet デバイス",
|
||||
"mtuDesc": "WireGuard が使用する MTU",
|
||||
"portDesc": "WireGuard が待ち受ける UDP ポート (通常は構成ポートも変更します)",
|
||||
"changeCidr": "CIDR を変更",
|
||||
"restart": "インターフェイスを再起動",
|
||||
"restartDesc": "WireGuard インターフェイスを再起動します",
|
||||
"restartWarn": "インターフェイスを再起動してもよろしいですか?すべてのクライアントが切断されます。",
|
||||
"restartSuccess": "インターフェイスを再起動しました",
|
||||
"firewall": "トラフィックフィルタリング",
|
||||
"firewallEnabled": "クライアントごとのファイアウォールを有効化",
|
||||
"firewallEnabledDesc": "iptables を使用して、クライアントのトラフィックを特定の宛先 IP に制限します。有効にすると、クライアントごとに許可する宛先を設定できます。"
|
||||
},
|
||||
"introText": "管理パネルへようこそ。\n\nここでは一般設定、構成、インターフェイス設定、フックを管理できます。\n\nまずサイドバーからセクションを選択してください。"
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} は必須です",
|
||||
"validNumber": "{0} は有効な数値である必要があります",
|
||||
"validNumberRange": "{0} は有効な数値または数値範囲である必要があります",
|
||||
"validString": "{0} は有効な文字列である必要があります",
|
||||
"validBoolean": "{0} は有効な真偽値である必要があります",
|
||||
"validArray": "{0} は有効な配列である必要があります",
|
||||
"stringMin": "{0} は {1} 文字以上である必要があります",
|
||||
"numberMin": "{0} は {1} 以上である必要があります"
|
||||
},
|
||||
"client": {
|
||||
"id": "クライアント ID",
|
||||
"name": "名前",
|
||||
"expiresAt": "有効期限",
|
||||
"address4": "IPv4 アドレス",
|
||||
"address6": "IPv6 アドレス",
|
||||
"serverAllowedIps": "サーバー許可 IP",
|
||||
"firewallIps": "ファイアウォール許可 IP",
|
||||
"firewallIpsInvalid": "ファイアウォール IP の指定が無効です。対応している構文はドキュメントを参照してください。"
|
||||
},
|
||||
"user": {
|
||||
"username": "ユーザー名",
|
||||
"password": "パスワード",
|
||||
"remember": "ログイン状態を保持",
|
||||
"name": "名前",
|
||||
"email": "メール",
|
||||
"emailInvalid": "メールは有効なメールアドレスである必要があります",
|
||||
"passwordMatch": "パスワードが一致しません",
|
||||
"totpEnable": "TOTP 有効化",
|
||||
"totpEnableTrue": "TOTP 有効化は true である必要があります",
|
||||
"totpCode": "TOTPコード"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "ホスト"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "セッションタイムアウト",
|
||||
"metricsEnabled": "メトリクス",
|
||||
"metricsPassword": "メトリクスパスワード"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "デバイス",
|
||||
"cidrValid": "CIDR は有効である必要があります"
|
||||
},
|
||||
"otl": "ワンタイムリンク",
|
||||
"stringMalformed": "文字列の形式が正しくありません",
|
||||
"body": "本文は有効なオブジェクトである必要があります",
|
||||
"hook": "フック",
|
||||
"enabled": "有効",
|
||||
"mtu": "MTU",
|
||||
"port": "ポート",
|
||||
"persistentKeepalive": "永続的 Keepalive",
|
||||
"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": "トランスポートパケットのジャンクサイズ",
|
||||
"h1Label": "初期化マジックヘッダー (H1)",
|
||||
"h1Description": "初期化パケットのヘッダー値または範囲 (X または X-Y、X<Y。最小 5、最大 2147483647。値または範囲は他のヘッダーと重複してはいけません)",
|
||||
"h2Label": "応答マジックヘッダー (H2)",
|
||||
"h2Description": "応答パケットのヘッダー値または範囲 (X または X-Y、X<Y。最小 5、最大 2147483647。値または範囲は他のヘッダーと重複してはいけません)",
|
||||
"h3Label": "Cookie 応答マジックヘッダー (H3)",
|
||||
"h3Description": "Cookie 応答パケットのヘッダー値または範囲 (X または X-Y、X<Y。最小 5、最大 2147483647。値または範囲は他のヘッダーと重複してはいけません)",
|
||||
"h4Label": "トランスポートマジックヘッダー (H4)",
|
||||
"h4Description": "トランスポートパケットのヘッダー値または範囲 (X または X-Y、X<Y。最小 5、最大 2147483647。値または範囲は他のヘッダーと重複してはいけません)",
|
||||
"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...>",
|
||||
"mtuNote": "値は MTU に依存します",
|
||||
"obfuscationParameters": "AmneziaWG 難読化パラメーター"
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
"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)",
|
||||
"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...>",
|
||||
"mtuNote": "Verdier avhenger av MTU",
|
||||
"obfuscationParameters": "AmneziaWG obfuskasjonsparametere"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Account",
|
||||
"clients": "Cliënten",
|
||||
"admin": {
|
||||
"panel": "Admin-paneel",
|
||||
"general": "Algemeen",
|
||||
"config": "Configuratie",
|
||||
"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": "Poort",
|
||||
"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",
|
||||
"firewallIps": "Firewall-toegestane IPs",
|
||||
"firewallIpsDesc": "Bestemmings-IP's/CIDR's waartoe deze client toegang heeft (handhaving aan de serverzijde). Laat leeg om Toegestane IP's te gebruiken. Ondersteunt optionele poort - en protocolfiltering. Zie documentatie voor syntaxis.",
|
||||
"downloadPng": "PNG downloaden",
|
||||
"copyPng": "PNG kopiëren"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Wijzigen",
|
||||
"cancel": "Annuleren",
|
||||
"create": "Aanmaken"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Succes",
|
||||
"saved": "Opgeslagen",
|
||||
"error": "Fout",
|
||||
"unknown": "Onbekende fout. Zie console voor meer details"
|
||||
},
|
||||
"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",
|
||||
"firewall": "Traffic-filtering",
|
||||
"firewallEnabled": "Per-Client Firewall inschakelen",
|
||||
"firewallEnabledDesc": "Beperk het cliëntverkeer tot specifieke bestemmings-IP's met behulp van iptables. Indien ingeschakeld, kan elke cliënt worden geconfigureerd met toegestane bestemmingen."
|
||||
},
|
||||
"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 getal zijn",
|
||||
"validNumberRange": "{0} moet een geldig getal of bereik 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",
|
||||
"firewallIps": "Firewall-toegestane IPs",
|
||||
"firewallIpsInvalid": "Ongeldige IP-invoer van firewall. Zie documentatie voor ondersteunde syntaxis."
|
||||
},
|
||||
"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",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Waarde of bereik Init packet header (X of X-Y, waarbij X<Y. Min. 5, max. 2147483647. Waarde of bereik mag niet overlappen met andere headers)",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Waarde of bereik Response packet header (X of X-Y, waarbij X<Y. Min. 5, max. 2147483647. Waarde of bereik mag niet overlappen met andere headers)",
|
||||
"h3Label": "Cookie reply magic header (H3)",
|
||||
"h3Description": "Waarde of bereik Cookie reply packet header (X of X-Y, waarbij X<Y. Min. 5, max. 2147483647. Waarde of bereik mag niet overlappen met andere headers)",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Waarde of bereik Transport packet header (X of X-Y, waarbij X<Y. Min. 5, max. 2147483647. Waarde of bereik mag niet overlappen met andere headers)",
|
||||
"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...>",
|
||||
"mtuNote": "Waarden zijn afhankelijk van de MTU",
|
||||
"obfuscationParameters": "AmneziaWG Obfuscation Parameters"
|
||||
}
|
||||
}
|
||||
+122
-65
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Konto",
|
||||
"clients": "Konta",
|
||||
"clients": "Klienci",
|
||||
"admin": {
|
||||
"panel": "Panel administracyjny",
|
||||
"panel": "Panel administratora",
|
||||
"general": "Ogólne",
|
||||
"config": "Konfiguracja",
|
||||
"interface": "Interfejs",
|
||||
@@ -16,22 +16,22 @@
|
||||
"me": {
|
||||
"currentPassword": "Aktualne hasło",
|
||||
"enable2fa": "Włącz uwierzytelnianie dwuskładnikowe",
|
||||
"enable2faDesc": "Zeskanuj kod QR w aplikacji uwierzytelniającej lub wprowadź klucz ręcznie.",
|
||||
"enable2faDesc": "Zeskanuj kod QR aplikacją uwierzytelniającą lub wprowadź klucz ręcznie.",
|
||||
"2faKey": "Klucz TOTP",
|
||||
"2faCodeDesc": "Wprowadź kod z aplikacji uwierzytelniającej.",
|
||||
"disable2fa": "Wyłącz uwierzytelnianie dwuskładnikowe",
|
||||
"disable2faDesc": "Wprowadź swoje hasło, aby wyłączyć uwierzytelnianie dwuskładnikowe."
|
||||
"disable2faDesc": "Wprowadź hasło, aby wyłączyć uwierzytelnianie dwuskładnikowe."
|
||||
},
|
||||
"general": {
|
||||
"name": "Nazwa",
|
||||
"username": "Nazwa użytkownika",
|
||||
"password": "Hasło",
|
||||
"newPassword": "Nowe hasło",
|
||||
"updatePassword": "Zmień hasło",
|
||||
"updatePassword": "Aktualizuj hasło",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Dozwolone adresy IP",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Stałe utrzymywanie połączenia",
|
||||
"persistentKeepalive": "Utrzymywanie połączenia (Keepalive)",
|
||||
"logout": "Wyloguj",
|
||||
"continue": "Kontynuuj",
|
||||
"host": "Host",
|
||||
@@ -44,42 +44,42 @@
|
||||
"2faCode": "Kod TOTP"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Witamy w pierwszej konfiguracji wg-easy",
|
||||
"welcomeDesc": "Znalazłeś najprostszy sposób na instalację i zarządzanie WireGuard na dowolnym serwerze Linux",
|
||||
"existingSetup": "Masz już istniejącą konfigurację?",
|
||||
"createAdminDesc": "Podaj nazwę użytkownika administratora oraz silne, bezpieczne hasło. Informacje te będą używane do logowania w panelu administracyjnym.",
|
||||
"setupConfigDesc": "Podaj informacje o hoście i porcie. Będą one używane w konfiguracji klienta podczas uruchamiania WireGuard na jego urządzeniach.",
|
||||
"setupMigrationDesc": "Podaj plik kopii zapasowej, jeśli chcesz przenieść dane ze starszej wersji wg-easy do nowej instalacji.",
|
||||
"welcome": "Witaj w pierwszej konfiguracji wg-easy",
|
||||
"welcomeDesc": "Znalazłeś najłatwiejszy sposób na instalację i zarządzanie WireGuard na dowolnym hoście Linux",
|
||||
"existingSetup": "Czy masz już istniejącą konfigurację?",
|
||||
"createAdminDesc": "Najpierw wprowadź nazwę użytkownika administratora i silne hasło. Dane te będą używane do logowania się do panelu administracyjnego.",
|
||||
"setupConfigDesc": "Wprowadź informacje o hoście i porcie. Zostaną one użyte do konfiguracji klientów podczas ustawiania WireGuard na ich urządzeniach.",
|
||||
"setupMigrationDesc": "Wskaż plik kopii zapasowej, jeśli chcesz przenieść dane z poprzedniej wersji wg-easy do nowej konfiguracji.",
|
||||
"upload": "Prześlij",
|
||||
"migration": "Przywróć kopię zapasową:",
|
||||
"createAccount": "Utwórz konto",
|
||||
"successful": "Konfiguracja zakończona sukcesem",
|
||||
"hostDesc": "Publiczny host, do którego będą łączyć się klienci",
|
||||
"portDesc": "Publiczny port UDP, na którym WireGuard będzie nasłuchiwał i do którego będą łączyć się klienci"
|
||||
"hostDesc": "Publiczna nazwa hosta, z którą będą łączyć się klienci",
|
||||
"portDesc": "Publiczny port UDP, na którym WireGuard będzie nasłuchiwać i z którym połączą się klienci"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Dostępna jest aktualizacja!",
|
||||
"update": "Aktualizuj"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Motyw ciemny",
|
||||
"light": "Motyw jasny",
|
||||
"dark": "Ciemny motyw",
|
||||
"light": "Jasny motyw",
|
||||
"system": "Motyw systemowy"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Pokaż/ukryj wykresy",
|
||||
"donate": "Wesprzyj"
|
||||
"donate": "Dotacja"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Zaloguj się",
|
||||
"rememberMe": "Zapamiętaj mnie",
|
||||
"rememberMeDesc": "Pozostań zalogowany po zamknięciu przeglądarki",
|
||||
"insecure": "Nie możesz się zalogować przez niezabezpieczone połączenie. Użyj HTTPS.",
|
||||
"2faRequired": "Wymagane uwierzytelnianie dwuskładnikowe",
|
||||
"2faWrong": "Nieprawidłowy kod uwierzytelniania dwuskładnikowego"
|
||||
"insecure": "Nie możesz zalogować się przez niezabezpieczone połączenie. Użyj HTTPS.",
|
||||
"2faRequired": "Wymagane jest uwierzytelnianie dwuskładnikowe",
|
||||
"2faWrong": "Błędny kod uwierzytelniania dwuskładnikowego"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Brak klientów.",
|
||||
"empty": "Nie ma jeszcze żadnych klientów.",
|
||||
"newShort": "Nowy",
|
||||
"sort": "Sortuj",
|
||||
"create": "Utwórz klienta",
|
||||
@@ -87,36 +87,44 @@
|
||||
"new": "Nowy klient",
|
||||
"name": "Nazwa",
|
||||
"expireDate": "Data wygaśnięcia",
|
||||
"expireDateDesc": "Data, po której klient zostanie wyłączony. Puste = na stałe",
|
||||
"expireDateDesc": "Data, w której klient zostanie wyłączony. Pozostaw puste dla bezterminowego dostępu",
|
||||
"delete": "Usuń",
|
||||
"deleteClient": "Usuń klienta",
|
||||
"deleteDialog1": "Czy na pewno chcesz usunąć",
|
||||
"deleteDialog2": "Tej akcji nie można cofnąć.",
|
||||
"deleteDialog1": "Czy na pewno chcesz usunąć klienta",
|
||||
"deleteDialog2": "Tej operacji nie można cofnąć.",
|
||||
"enabled": "Włączony",
|
||||
"address": "Adres",
|
||||
"serverAllowedIps": "Dozwolone adresy IP serwera",
|
||||
"otlDesc": "Wygeneruj jednorazowy krótki link",
|
||||
"otlDesc": "Generuj krótki link jednorazowy",
|
||||
"permanent": "Stały",
|
||||
"createdOn": "Utworzony ",
|
||||
"lastSeen": "Ostatnio widziany ",
|
||||
"totalDownload": "Łączne pobieranie: ",
|
||||
"totalUpload": "Łączne wysyłanie: ",
|
||||
"createdOn": "Utworzono: ",
|
||||
"lastSeen": "Ostatnio widziany: ",
|
||||
"totalDownload": "Pobieranie łącznie: ",
|
||||
"totalUpload": "Wysyłanie łącznie: ",
|
||||
"newClient": "Nowy klient",
|
||||
"disableClient": "Wyłącz klienta",
|
||||
"enableClient": "Włącz klienta",
|
||||
"noPrivKey": "Ten klient nie ma znanego klucza prywatnego. Nie można utworzyć konfiguracji.",
|
||||
"noPrivKey": "Ten klient nie posiada klucza prywatnego. Nie można utworzyć konfiguracji.",
|
||||
"showQR": "Pokaż kod QR",
|
||||
"downloadConfig": "Pobierz konfigurację",
|
||||
"allowedIpsDesc": "Które adresy IP będą kierowane przez VPN (nadpisuje konfigurację globalną)",
|
||||
"serverAllowedIpsDesc": "Które adresy IP serwer będzie kierował do klienta",
|
||||
"mtuDesc": "Ustawia maksymalny rozmiar pakietu (MTU) dla tunelu VPN",
|
||||
"persistentKeepaliveDesc": "Ustawia interwał (w sekundach) wysyłania pakietów keep-alive. 0 = wyłączone",
|
||||
"allowedIpsDesc": "Adresy IP kierowane przez VPN (nadpisuje konfigurację globalną)",
|
||||
"serverAllowedIpsDesc": "Adresy IP, które serwer będzie kierował do klienta",
|
||||
"mtuDesc": "Ustawia maksymalną jednostkę transmisji (rozmiar pakietu) dla tunelu VPN",
|
||||
"persistentKeepaliveDesc": "Ustawia interwał (w sekundach) dla pakietów utrzymujących połączenie. 0 wyłącza.",
|
||||
"hooks": "Hooki",
|
||||
"hooksDescription": "Hooki działają tylko z wg-quick",
|
||||
"hooksLeaveEmpty": "Tylko dla wg-quick. W innym przypadku pozostaw puste",
|
||||
"dnsDesc": "Serwer DNS, którego będą używać klienci (nadpisuje konfigurację globalną)",
|
||||
"notConnected": "Klient nie jest połączony",
|
||||
"hooksLeaveEmpty": "Tylko dla wg-quick. W przeciwnym razie pozostaw puste",
|
||||
"dnsDesc": "Serwer DNS dla klientów (nadpisuje konfigurację globalną)",
|
||||
"notConnected": "Klient niepołączony",
|
||||
"endpoint": "Punkt końcowy",
|
||||
"endpointDesc": "Adres IP klienta, z którego ustanawiane jest połączenie WireGuard"
|
||||
"endpointDesc": "Adres IP klienta, z którego ustanowiono połączenie WireGuard",
|
||||
"search": "Szukaj klientów...",
|
||||
"config": "Konfiguracja",
|
||||
"viewConfig": "Zobacz konfigurację",
|
||||
"firewallIps": "Dozwolone IP zapory",
|
||||
"firewallIpsDesc": "Docelowe adresy IP/CIDR, do których ten klient ma dostęp (wymuszane po stronie serwera). Pozostaw puste, aby użyć Dozwolonych IP. Obsługuje opcjonalne filtrowanie portów i protokołów. Zobacz dokumentację dla składni.",
|
||||
"downloadPng": "Pobierz PNG",
|
||||
"copyPng": "Kopiuj PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Zmień",
|
||||
@@ -126,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Sukces",
|
||||
"saved": "Zapisano",
|
||||
"error": "Błąd"
|
||||
"error": "Błąd",
|
||||
"unknown": "Nieznany błąd. Sprawdź konsolę, aby uzyskać więcej szczegółów"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Akcje",
|
||||
@@ -135,16 +144,16 @@
|
||||
"sectionGeneral": "Ogólne",
|
||||
"sectionAdvanced": "Zaawansowane",
|
||||
"noItems": "Brak elementów",
|
||||
"nullNoItems": "Brak elementów. Używana konfiguracja globalna",
|
||||
"nullNoItems": "Brak elementów. Używanie konfiguracji globalnej",
|
||||
"add": "Dodaj"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Limit czasu sesji",
|
||||
"sessionTimeoutDesc": "Czas trwania sesji dla opcji Zapamiętaj mnie (w sekundach)",
|
||||
"sessionTimeoutDesc": "Czas trwania sesji dla 'Zapamiętaj mnie' (w sekundach)",
|
||||
"metrics": "Metryki",
|
||||
"metricsPassword": "Hasło",
|
||||
"metricsPasswordDesc": "Hasło Bearer dla endpointu metryk (hasło lub hash argon2)",
|
||||
"metricsPasswordDesc": "Hasło Bearer dla punktu końcowego metryk (hasło lub hash argon2)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Ścieżka dla metryk w formacie JSON",
|
||||
"prometheus": "Prometheus",
|
||||
@@ -152,57 +161,63 @@
|
||||
},
|
||||
"config": {
|
||||
"connection": "Połączenie",
|
||||
"hostDesc": "Publiczny host, do którego będą łączyć się klienci (unieważnia konfigurację)",
|
||||
"portDesc": "Publiczny port UDP, do którego będą łączyć się klienci (unieważnia konfigurację, prawdopodobnie należy też zmienić port interfejsu)",
|
||||
"hostDesc": "Publiczna nazwa hosta, z którą będą łączyć się klienci (unieważnia konfigurację)",
|
||||
"portDesc": "Publiczny port UDP klientów (unieważnia konfigurację; zaleca się także zmianę Portu Interfejsu)",
|
||||
"allowedIpsDesc": "Dozwolone adresy IP klientów (konfiguracja globalna)",
|
||||
"dnsDesc": "Serwer DNS klientów (konfiguracja globalna)",
|
||||
"mtuDesc": "MTU klientów (tylko dla nowych klientów)",
|
||||
"persistentKeepaliveDesc": "Interwał w sekundach dla keepalive do serwera. 0 = wyłączone (tylko dla nowych klientów)",
|
||||
"persistentKeepaliveDesc": "Interwał wysyłania pakietów keepalive do serwera (sekundy). 0 = wyłączone (tylko dla nowych klientów)",
|
||||
"suggest": "Sugeruj",
|
||||
"suggestDesc": "Wybierz adres IP lub nazwę hosta dla pola Host"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "Zmieniono CIDR",
|
||||
"device": "Urządzenie",
|
||||
"deviceDesc": "Urządzenie sieciowe, przez które ma być przekazywany ruch WireGuard",
|
||||
"mtuDesc": "MTU używane przez WireGuard",
|
||||
"portDesc": "Port UDP, na którym WireGuard będzie nasłuchiwał (prawdopodobnie trzeba też zmienić port w konfiguracji)",
|
||||
"deviceDesc": "Interfejs sieciowy, przez który ma być przekazywany ruch WireGuard",
|
||||
"mtuDesc": "MTU, którego będzie używać WireGuard",
|
||||
"portDesc": "Port UDP, na którym będzie nasłuchiwać WireGuard (zaleca się także zmianę Portu Konfiguracji)",
|
||||
"changeCidr": "Zmień CIDR",
|
||||
"restart": "Restart interfejsu",
|
||||
"restart": "Restartuj interfejs",
|
||||
"restartDesc": "Zrestartuj interfejs WireGuard",
|
||||
"restartWarn": "Czy na pewno chcesz zrestartować interfejs? Wszyscy klienci zostaną rozłączeni.",
|
||||
"restartSuccess": "Interfejs zrestartowany"
|
||||
"restartWarn": "Czy na pewno chcesz zrestartować interfejs? Spowoduje to rozłączenie wszystkich klientów.",
|
||||
"restartSuccess": "Interfejs zrestartowany",
|
||||
"firewall": "Filtrowanie ruchu",
|
||||
"firewallEnabled": "Włącz zaporę per-klient",
|
||||
"firewallEnabledDesc": "Ogranicz ruch klienta do określonych docelowych adresów IP za pomocą iptables. Gdy włączone, każdy klient może mieć skonfigurowane dozwolone cele."
|
||||
},
|
||||
"introText": "Witamy w panelu administracyjnym.\n\nTutaj możesz zarządzać ustawieniami ogólnymi, konfiguracją, interfejsem i hookami.\n\nZacznij od wybrania jednej z sekcji w pasku bocznym."
|
||||
"introText": "Witaj w panelu administratora.\n\nTutaj możesz zarządzać ustawieniami ogólnymi, konfiguracją, ustawieniami interfejsu i hookami.\n\nZacznij od wybrania jednej z sekcji na pasku bocznym."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} jest wymagane",
|
||||
"validNumber": "{0} musi być prawidłową liczbą",
|
||||
"validString": "{0} musi być prawidłowym tekstem",
|
||||
"validNumberRange": "{0} musi być prawidłową liczbą lub zakresem liczb",
|
||||
"validString": "{0} musi być prawidłowym ciągiem znaków",
|
||||
"validBoolean": "{0} musi być prawidłową wartością logiczną",
|
||||
"validArray": "{0} musi być prawidłową tablicą",
|
||||
"stringMin": "{0} musi mieć co najmniej {1} znaków",
|
||||
"numberMin": "{0} musi być co najmniej {1}"
|
||||
"numberMin": "{0} musi wynosić co najmniej {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID klienta",
|
||||
"name": "Nazwa",
|
||||
"expiresAt": "Wygasa",
|
||||
"expiresAt": "Wygasa dnia",
|
||||
"address4": "Adres IPv4",
|
||||
"address6": "Adres IPv6",
|
||||
"serverAllowedIps": "Dozwolone adresy IP serwera"
|
||||
"serverAllowedIps": "Dozwolone IP serwerowe",
|
||||
"firewallIps": "Dozwolone IP zapory",
|
||||
"firewallIpsInvalid": "Nieprawidłowy wpis IP zapory. Zobacz dokumentację dla obsługiwanej składni."
|
||||
},
|
||||
"user": {
|
||||
"username": "Nazwa użytkownika",
|
||||
"password": "Hasło",
|
||||
"remember": "Zapamiętaj",
|
||||
"name": "Imię",
|
||||
"name": "Nazwa",
|
||||
"email": "E-mail",
|
||||
"emailInvalid": "E-mail musi być prawidłowy",
|
||||
"emailInvalid": "E-mail musi być prawidłowym adresem",
|
||||
"passwordMatch": "Hasła muszą się zgadzać",
|
||||
"totpEnable": "Włącz TOTP",
|
||||
"totpEnableTrue": "TOTP musi być włączone",
|
||||
"totpEnableTrue": "Włączenie TOTP musi mieć wartość prawda",
|
||||
"totpCode": "Kod TOTP"
|
||||
},
|
||||
"userConfig": {
|
||||
@@ -211,24 +226,24 @@
|
||||
"general": {
|
||||
"sessionTimeout": "Limit czasu sesji",
|
||||
"metricsEnabled": "Metryki",
|
||||
"metricsPassword": "Hasło do metryk"
|
||||
"metricsPassword": "Hasło metryk"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Urządzenie",
|
||||
"cidrValid": "CIDR musi być prawidłowy"
|
||||
},
|
||||
"otl": "Jednorazowy link",
|
||||
"stringMalformed": "Nieprawidłowy format tekstu",
|
||||
"body": "Treść musi być prawidłowym obiektem",
|
||||
"otl": "Link jednorazowy",
|
||||
"stringMalformed": "Ciąg znaków jest zniekształcony",
|
||||
"body": "Body musi być prawidłowym obiektem",
|
||||
"hook": "Hook",
|
||||
"enabled": "Włączone",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Stałe utrzymywanie połączenia",
|
||||
"persistentKeepalive": "Utrzymywanie połączenia",
|
||||
"address": "Adres IP",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Dozwolone adresy IP",
|
||||
"allowedIps": "Dozwolone IP",
|
||||
"file": "Plik"
|
||||
},
|
||||
"hooks": {
|
||||
@@ -236,5 +251,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopiowanie nie jest obsługiwane",
|
||||
"copied": "Skopiowano!",
|
||||
"failed": "Kopiowanie nieudane",
|
||||
"copy": "Kopiuj"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Liczba pakietów śmieci (Jc)",
|
||||
"jCDescription": "Liczba pakietów śmieci do wysłania (1-128, zalecane: 4-12)",
|
||||
"jMinLabel": "Minimalny rozmiar pakietu śmieci (Jmin)",
|
||||
"jMinDescription": "Minimalny rozmiar pakietów śmieci (0-1279*, zalecane: 8, musi być < Jmax)",
|
||||
"jMaxLabel": "Maksymalny rozmiar pakietu śmieci (Jmax)",
|
||||
"jMaxDescription": "Maksymalny rozmiar pakietów śmieci (1-1280*, zalecane: 80, musi być > Jmin)",
|
||||
"s1Label": "Rozmiar śmieci pakietu inicjującego (S1)",
|
||||
"s1Description": "Rozmiar śmieci pakietu inicjującego (0-1132, zalecane: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Rozmiar śmieci pakietu odpowiedzi (S2)",
|
||||
"s2Description": "Rozmiar śmieci pakietu odpowiedzi (0-1188, zalecane: 15-150)",
|
||||
"s3Label": "Rozmiar śmieci pakietu odpowiedzi cookie (S3)",
|
||||
"s3Description": "Rozmiar śmieci pakietu odpowiedzi cookie",
|
||||
"s4Label": "Rozmiar śmieci pakietu transportowego (S4)",
|
||||
"s4Description": "Rozmiar śmieci pakietu transportowego",
|
||||
"h1Label": "Magiczny nagłówek inicjujący (H1)",
|
||||
"h1Description": "Wartość lub zakres nagłówka pakietu inicjującego (X lub X-Y, gdzie X < Y. Min 5, max 2147483647. Wartości nie mogą nakładać się na inne nagłówki)",
|
||||
"h2Label": "Magiczny nagłówek odpowiedzi (H2)",
|
||||
"h2Description": "Wartość lub zakres nagłówka pakietu odpowiedzi (X lub X-Y, gdzie X < Y. Min 5, max 2147483647. Wartości nie mogą nakładać się na inne nagłówki)",
|
||||
"h3Label": "Magiczny nagłówek odpowiedzi cookie (H3)",
|
||||
"h3Description": "Wartość lub zakres nagłówka pakietu odpowiedzi cookie (X lub X-Y, gdzie X < Y. Min 5, max 2147483647. Wartości nie mogą nakładać się na inne nagłówki)",
|
||||
"h4Label": "Magiczny nagłówek transportowy (H4)",
|
||||
"h4Description": "Wartość lub zakres nagłówka pakietu transportowego (X lub X-Y, gdzie X < Y. Min 5, max 2147483647. Wartości nie mogą nakładać się na inne nagłówki)",
|
||||
"i1Label": "Specjalny pakiet śmieci 1 (I1)",
|
||||
"i1Description": "Pakiet imitujący protokół w formacie hex: <b 0x...>",
|
||||
"i2Label": "Specjalny pakiet śmieci 2 (I2)",
|
||||
"i2Description": "Pakiet imitujący protokół w formacie hex: <b 0x...>",
|
||||
"i3Label": "Specjalny pakiet śmieci 3 (I3)",
|
||||
"i3Description": "Pakiet imitujący protokół w formacie hex: <b 0x...>",
|
||||
"i4Label": "Specjalny pakiet śmieci 4 (I4)",
|
||||
"i4Description": "Pakiet imitujący protokół w formacie hex: <b 0x...>",
|
||||
"i5Label": "Specjalny pakiet śmieci 5 (I5)",
|
||||
"i5Description": "Pakiet imitujący protokół w formacie hex: <b 0x...>",
|
||||
"mtuNote": "Wartości zależą od MTU",
|
||||
"obfuscationParameters": "Parametry maskowania AmneziaWG"
|
||||
}
|
||||
}
|
||||
|
||||
+48
-37
@@ -6,7 +6,7 @@
|
||||
"panel": "Админ-панель",
|
||||
"general": "Общие настройки",
|
||||
"config": "Конфигурация",
|
||||
"interface": "Интерфейс",
|
||||
"interface": "Сетевой интерфейс",
|
||||
"hooks": "Хуки"
|
||||
}
|
||||
},
|
||||
@@ -110,7 +110,7 @@
|
||||
"allowedIpsDesc": "Какие IP‑адреса будут маршрутизироваться через VPN (переопределяет глобальную конфигурацию)",
|
||||
"serverAllowedIpsDesc": "Какие IP‑адреса сервер будет отправлять клиенту",
|
||||
"mtuDesc": "Максимальный размер пакета (MTU) для VPN‑туннеля",
|
||||
"persistentKeepaliveDesc": "Устанавливает интервал (в секундах) для пакетов поддержания соединения. 0 — отключить",
|
||||
"persistentKeepaliveDesc": "Устанавливает интервал (в секундах) для пакетов поддержания соединения. 0 — Отключить",
|
||||
"hooks": "Хуки",
|
||||
"hooksDescription": "Хуки работают только с wg‑quick",
|
||||
"hooksLeaveEmpty": "Только для wg‑quick. В остальных случаях оставьте пустым",
|
||||
@@ -120,7 +120,11 @@
|
||||
"endpointDesc": "IP‑адрес клиента, с которого установлено соединение WireGuard",
|
||||
"search": "Поиск клиентов...",
|
||||
"config": "Конфигурация",
|
||||
"viewConfig": "Просмотреть конфигурацию"
|
||||
"viewConfig": "Просмотреть конфигурацию",
|
||||
"firewallIps": "Разрешённые фаерволом IP-адреса",
|
||||
"firewallIpsDesc": "IP‑адреса/CIDR-диапазоны, к которым может получить доступ клиент (проверка на сервере). Оставьте пустым, будут использоваться «Разрешённые IP‑адреса» (AllowedIPs). Поддерживается фильтрация по портам и протоколам. Подробности см. в документации.",
|
||||
"downloadPng": "Скачать PNG",
|
||||
"copyPng": "Копировать PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Изменить",
|
||||
@@ -130,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Успешно",
|
||||
"saved": "Сохранено",
|
||||
"error": "Ошибка"
|
||||
"error": "Ошибка",
|
||||
"unknown": "Неизвестная ошибка. Подробности см. в консоли браузера"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Действия",
|
||||
@@ -170,12 +175,15 @@
|
||||
"device": "Устройство",
|
||||
"deviceDesc": "Сетевое устройство Ethernet, через которое должен проходить трафик WireGuard",
|
||||
"mtuDesc": "MTU, который будет использовать WireGuard",
|
||||
"portDesc": "UDP‑порт, на котором будет слушать WireGuard (возможно, нужно также изменить порт конфигурации)",
|
||||
"portDesc": "UDP‑порт, на котором будет слушать WireGuard (возможно, также нужно изменить порт в конфигурации)",
|
||||
"changeCidr": "Изменить CIDR",
|
||||
"restart": "Перезапустить интерфейс",
|
||||
"restartDesc": "Перезапустить интерфейс WireGuard",
|
||||
"restartWarn": "Вы уверены, что хотите перезапустить интерфейс? Это приведёт к отключению всех клиентов.",
|
||||
"restartSuccess": "Интерфейс перезапущен"
|
||||
"restartDesc": "Перезапустить сетевой интерфейс WireGuard",
|
||||
"restartWarn": "Вы уверены, что хотите перезапустить сетевой интерфейс? Это приведёт к отключению всех клиентов.",
|
||||
"restartSuccess": "Интерфейс перезапущен",
|
||||
"firewall": "Фильтрация трафика",
|
||||
"firewallEnabled": "Включить фаервол для отдельных клиентов",
|
||||
"firewallEnabledDesc": "Ограничить трафик клиентов до определённых IP‑адресов с помощью iptables. При включении для каждого клиента можно настроить список разрешённых адресов."
|
||||
},
|
||||
"introText": "Добро пожаловать в панель администратора.\n\nЗдесь вы можете управлять общими настройками, конфигурацией, настройками интерфейса и хуками.\n\nНачните с выбора одного из разделов на боковой панели."
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0} обязательно для заполнения",
|
||||
"validNumber": "{0} должно быть числом",
|
||||
"validNumberRange": "{0} должно быть числом или диапазоном чисел",
|
||||
"validString": "{0} должно быть строкой",
|
||||
"validBoolean": "{0} должно быть логическим значением",
|
||||
"validArray": "{0} должно быть массивом",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "Дата окончания действия",
|
||||
"address4": "IPv4‑адрес",
|
||||
"address6": "IPv6‑адрес",
|
||||
"serverAllowedIps": "Разрешённые IP‑адреса сервера"
|
||||
"serverAllowedIps": "Разрешённые IP‑адреса сервера",
|
||||
"firewallIps": "Разрешённые фаерволом IP-адреса",
|
||||
"firewallIpsInvalid": "Некорректная запись IP-адреса для фаервола. Поддерживаемый синтаксис см. в документации"
|
||||
},
|
||||
"user": {
|
||||
"username": "Имя пользователя",
|
||||
@@ -248,38 +259,38 @@
|
||||
"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...>",
|
||||
"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": "Размер мусорных данных в транспортном пакете",
|
||||
"h1Label": "Init magic заголовок (H1)",
|
||||
"h1Description": "Значение заголовка init-пакета (5-2147483647, должно отличаться от H2-H4)",
|
||||
"h1Description": "Значение или диапазон заголовка init-пакета (X или X-Y, где X < Y. От 5 до 2147483647. Диапазоны H1–H4 не должны пересекаться между собой)",
|
||||
"h2Label": "Response magic заголовок (H2)",
|
||||
"h2Description": "Значение заголовка ответного пакета (5-2147483647, должно отличаться от H1, H3, H4)",
|
||||
"h2Description": "Значение или диапазон заголовка ответного пакета (X или X-Y, где X < Y. От 5 до 2147483647. Диапазоны H1–H4 не должны пересекаться между собой)",
|
||||
"h3Label": "Cookie reply magic заголовок (H3)",
|
||||
"h3Description": "Значение заголовка cookie-reply пакета (5-2147483647, должно отличаться от H1, H2, H4)",
|
||||
"h3Description": "Значение или диапазон заголовка cookie-reply пакета (X или X-Y, где X < Y. От 5 до 2147483647. Диапазоны H1–H4 не должны пересекаться между собой)",
|
||||
"h4Label": "Transport magic заголовок (H4)",
|
||||
"h4Description": "Значение заголовка транспортного пакета (5-2147483647, должно отличаться от H1-H3)",
|
||||
"h4Description": "Значение или диапазон заголовка транспортного пакета (X или X-Y, где X < Y. От 5 до 2147483647. Диапазоны H1–H4 не должны пересекаться между собой)",
|
||||
"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...>",
|
||||
"mtuNote": "Значения зависят от MTU",
|
||||
"obfuscationParameters": "Параметры обфускации AmneziaWG"
|
||||
}
|
||||
|
||||
+160
-103
@@ -7,7 +7,7 @@
|
||||
"general": "Genel",
|
||||
"config": "Yapılandırma",
|
||||
"interface": "Arayüz",
|
||||
"hooks": "Hook'lar"
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
@@ -15,56 +15,56 @@
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Mevcut Şifre",
|
||||
"enable2fa": "İki Faktörlü Kimlik Doğrulamayı Etkinleştir",
|
||||
"enable2faDesc": "QR kodunu kimlik doğrulayıcı uygulamanızla tarayın veya anahtarı manuel olarak girin.",
|
||||
"enable2fa": "2FA'yı Etkinleştir",
|
||||
"enable2faDesc": "Kimlik doğrulama uygulamanızla QR kodunu tarayın veya anahtarı manuel olarak girin.",
|
||||
"2faKey": "TOTP Anahtarı",
|
||||
"2faCodeDesc": "Kimlik doğrulayıcı uygulamanızdan kodu girin.",
|
||||
"disable2fa": "İki Faktörlü Kimlik Doğrulamayı Devre Dışı Bırak",
|
||||
"disable2faDesc": "İki Faktörlü Kimlik Doğrulamayı devre dışı bırakmak için şifrenizi girin."
|
||||
"2faCodeDesc": "Uygulamanızdaki doğrulama kodunu girin.",
|
||||
"disable2fa": "2FA'yı Devre Dışı Bırak",
|
||||
"disable2faDesc": "2FA'yı kapatmak için şifrenizi girin."
|
||||
},
|
||||
"general": {
|
||||
"name": "Ad",
|
||||
"name": "İsim",
|
||||
"username": "Kullanıcı Adı",
|
||||
"password": "Şifre",
|
||||
"newPassword": "Yeni Şifre",
|
||||
"updatePassword": "Şifreyi Güncelle",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "İzin Verilen IP'ler",
|
||||
"allowedIps": "Allowed IPs",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Kalıcı Keepalive",
|
||||
"persistentKeepalive": "Persistent Keepalive",
|
||||
"logout": "Çıkış Yap",
|
||||
"continue": "Devam Et",
|
||||
"host": "Ana Bilgisayar",
|
||||
"host": "Host",
|
||||
"port": "Port",
|
||||
"yes": "Evet",
|
||||
"no": "Hayır",
|
||||
"confirmPassword": "Şifreyi Onayla",
|
||||
"loading": "Yükleniyor...",
|
||||
"2fa": "İki Faktörlü Kimlik Doğrulama",
|
||||
"2fa": "2FA (İki Faktörlü Doğrulama)",
|
||||
"2faCode": "TOTP Kodu"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "wg-easy ilk kurulumunuza hoş geldiniz",
|
||||
"welcomeDesc": "Herhangi bir Linux ana bilgisayarda WireGuard kurmanın ve yönetmenin en kolay yolunu buldunuz",
|
||||
"welcome": "wg-easy kurulumuna hoş geldiniz",
|
||||
"welcomeDesc": "Linux üzerinde WireGuard kurmanın ve yönetmenin en kolay yolu.",
|
||||
"existingSetup": "Mevcut bir kurulumunuz var mı?",
|
||||
"createAdminDesc": "Lütfen önce bir yönetici kullanıcı adı ve güçlü bir güvenli şifre girin. Bu bilgiler yönetim panelinize giriş yapmak için kullanılacaktır.",
|
||||
"setupConfigDesc": "Lütfen ana bilgisayar ve port bilgilerini girin. Bu, cihazlarında WireGuard kurulumu yaparken istemci yapılandırması için kullanılacaktır.",
|
||||
"setupMigrationDesc": "Verilerinizi önceki wg-easy sürümünüzden yeni kurulumunuza taşımak istiyorsanız yedekleme dosyasını sağlayın.",
|
||||
"createAdminDesc": "Yönetim paneline giriş için bir kullanıcı adı ve güçlü bir şifre belirleyin.",
|
||||
"setupConfigDesc": "İstemci cihazların bağlanacağı Host ve Port bilgilerini girin.",
|
||||
"setupMigrationDesc": "Eski wg-easy verilerinizi taşımak için yedek dosyasını yükleyebilirsiniz.",
|
||||
"upload": "Yükle",
|
||||
"migration": "Yedeği geri yükle:",
|
||||
"migration": "Yedeği Geri Yükle:",
|
||||
"createAccount": "Hesap Oluştur",
|
||||
"successful": "Kurulum başarılı",
|
||||
"hostDesc": "İstemcilerin bağlanacağı genel ana bilgisayar adı",
|
||||
"portDesc": "İstemcilerin bağlanacağı ve WireGuard'ın dinleyeceği genel UDP portu"
|
||||
"successful": "Kurulum Başarılı",
|
||||
"hostDesc": "İstemcilerin bağlanacağı public hostname/IP",
|
||||
"portDesc": "WireGuard'ın dinleyeceği public UDP portu"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Güncelleme mevcut!",
|
||||
"updateAvailable": "Yeni bir güncelleme mevcut!",
|
||||
"update": "Güncelle"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Koyu tema",
|
||||
"light": "Açık tema",
|
||||
"system": "Sistem teması"
|
||||
"dark": "Koyu Tema",
|
||||
"light": "Açık Tema",
|
||||
"system": "Sistem Teması"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Grafikleri Göster/Gizle",
|
||||
@@ -73,50 +73,58 @@
|
||||
"login": {
|
||||
"signIn": "Giriş Yap",
|
||||
"rememberMe": "Beni hatırla",
|
||||
"rememberMeDesc": "Tarayıcıyı kapattıktan sonra giriş yapmış olarak kal",
|
||||
"insecure": "Güvensiz bir bağlantı ile giriş yapamazsınız. HTTPS kullanın.",
|
||||
"2faRequired": "İki Faktörlü Kimlik Doğrulama gerekli",
|
||||
"2faWrong": "İki Faktörlü Kimlik Doğrulama yanlış"
|
||||
"rememberMeDesc": "Oturumu açık tut",
|
||||
"insecure": "Güvensiz bağlantı üzerinden giriş yapılamaz. Lütfen HTTPS kullanın.",
|
||||
"2faRequired": "2FA Doğrulaması Gerekli",
|
||||
"2faWrong": "Hatalı 2FA Kodu"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Henüz istemci yok.",
|
||||
"empty": "Henüz kayıtlı bir istemci yok.",
|
||||
"newShort": "Yeni",
|
||||
"sort": "Sırala",
|
||||
"create": "İstemci Oluştur",
|
||||
"created": "İstemci oluşturuldu",
|
||||
"new": "Yeni İstemci",
|
||||
"name": "Ad",
|
||||
"name": "İsim",
|
||||
"expireDate": "Son Kullanma Tarihi",
|
||||
"expireDateDesc": "İstemcinin devre dışı bırakılacağı tarih. Kalıcı için boş bırakın",
|
||||
"expireDateDesc": "Boş bırakılırsa süresiz olur.",
|
||||
"delete": "Sil",
|
||||
"deleteClient": "İstemciyi Sil",
|
||||
"deleteDialog1": "Silmek istediğinizden emin misiniz",
|
||||
"deleteDialog2": "Bu eylem geri alınamaz.",
|
||||
"enabled": "Etkin",
|
||||
"deleteDialog1": "Silmek istediğinize emin misiniz",
|
||||
"deleteDialog2": "Bu işlem geri alınamaz.",
|
||||
"enabled": "Aktif",
|
||||
"address": "Adres",
|
||||
"serverAllowedIps": "Sunucu İzin Verilen IP'ler",
|
||||
"otlDesc": "Kısa tek seferlik bağlantı oluştur",
|
||||
"permanent": "Kalıcı",
|
||||
"createdOn": "Oluşturulma tarihi ",
|
||||
"lastSeen": "Son görülme ",
|
||||
"serverAllowedIps": "Server Allowed IPs",
|
||||
"otlDesc": "Tek seferlik kısa link oluştur",
|
||||
"permanent": "Süresiz",
|
||||
"createdOn": "Oluşturulma: ",
|
||||
"lastSeen": "Son Görülme: ",
|
||||
"totalDownload": "Toplam İndirme: ",
|
||||
"totalUpload": "Toplam Yükleme: ",
|
||||
"newClient": "Yeni İstemci",
|
||||
"disableClient": "İstemciyi Devre Dışı Bırak",
|
||||
"enableClient": "İstemciyi Etkinleştir",
|
||||
"noPrivKey": "Bu istemcinin bilinen özel anahtarı yok. Yapılandırma oluşturulamıyor.",
|
||||
"noPrivKey": "Özel anahtar (private key) bulunamadı. Yapılandırma oluşturulamaz.",
|
||||
"showQR": "QR Kodunu Göster",
|
||||
"downloadConfig": "Yapılandırmayı İndir",
|
||||
"allowedIpsDesc": "Hangi IP'lerin VPN üzerinden yönlendirileceği (genel yapılandırmayı geçersiz kılar)",
|
||||
"downloadConfig": "Config İndir",
|
||||
"allowedIpsDesc": "VPN üzerinden yönlendirilecek IP'ler (global ayarı ezer)",
|
||||
"serverAllowedIpsDesc": "Sunucunun istemciye yönlendireceği IP'ler",
|
||||
"mtuDesc": "VPN tüneli için maksimum iletim birimini (paket boyutu) ayarlar",
|
||||
"persistentKeepaliveDesc": "Keepalive paketleri için aralığı (saniye cinsinden) ayarlar. 0 devre dışı bırakır",
|
||||
"hooks": "Hook'lar",
|
||||
"hooksDescription": "Hook'lar sadece wg-quick ile çalışır",
|
||||
"hooksLeaveEmpty": "Sadece wg-quick için. Aksi takdirde boş bırakın",
|
||||
"dnsDesc": "İstemcilerin kullanacağı DNS sunucusu (genel yapılandırmayı geçersiz kılar)",
|
||||
"notConnected": "İstemci bağlı değil",
|
||||
"endpoint": "Uç Nokta",
|
||||
"endpointDesc": "WireGuard bağlantısının kurulduğu istemcinin IP'si"
|
||||
"mtuDesc": "VPN tüneli için paket boyutu (MTU)",
|
||||
"persistentKeepaliveDesc": "Bağlantıyı ayakta tutma aralığı (saniye). 0 devre dışı bırakır.",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks sadece wg-quick ile çalışır",
|
||||
"hooksLeaveEmpty": "Sadece wg-quick içindir. Aksi halde boş bırakın.",
|
||||
"dnsDesc": "İstemci DNS sunucuları (global ayarı ezer)",
|
||||
"notConnected": "Bağlı Değil",
|
||||
"endpoint": "Endpoint",
|
||||
"endpointDesc": "İstemcinin WireGuard bağlantısı kurduğu IP adresi",
|
||||
"search": "İstemci ara...",
|
||||
"config": "Config",
|
||||
"viewConfig": "Config Görüntüle",
|
||||
"firewallIps": "Firewall Allowed IPs",
|
||||
"firewallIpsDesc": "İstemcinin erişebileceği hedef IP/CIDR'ler (isteğe bağlı port/protokol filtreleme ile). Boş bırakılırsa Allowed IPs kullanılır. Ayrıntılı söz dizimi için dokümantasyona bakın.",
|
||||
"downloadPng": "PNG İndir",
|
||||
"copyPng": "PNG Kopyala"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Değiştir",
|
||||
@@ -126,109 +134,116 @@
|
||||
"toast": {
|
||||
"success": "Başarılı",
|
||||
"saved": "Kaydedildi",
|
||||
"error": "Hata"
|
||||
"error": "Hata",
|
||||
"unknown": "Bilinmeyen hata. Detaylar için konsola bakın."
|
||||
},
|
||||
"form": {
|
||||
"actions": "Eylemler",
|
||||
"actions": "İşlemler",
|
||||
"save": "Kaydet",
|
||||
"revert": "Geri Al",
|
||||
"sectionGeneral": "Genel",
|
||||
"sectionAdvanced": "Gelişmiş",
|
||||
"noItems": "Öğe yok",
|
||||
"nullNoItems": "Öğe yok. Genel yapılandırma kullanılıyor",
|
||||
"noItems": "Öge yok",
|
||||
"nullNoItems": "Öge yok. Global ayarlar kullanılıyor.",
|
||||
"add": "Ekle"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Oturum Zaman Aşımı",
|
||||
"sessionTimeoutDesc": "Beni Hatırla için oturum süresi (saniye)",
|
||||
"sessionTimeoutDesc": "Beni Hatırla süresi (saniye)",
|
||||
"metrics": "Metrikler",
|
||||
"metricsPassword": "Şifre",
|
||||
"metricsPasswordDesc": "Metrik uç noktası için Bearer şifresi (şifre veya argon2 hash)",
|
||||
"metricsPasswordDesc": "Metrics endpoint'i için Bearer şifresi (argon2 hash destekler)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "JSON formatında metrikler için rota",
|
||||
"jsonDesc": "JSON metrik rotası",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Prometheus metrikleri için rota"
|
||||
"prometheusDesc": "Prometheus metrik rotası"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Bağlantı",
|
||||
"hostDesc": "İstemcilerin bağlanacağı genel ana bilgisayar adı (yapılandırmayı geçersiz kılar)",
|
||||
"portDesc": "İstemcilerin bağlanacağı genel UDP portu (yapılandırmayı geçersiz kılar, muhtemelen Arayüz Portunu da değiştirmek isteyeceksiniz)",
|
||||
"allowedIpsDesc": "İstemcilerin kullanacağı İzin Verilen IP'ler (genel yapılandırma)",
|
||||
"dnsDesc": "İstemcilerin kullanacağı DNS sunucusu (genel yapılandırma)",
|
||||
"mtuDesc": "İstemcilerin kullanacağı MTU (sadece yeni istemciler için)",
|
||||
"persistentKeepaliveDesc": "Sunucuya keepalive göndermek için saniye cinsinden aralık. 0 = devre dışı (sadece yeni istemciler için)",
|
||||
"hostDesc": "İstemcilerin bağlanacağı Host (configleri etkiler)",
|
||||
"portDesc": "İstemcilerin bağlanacağı UDP portu. Bunu değiştirmek mevcut istemci yapılandırmalarını geçersiz kılabilir ve WireGuard Arayüz Portu ile eşleşmelidir.",
|
||||
"allowedIpsDesc": "Genel Allowed IPs (izin verilen IP'ler)",
|
||||
"dnsDesc": "Global DNS",
|
||||
"mtuDesc": "Varsayılan MTU (yeni istemciler için)",
|
||||
"persistentKeepaliveDesc": "Varsayılan Keepalive (yeni istemciler için)",
|
||||
"suggest": "Öner",
|
||||
"suggestDesc": "Ana Bilgisayar alanı için bir IP Adresi veya Ana Bilgisayar Adı seçin"
|
||||
"suggestDesc": "Host alanı için bir IP veya Hostname öner"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR değiştirildi",
|
||||
"device": "Cihaz",
|
||||
"deviceDesc": "WireGuard trafiğinin yönlendirileceği Ethernet cihazı",
|
||||
"mtuDesc": "WireGuard'ın kullanacağı MTU",
|
||||
"portDesc": "WireGuard'ın dinleyeceği UDP Portu (muhtemelen Yapılandırma Portunu da değiştirmek isteyeceksiniz)",
|
||||
"changeCidr": "CIDR'ı Değiştir",
|
||||
"cidrSuccess": "CIDR güncellendi",
|
||||
"device": "Arayüz",
|
||||
"deviceDesc": "Trafiğin yönlendirileceği ağ arayüzü (ethernet)",
|
||||
"mtuDesc": "WireGuard arayüz MTU'su",
|
||||
"portDesc": "WireGuard dinleme portu",
|
||||
"changeCidr": "CIDR Değiştir",
|
||||
"restart": "Arayüzü Yeniden Başlat",
|
||||
"restartDesc": "WireGuard arayüzünü yeniden başlat",
|
||||
"restartWarn": "Arayüzü yeniden başlatmak istediğinizden emin misiniz? Bu tüm istemcilerin bağlantısını kesecektir.",
|
||||
"restartSuccess": "Arayüz yeniden başlatıldı"
|
||||
"restartDesc": "WireGuard arayüzünü resetler",
|
||||
"restartWarn": "Arayüzü yeniden başlatmak tüm istemci bağlantılarını koparacaktır. Emin misiniz?",
|
||||
"restartSuccess": "Arayüz yeniden başlatıldı",
|
||||
"firewall": "Trafik Filtreleme",
|
||||
"firewallEnabled": "İstemci Bazlı Firewall",
|
||||
"firewallEnabledDesc": "iptables kullanarak istemci trafiğini kısıtlayın."
|
||||
},
|
||||
"introText": "Yönetici paneline hoş geldiniz.\n\nBurada genel ayarları, yapılandırmayı, arayüz ayarlarını ve hook'ları yönetebilirsiniz.\n\nKenar çubuğundaki bölümlerden birini seçerek başlayın."
|
||||
"introText": "Yönetici paneline hoş geldiniz.\n\nBuradan sistem ayarlarını, WireGuard yapılandırmasını ve Hooks ayarlarını yönetebilirsiniz."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} gerekli",
|
||||
"validNumber": "{0} geçerli bir sayı olmalı",
|
||||
"validString": "{0} geçerli bir dize olmalı",
|
||||
"validBoolean": "{0} geçerli bir boolean olmalı",
|
||||
"validArray": "{0} geçerli bir dizi olmalı",
|
||||
"stringMin": "{0} en az {1} karakter olmalı",
|
||||
"numberMin": "{0} en az {1} olmalı"
|
||||
"required": "{0} alanı zorunludur",
|
||||
"validNumber": "{0} geçerli bir sayı olmalıdır",
|
||||
"validNumberRange": "{0} geçerli bir sayı veya aralık olmalıdır",
|
||||
"validString": "{0} geçerli bir metin olmalıdır",
|
||||
"validBoolean": "{0} geçerli bir boolean olmalıdır",
|
||||
"validArray": "{0} geçerli bir dizi olmalıdır",
|
||||
"stringMin": "{0} en az {1} karakter olmalıdır",
|
||||
"numberMin": "{0} en az {1} olmalıdır"
|
||||
},
|
||||
"client": {
|
||||
"id": "İstemci ID",
|
||||
"name": "Ad",
|
||||
"expiresAt": "Son Kullanma Tarihi",
|
||||
"id": "Client ID",
|
||||
"name": "İsim",
|
||||
"expiresAt": "Son Kullanma",
|
||||
"address4": "IPv4 Adresi",
|
||||
"address6": "IPv6 Adresi",
|
||||
"serverAllowedIps": "Sunucu İzin Verilen IP'ler"
|
||||
"serverAllowedIps": "Server Allowed IPs",
|
||||
"firewallIps": "Firewall Allowed IPs",
|
||||
"firewallIpsInvalid": "Geçersiz Firewall IP formatı. Desteklenen söz dizimi için dokümantasyona bakın. See docs for supported syntax."
|
||||
},
|
||||
"user": {
|
||||
"username": "Kullanıcı Adı",
|
||||
"password": "Şifre",
|
||||
"remember": "Hatırla",
|
||||
"name": "Ad",
|
||||
"name": "İsim",
|
||||
"email": "E-posta",
|
||||
"emailInvalid": "E-posta geçerli bir e-posta olmalı",
|
||||
"passwordMatch": "Şifreler eşleşmeli",
|
||||
"totpEnable": "TOTP Etkinleştir",
|
||||
"totpEnableTrue": "TOTP Etkinleştir doğru olmalı",
|
||||
"totpCode": "TOTP Kodu"
|
||||
"emailInvalid": "Geçersiz e-posta formatı",
|
||||
"passwordMatch": "Şifreler eşleşmiyor",
|
||||
"totpEnable": "2FA Aktif",
|
||||
"totpEnableTrue": "2FA Aktif edilmelidir",
|
||||
"totpCode": "2FA Kodu"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Ana Bilgisayar"
|
||||
"host": "Host"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Oturum Zaman Aşımı",
|
||||
"sessionTimeout": "Zaman Aşımı",
|
||||
"metricsEnabled": "Metrikler",
|
||||
"metricsPassword": "Metrik Şifresi"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Cihaz",
|
||||
"cidrValid": "CIDR geçerli olmalı"
|
||||
"device": "Aygıt",
|
||||
"cidrValid": "Geçersiz CIDR"
|
||||
},
|
||||
"otl": "Tek seferlik bağlantı",
|
||||
"stringMalformed": "Dize hatalı biçimlendirilmiş",
|
||||
"body": "Gövde geçerli bir nesne olmalı",
|
||||
"otl": "OTL (One Time Link)",
|
||||
"stringMalformed": "Hatalı format",
|
||||
"body": "Body geçerli bir obje olmalıdır",
|
||||
"hook": "Hook",
|
||||
"enabled": "Etkin",
|
||||
"enabled": "Aktif",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Kalıcı Keepalive",
|
||||
"persistentKeepalive": "Keepalive",
|
||||
"address": "IP Adresi",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "İzin Verilen IP'ler",
|
||||
"allowedIps": "Allowed IPs",
|
||||
"file": "Dosya"
|
||||
},
|
||||
"hooks": {
|
||||
@@ -236,5 +251,47 @@
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Kopyalama desteklenmiyor",
|
||||
"copied": "Kopyalandı!",
|
||||
"failed": "Kopyalama başarısız",
|
||||
"copy": "Kopyala"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Junk paket sayısı (Jc)",
|
||||
"jCDescription": "Gönderilecek sahte paket sayısı (1-128)",
|
||||
"jMinLabel": "Junk min boyutu (Jmin)",
|
||||
"jMinDescription": "Sahte paketlerin minimum boyutu (Jmin < Jmax, MTU ile sınırlı)",
|
||||
"jMaxLabel": "Junk maks boyutu (Jmax)",
|
||||
"jMaxDescription": "Sahte paketlerin maksimum boyutu (Jmax > Jmin, MTU ile sınırlı)",
|
||||
"s1Label": "Init junk boyutu (S1)",
|
||||
"s1Description": "Başlangıç paketi junk boyutu",
|
||||
"s2Label": "Response junk boyutu (S2)",
|
||||
"s2Description": "Yanıt paketi junk boyutu",
|
||||
"s3Label": "Cookie junk boyutu (S3)",
|
||||
"s3Description": "Cookie reply junk boyutu",
|
||||
"s4Label": "Transport junk boyutu (S4)",
|
||||
"s4Description": "Transport junk boyutu",
|
||||
"h1Label": "Init magic header (H1)",
|
||||
"h1Description": "Init paket başlık değeri",
|
||||
"h2Label": "Response magic header (H2)",
|
||||
"h2Description": "Response paket başlık değeri",
|
||||
"h3Label": "Cookie magic header (H3)",
|
||||
"h3Description": "Cookie reply başlık değeri",
|
||||
"h4Label": "Transport magic header (H4)",
|
||||
"h4Description": "Transport paket başlık değeri",
|
||||
"i1Label": "Özel junk 1 (I1)",
|
||||
"i1Description": "Hex formatında protocol mimic paketi",
|
||||
"i2Label": "Özel junk 2 (I2)",
|
||||
"i2Description": "Hex formatında protocol mimic paketi",
|
||||
"i3Label": "Özel junk 3 (I3)",
|
||||
"i3Description": "Hex formatında protocol mimic paketi",
|
||||
"i4Label": "Özel junk 4 (I4)",
|
||||
"i4Description": "Hex formatında protocol mimic paketi",
|
||||
"i5Label": "Özel junk 5 (I5)",
|
||||
"i5Description": "Hex formatında protocol mimic paketi",
|
||||
"mtuNote": "Değerler MTU'ya bağlıdır",
|
||||
"obfuscationParameters": "AmneziaWG Obfuscation Ayarları"
|
||||
}
|
||||
}
|
||||
|
||||
+23
-12
@@ -120,7 +120,11 @@
|
||||
"endpointDesc": "IP-адреса клієнта, з якої встановлюється з’єднання WireGuard",
|
||||
"search": "Пошук клієнтів...",
|
||||
"config": "Конфігурація",
|
||||
"viewConfig": "Переглянути конфігурацію"
|
||||
"viewConfig": "Переглянути конфігурацію",
|
||||
"firewallIps": "Дозволені IP-адреси брандмауера",
|
||||
"firewallIpsDesc": "IP-адреси/ CIDR призначення, до яких цей клієнт має доступ (контроль на стороні сервера). Залиште порожнім, щоб використовувати дозволені IP-адреси. Підтримує необов’язкову фільтрацію за портом і протоколом. Див. документацію щодо синтаксису.",
|
||||
"downloadPng": "Завантажити PNG",
|
||||
"copyPng": "Скопіювати PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Змінити",
|
||||
@@ -130,7 +134,8 @@
|
||||
"toast": {
|
||||
"success": "Успіх",
|
||||
"saved": "Збережено",
|
||||
"error": "Помилка"
|
||||
"error": "Помилка",
|
||||
"unknown": "Невідома помилка. Дивіться консоль для отримання додаткових деталей"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Дії",
|
||||
@@ -175,7 +180,10 @@
|
||||
"restart": "Перезавантажити інтерфейс",
|
||||
"restartDesc": "Перезавантажити інтерфейс WireGuard",
|
||||
"restartWarn": "Ви впевнені, що бажаєте перезавантажити інтерфейс? Це призведе до відключення всіх клієнтів.",
|
||||
"restartSuccess": "Інтерфейс перезавантажено"
|
||||
"restartSuccess": "Інтерфейс перезавантажено",
|
||||
"firewall": "Фільтрація трафіку",
|
||||
"firewallEnabled": "Увімкнути брандмауер для кожного клієнта",
|
||||
"firewallEnabledDesc": "Обмежити трафік клієнта до певних IP-адрес призначення за допомогою iptables. Коли увімкнено, для кожного клієнта можна налаштувати дозволені адреси призначення."
|
||||
},
|
||||
"introText": "Ласкаво просимо до панелі адміністратора.\n\nТут ви можете керувати загальними налаштуваннями, конфігурацією, налаштуваннями інтерфейсу та перехоплювачами.\n\nПочніть з вибору одного з розділів на боковій панелі."
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0} обов'язковий",
|
||||
"validNumber": "{0} має бути дійсним числом",
|
||||
"validNumberRange": "{0} має бути коректним числом або діапазоном чисел",
|
||||
"validString": "{0} має бути дійсним рядком",
|
||||
"validBoolean": "{0} має бути дійсним логічним значенням",
|
||||
"validArray": "{0} має бути дійсним масивом",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "Термін дії закінчується о",
|
||||
"address4": "IPv4-адреса",
|
||||
"address6": "IPv6-адреса",
|
||||
"serverAllowedIps": "Дозволені IP-адреси сервера"
|
||||
"serverAllowedIps": "Дозволені IP-адреси сервера",
|
||||
"firewallIps": "Дозволені IP-адреси брандмауера",
|
||||
"firewallIpsInvalid": "Некоректний запис IP для брандмауера. Дивіться документацію щодо підтримуваного синтаксису."
|
||||
},
|
||||
"user": {
|
||||
"username": "Ім'я користувача",
|
||||
@@ -262,6 +273,14 @@
|
||||
"s3Description": "Розмір сміттєвих даних у пакеті «cookie reply»",
|
||||
"s4Label": "Розмір сміттєвих даних у транспортному пакеті (S4)",
|
||||
"s4Description": "Розмір сміттєвих даних у транспортному пакеті",
|
||||
"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)",
|
||||
"i1Label": "Спеціальний сміттєвий пакет 1 (I1)",
|
||||
"i1Description": "Пакет-імітація протоколу у hex-форматі: <b 0x...>",
|
||||
"i2Label": "Спеціальний сміттєвий пакет 2 (I2)",
|
||||
@@ -272,14 +291,6 @@
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Tài khoản",
|
||||
"clients": "Người dùng",
|
||||
"admin": {
|
||||
"panel": "Bảng quản trị",
|
||||
"general": "Chung",
|
||||
"config": "Cấu hình",
|
||||
"interface": "Giao diện mạng",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "E-Mail"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Mật khẩu hiện tại",
|
||||
"enable2fa": "Bật xác thực hai yếu tố",
|
||||
"enable2faDesc": "Quét mã QR bằng ứng dụng xác thực của bạn hoặc nhập khóa thủ công.",
|
||||
"2faKey": "Khóa TOTP",
|
||||
"2faCodeDesc": "Nhập mã từ ứng dụng xác thực của bạn.",
|
||||
"disable2fa": "Tắt xác thực hai yếu tố",
|
||||
"disable2faDesc": "Nhập mật khẩu để tắt xác thực hai yếu tố."
|
||||
},
|
||||
"general": {
|
||||
"name": "Tên",
|
||||
"username": "Tên đăng nhập",
|
||||
"password": "Mật khẩu",
|
||||
"newPassword": "Mật khẩu mới",
|
||||
"updatePassword": "Cập nhật mật khẩu",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "IP được phép",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Persistent Keepalive",
|
||||
"logout": "Đăng xuất",
|
||||
"continue": "Tiếp tục",
|
||||
"host": "Host",
|
||||
"port": "Cổng",
|
||||
"yes": "Có",
|
||||
"no": "Chưa",
|
||||
"confirmPassword": "Xác nhận mật khẩu",
|
||||
"loading": "Đang tải...",
|
||||
"2fa": "Xác thực hai yếu tố",
|
||||
"2faCode": "Mã TOTP"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Chào mừng đến với thiết lập đầu tiên của wg-easy",
|
||||
"welcomeDesc": "Bạn đã tìm thấy cách dễ nhất để cài đặt và quản lý WireGuard trên bất kỳ máy chủ Linux nào",
|
||||
"existingSetup": "Bạn có hệ thống được cài đặt trước đây chưa?",
|
||||
"createAdminDesc": "Vui lòng nhập tên đăng nhập quản trị viên và mật khẩu mạnh. Thông tin này sẽ được sử dụng để đăng nhập vào bảng quản trị của bạn.",
|
||||
"setupConfigDesc": "Vui lòng cung cấp host và cổng. Những thông tin này sẽ được sử dụng để cấu hình WireGuard cho người dùng trên thiết bị của họ.",
|
||||
"setupMigrationDesc": "Vui lòng cung cấp tệp sao lưu nếu bạn muốn chuyển dữ liệu từ phiên bản wg-easy trước sang cài đặt mới.",
|
||||
"upload": "Tải lên",
|
||||
"migration": "Khôi phục bản sao lưu:",
|
||||
"createAccount": "Tạo tài khoản",
|
||||
"successful": "Thiết lập thành công",
|
||||
"hostDesc": "Tên miền công khai mà thiết bị sẽ kết nối tới",
|
||||
"portDesc": "Cổng UDP công khai mà thiết bị sẽ kết nối và WireGuard sẽ sử dụng"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Có bản cập nhật mới!",
|
||||
"update": "Cập nhật"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Giao diện tối",
|
||||
"light": "Giao diện sáng",
|
||||
"system": "Giao diện hệ thống"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Hiện/ẩn biểu đồ",
|
||||
"donate": "Ủng hộ"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Đăng nhập",
|
||||
"rememberMe": "Duy trì đăng nhập",
|
||||
"rememberMeDesc": "Duy trì trạng thái đăng nhập sau khi đóng trình duyệt",
|
||||
"insecure": "Bạn không thể đăng nhập qua kết nối không bảo mật. Hãy dùng HTTPS.",
|
||||
"2faRequired": "Yêu cầu xác thực hai yếu tố",
|
||||
"2faWrong": "Mã xác thực hai yếu tố không đúng"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Chưa có người dùng nào.",
|
||||
"newShort": "Mới",
|
||||
"sort": "Sắp xếp",
|
||||
"create": "Tạo người dùng",
|
||||
"created": "Đã tạo người dùng",
|
||||
"new": "Người dùng mới",
|
||||
"name": "Tên",
|
||||
"expireDate": "Ngày hết hạn",
|
||||
"expireDateDesc": "Ngày người dùng sẽ bị vô hiệu hóa. Để trống nếu dùng vĩnh viễn",
|
||||
"delete": "Xóa",
|
||||
"deleteClient": "Xóa người dùng",
|
||||
"deleteDialog1": "Bạn có chắc rằng muốn xóa",
|
||||
"deleteDialog2": "Hành động này không thể hoàn tác.",
|
||||
"enabled": "Đã bật",
|
||||
"address": "Địa chỉ",
|
||||
"serverAllowedIps": "IP được phép phía máy chủ",
|
||||
"otlDesc": "Tạo liên kết dùng một lần",
|
||||
"permanent": "Vĩnh viễn",
|
||||
"createdOn": "Được tạo vào ",
|
||||
"lastSeen": "Lần cuối trực tuyến ",
|
||||
"totalDownload": "Tổng tải về: ",
|
||||
"totalUpload": "Tổng tải lên: ",
|
||||
"newClient": "Người dùng mới",
|
||||
"disableClient": "Vô hiệu hóa người dùng",
|
||||
"enableClient": "Kích hoạt người dùng",
|
||||
"noPrivKey": "Người dùng này không có khóa riêng tư. Không thể tạo cấu hình.",
|
||||
"showQR": "Hiển thị mã QR",
|
||||
"downloadConfig": "Tải cấu hình",
|
||||
"allowedIpsDesc": "Các IP sẽ được định tuyến qua VPN (ghi đè cấu hình chung)",
|
||||
"serverAllowedIpsDesc": "Các IP mà máy chủ sẽ định tuyến đến người dùng",
|
||||
"mtuDesc": "Đặt đơn vị truyền tải tối đa - MTU (kích thước gói tin) cho VPN",
|
||||
"persistentKeepaliveDesc": "Đặt khoảng thời gian (giây) gửi gói tin keep-alive. 0 để tắt",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks chỉ hoạt động với wg-quick",
|
||||
"hooksLeaveEmpty": "Chỉ dùng cho wg-quick. Nếu không, để trống",
|
||||
"dnsDesc": "Máy chủ DNS mà người dùng sử dụng (ghi đè cấu hình chung)",
|
||||
"notConnected": "Người dùng chưa kết nối",
|
||||
"endpoint": "Điểm cuối",
|
||||
"endpointDesc": "IP của người dùng dùng để thiết lập kết nối WireGuard",
|
||||
"search": "Tìm kiếm người dùng...",
|
||||
"config": "Cấu hình",
|
||||
"viewConfig": "Xem cấu hình",
|
||||
"firewallIps": "IP được phép qua tường lửa",
|
||||
"firewallIpsDesc": "Địa chỉ IP/CIDR đích mà người dùng này có thể truy cập (kiểm soát phía máy chủ). Để trống để dùng giá trị IP được phép. Hỗ trợ lọc theo cổng và giao thức tùy chọn. Xem tài liệu để hiểu cú pháp.",
|
||||
"downloadPng": "Tải PNG",
|
||||
"copyPng": "Sao chép PNG"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Thay đổi",
|
||||
"cancel": "Hủy",
|
||||
"create": "Tạo"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Thành công",
|
||||
"saved": "Đã lưu",
|
||||
"error": "Lỗi",
|
||||
"unknown": "Lỗi không xác định. Xem console để biết thêm chi tiết"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Thao tác",
|
||||
"save": "Lưu",
|
||||
"revert": "Hoàn tác",
|
||||
"sectionGeneral": "Chung",
|
||||
"sectionAdvanced": "Nâng cao",
|
||||
"noItems": "Không có mục nào",
|
||||
"nullNoItems": "Không có mục nào. Sử dụng cấu hình chung",
|
||||
"add": "Thêm"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Thời gian hết phiên",
|
||||
"sessionTimeoutDesc": "Thời lượng phiên cho tính năng Duy trì đăng nhập (giây)",
|
||||
"metrics": "Metrics",
|
||||
"metricsPassword": "Mật khẩu",
|
||||
"metricsPasswordDesc": "Mật khẩu Bearer cho đường dẫn metrics (mật khẩu hoặc hash argon2)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Đường dẫn metrics định dạng JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Đường dẫn metrics Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Kết nối",
|
||||
"hostDesc": "Tên miền công khai mà người dùng sẽ kết nối tới (làm mất hiệu lực cấu hình)",
|
||||
"portDesc": "Cổng UDP công khai mà người dùng sẽ kết nối tới (làm mất hiệu lực cấu hình, bạn cũng cần thay đổi cổng giao diện mạng)",
|
||||
"allowedIpsDesc": "Các IP được cho phép mà người dùng sẽ sử dụng (cấu hình chung)",
|
||||
"dnsDesc": "Máy chủ DNS mà người dùng sẽ sử dụng (cấu hình chung)",
|
||||
"mtuDesc": "MTU mà người dùng sẽ sử dụng (chỉ áp dụng cho người dùng mới)",
|
||||
"persistentKeepaliveDesc": "Khoảng thời gian (giây) gửi keepalive đến máy chủ. 0 = tắt (chỉ áp dụng cho người dùng mới)",
|
||||
"suggest": "Gợi ý",
|
||||
"suggestDesc": "Chọn địa chỉ IP hoặc tên miền cho trường Host"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "Đã thay đổi CIDR",
|
||||
"device": "Card mạng",
|
||||
"deviceDesc": "Card mạng mà lưu lượng WireGuard sẽ được chuyển tiếp qua",
|
||||
"mtuDesc": "MTU mà WireGuard sẽ sử dụng",
|
||||
"portDesc": "Cổng UDP mà WireGuard sẽ sử dụng (bạn cũng cần thay đổi cổng cấu hình)",
|
||||
"changeCidr": "Thay đổi CIDR",
|
||||
"restart": "Khởi động lại giao diện mạng",
|
||||
"restartDesc": "Khởi động lại giao diện mạng WireGuard",
|
||||
"restartWarn": "Bạn có chắc muốn khởi động lại giao diện mạng? Điều này sẽ ngắt kết nối tất cả người dùng.",
|
||||
"restartSuccess": "Đã khởi động lại giao diện mạng",
|
||||
"firewall": "Lọc lưu lượng",
|
||||
"firewallEnabled": "Bật tường lửa theo từng người dùng",
|
||||
"firewallEnabledDesc": "Áp dụng iptables để giới hạn người dùng chỉ truy cập các IP đích xác định. Sau khi kích hoạt, cho phép cấu hình điểm đến riêng cho từng người dùng."
|
||||
},
|
||||
"introText": "Chào mừng đến bảng quản trị.\n\nTại đây bạn có thể quản lý cài đặt chung, cấu hình, cài đặt giao diện mạng và hooks.\n\nBắt đầu bằng cách chọn một trong các mục trong thanh bên."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} không được để trống",
|
||||
"validNumber": "{0} phải là số hợp lệ",
|
||||
"validNumberRange": "{0} phải là số hoặc khoảng số hợp lệ",
|
||||
"validString": "{0} phải là chuỗi hợp lệ",
|
||||
"validBoolean": "{0} phải là giá trị boolean hợp lệ",
|
||||
"validArray": "{0} phải là mảng hợp lệ",
|
||||
"stringMin": "{0} phải có ít nhất {1} ký tự",
|
||||
"numberMin": "{0} phải có giá trị ít nhất là {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "ID thiết bị",
|
||||
"name": "Tên",
|
||||
"expiresAt": "Hết hạn lúc",
|
||||
"address4": "Địa chỉ IPv4",
|
||||
"address6": "Địa chỉ IPv6",
|
||||
"serverAllowedIps": "IP được phép phía máy chủ",
|
||||
"firewallIps": "IP được phép qua tường lửa",
|
||||
"firewallIpsInvalid": "IP tường lửa không hợp lệ. Xem tài liệu để biết cú pháp được hỗ trợ."
|
||||
},
|
||||
"user": {
|
||||
"username": "Tên đăng nhập",
|
||||
"password": "Mật khẩu",
|
||||
"remember": "Ghi nhớ",
|
||||
"name": "Tên",
|
||||
"email": "Email",
|
||||
"emailInvalid": "Email phải có định dạng hợp lệ",
|
||||
"passwordMatch": "Mật khẩu phải khớp nhau",
|
||||
"totpEnable": "Bật TOTP",
|
||||
"totpEnableTrue": "Bật TOTP phải là true",
|
||||
"totpCode": "Mã TOTP"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Host"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Thời gian hết phiên",
|
||||
"metricsEnabled": "Số liệu",
|
||||
"metricsPassword": "Mật khẩu số liệu"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Thiết bị mạng",
|
||||
"cidrValid": "CIDR phải hợp lệ"
|
||||
},
|
||||
"otl": "Liên kết dùng một lần",
|
||||
"stringMalformed": "Chuỗi không đúng định dạng",
|
||||
"body": "Body phải là đối tượng hợp lệ",
|
||||
"hook": "Hook",
|
||||
"enabled": "Đã bật",
|
||||
"mtu": "MTU",
|
||||
"port": "Cổng",
|
||||
"persistentKeepalive": "Persistent Keepalive",
|
||||
"address": "Địa chỉ IP",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Các IP được phép",
|
||||
"file": "Tệp"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
},
|
||||
"copy": {
|
||||
"notSupported": "Không hỗ trợ sao chép",
|
||||
"copied": "Đã sao chép!",
|
||||
"failed": "Sao chép thất bại",
|
||||
"copy": "Sao chép"
|
||||
},
|
||||
"awg": {
|
||||
"jCLabel": "Số lượng gói tin rác (Jc)",
|
||||
"jCDescription": "Số gói tin rác cần gửi (1-128, khuyến nghị: 4-12)",
|
||||
"jMinLabel": "Kích thước tối thiểu gói tin rác (Jmin)",
|
||||
"jMinDescription": "Kích thước tối thiểu của gói tin rác (0-1279*, khuyến nghị: 8, phải nhỏ hơn Jmax)",
|
||||
"jMaxLabel": "Kích thước tối đa gói tin rác (Jmax)",
|
||||
"jMaxDescription": "Kích thước tối đa của gói tin rác (1-1280*, khuyến nghị: 80, phải lớn hơn Jmin)",
|
||||
"s1Label": "Kích thước rác gói tin khởi tạo (S1)",
|
||||
"s1Description": "Kích thước rác gói tin khởi tạo (0-1132[1280* - 148 = 1132], khuyến nghị: 15-150, S1+56 ≠ S2)",
|
||||
"s2Label": "Kích thước rác gói tin phản hồi (S2)",
|
||||
"s2Description": "Kích thước rác gói tin phản hồi (0-1188[1280* - 92 = 1188], khuyến nghị: 15-150)",
|
||||
"s3Label": "Kích thước rác gói tin cookie reply (S3)",
|
||||
"s3Description": "Kích thước rác gói tin cookie reply",
|
||||
"s4Label": "Kích thước rác gói tin vận chuyển (S4)",
|
||||
"s4Description": "Kích thước rác gói tin vận chuyển",
|
||||
"h1Label": "Header khởi tạo (H1)",
|
||||
"h1Description": "Giá trị hoặc khoảng header gói tin khởi tạo (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
|
||||
"h2Label": "Header phản hồi (H2)",
|
||||
"h2Description": "Giá trị hoặc khoảng header gói tin phản hồi (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
|
||||
"h3Label": "Header cookie reply (H3)",
|
||||
"h3Description": "Giá trị hoặc khoảng header gói tin cookie reply (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
|
||||
"h4Label": "Header vận chuyển (H4)",
|
||||
"h4Description": "Giá trị hoặc khoảng header gói tin vận chuyển (X hoặc X-Y, với X<Y. Tối thiểu 5, tối đa 2147483647. Giá trị hoặc khoảng không được trùng với các header khác)",
|
||||
"i1Label": "Gói tin rác đặc biệt 1 (I1)",
|
||||
"i1Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
|
||||
"i2Label": "Gói tin rác đặc biệt 2 (I2)",
|
||||
"i2Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
|
||||
"i3Label": "Gói tin rác đặc biệt 3 (I3)",
|
||||
"i3Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
|
||||
"i4Label": "Gói tin rác đặc biệt 4 (I4)",
|
||||
"i4Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
|
||||
"i5Label": "Gói tin rác đặc biệt 5 (I5)",
|
||||
"i5Description": "Gói tin giả lập giao thức định dạng hex: <b 0x...>",
|
||||
"mtuNote": "Các giá trị phụ thuộc vào MTU",
|
||||
"obfuscationParameters": "Tham số làm rối AmneziaWG"
|
||||
}
|
||||
}
|
||||
+24
-13
@@ -120,17 +120,22 @@
|
||||
"endpointDesc": "建立 WireGuard 连接时客户端的 IP 地址",
|
||||
"search": "搜索客户端...",
|
||||
"config": "配置",
|
||||
"viewConfig": "查看配置文本"
|
||||
"viewConfig": "查看配置文本",
|
||||
"firewallIps": "防火墙允许的IP",
|
||||
"firewallIpsDesc": "客户端可访问的目标 IP/CIDR 范围(由服务器端进行限制)。留空时将使用 服务端允许的IP 设置。支持按 端口 和 协议 进行过滤。具体语法请查看文档。",
|
||||
"downloadPng": "下载图片",
|
||||
"copyPng": "复制图片"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "确认修改",
|
||||
"change": "修改",
|
||||
"cancel": "取消",
|
||||
"create": "创建"
|
||||
},
|
||||
"toast": {
|
||||
"success": "操作成功",
|
||||
"saved": "保存成功",
|
||||
"error": "发生错误"
|
||||
"error": "发生错误",
|
||||
"unknown": "未知错误。查看控制台获取更详细信息"
|
||||
},
|
||||
"form": {
|
||||
"actions": "操作",
|
||||
@@ -175,7 +180,10 @@
|
||||
"restart": "重启接口",
|
||||
"restartDesc": "重新启动WireGuard接口",
|
||||
"restartWarn": "确定要重启接口吗?这将断开所有客户端的连接。",
|
||||
"restartSuccess": "接口重启成功"
|
||||
"restartSuccess": "接口重启成功",
|
||||
"firewall": "流量过滤",
|
||||
"firewallEnabled": "启用客户端防火墙",
|
||||
"firewallEnabledDesc": "通过 iptables 限制客户端只能访问指定的目标 IP。启用后,可以为每个客户端单独配置允许访问的目标地址列表。"
|
||||
},
|
||||
"introText": "欢迎使用管理控制台。\n\n您可以在这里管理通用设置、网络配置、接口配置和钩子脚本。\n\n请从侧边栏选择一个功能模块开始。"
|
||||
},
|
||||
@@ -183,6 +191,7 @@
|
||||
"generic": {
|
||||
"required": "{0}是必填项",
|
||||
"validNumber": "{0}必须是有效数字",
|
||||
"validNumberRange": "{0}必须是有效的数字或数字范围",
|
||||
"validString": "{0}必须是有效文本",
|
||||
"validBoolean": "{0}必须是是/否选项",
|
||||
"validArray": "{0}必须是有效数组",
|
||||
@@ -195,7 +204,9 @@
|
||||
"expiresAt": "过期时间",
|
||||
"address4": "IPv4地址",
|
||||
"address6": "IPv6地址",
|
||||
"serverAllowedIps": "服务端允许的IP"
|
||||
"serverAllowedIps": "服务端允许的IP",
|
||||
"firewallIps": "防火墙允许的IP",
|
||||
"firewallIpsInvalid": "IP格式错误。请查看相关文档获取支持的写法。"
|
||||
},
|
||||
"user": {
|
||||
"username": "用户名",
|
||||
@@ -262,6 +273,14 @@
|
||||
"s3Description": "Cookie 回复数据包中垃圾数据的大小",
|
||||
"s4Label": "传输数据包垃圾数据大小(S4)",
|
||||
"s4Description": "传输数据包中垃圾数据的大小",
|
||||
"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 不同)",
|
||||
"i1Label": "特殊垃圾数据包 1(I1)",
|
||||
"i1Description": "协议模拟数据包(十六进制格式):<b 0x...>",
|
||||
"i2Label": "特殊垃圾数据包 2(I2)",
|
||||
@@ -272,14 +291,6 @@
|
||||
"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 混淆参数"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user