diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 1a95228..c89c1d2 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -4,7 +4,7 @@ on: pull_request: branches: [master] push: - branches: [master, stable] + branches: [master, stable, legacy] # Publish vX.X.X tags as releases. tags: ["v*.*.*"] diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5e1f2ab..cbec92b 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -2,7 +2,11 @@ name: github-pages on: push: branches: [master] - tags: ["v*"] + tags: + - 'v*' + - '!v*-alpha*' + - '!v*-beta*' + - '!v*-rc*' permissions: contents: write diff --git a/README.md b/README.md index a42ae02..c5a2968 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# WireGuard Portal (v2 - testing) +# WireGuard Portal v2 [![Build Status](https://github.com/h44z/wg-portal/actions/workflows/docker-publish.yml/badge.svg?event=push)](https://github.com/h44z/wg-portal/actions/workflows/docker-publish.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT) @@ -8,14 +8,6 @@ ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/h44z/wg-portal) [![Docker Pulls](https://img.shields.io/docker/pulls/h44z/wg-portal.svg)](https://hub.docker.com/r/wgportal/wg-portal/) -> [!CAUTION] -> Version 2 is currently under development and may contain bugs and breaking changes. -> It is not advised to use this version in production. Use version [v1](https://github.com/h44z/wg-portal/tree/stable) instead. - -> [!IMPORTANT] -> Since the project was accepted by the Docker-Sponsored Open Source Program, the Docker image location has moved to [wgportal/wg-portal](https://hub.docker.com/r/wgportal/wg-portal). -> Please update the Docker image from **h44z/wg-portal** to **wgportal/wg-portal**. - ## Introduction **WireGuard Portal** is a simple, web-based configuration portal for [WireGuard](https://wireguard.com) server management. @@ -23,7 +15,7 @@ The portal uses the WireGuard [wgctrl](https://github.com/WireGuard/wgctrl-go) l interfaces. This allows for the seamless activation or deactivation of new users without disturbing existing VPN connections. -The configuration portal supports using a database (SQLite, MySQL, MsSQL or Postgres), OAuth or LDAP +The configuration portal supports using a database (SQLite, MySQL, MsSQL, or Postgres), OAuth or LDAP (Active Directory or OpenLDAP) as a user source for authentication and profile data. ## Features @@ -44,7 +36,7 @@ The configuration portal supports using a database (SQLite, MySQL, MsSQL or Post * Handles route and DNS settings like wg-quick does * Exposes Prometheus metrics for monitoring and alerting * REST API for management and client deployment -* Webhook for custom actions on peer, interface or user updates +* Webhook for custom actions on peer, interface, or user updates ![Screenshot](docs/assets/images/screenshot.png) @@ -68,3 +60,8 @@ For the complete documentation visit [wgportal.org](https://wgportal.org). ## License * MIT License. [MIT](LICENSE.txt) or + + +> [!IMPORTANT] +> Since the project was accepted by the Docker-Sponsored Open Source Program, the Docker image location has moved to [wgportal/wg-portal](https://hub.docker.com/r/wgportal/wg-portal). +> Please update the Docker image from **h44z/wg-portal** to **wgportal/wg-portal**. diff --git a/docker-compose.yml b/docker-compose.yml index 03a59a1..c5611e0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ --- services: wg-portal: - image: wgportal/wg-portal:latest + image: wgportal/wg-portal:v2 container_name: wg-portal restart: unless-stopped logging: @@ -10,6 +10,7 @@ services: max-file: "3" cap_add: - NET_ADMIN + # Use host network mode for WireGuard and the UI. Ensure that access to the UI is properly secured. network_mode: "host" volumes: # left side is the host path, right side is the container path diff --git a/docs/documentation/configuration/examples.md b/docs/documentation/configuration/examples.md index 46e7ed1..83571dd 100644 --- a/docs/documentation/configuration/examples.md +++ b/docs/documentation/configuration/examples.md @@ -15,7 +15,7 @@ web: site_title: My WireGuard Server site_company_name: My Company listening_address: :8080 - external_url: https://my.externa-domain.com + external_url: https://my.external-domain.com csrf_secret: super-s3cr3t-csrf session_secret: super-s3cr3t-session request_logging: true diff --git a/docs/documentation/configuration/overview.md b/docs/documentation/configuration/overview.md index fa0c505..27d4309 100644 --- a/docs/documentation/configuration/overview.md +++ b/docs/documentation/configuration/overview.md @@ -1,10 +1,10 @@ This page provides an overview of **all available configuration options** for WireGuard Portal. -You can supply these configurations in a **YAML** file (e.g. `config.yaml`) when starting the Portal. -The path of the configuration file defaults to **config/config.yaml** (or config/config.yml) in the working directory of the executable. -It is possible to override configuration filepath using the environment variable `WG_PORTAL_CONFIG`. +You can supply these configurations in a **YAML** file when starting the Portal. +The path of the configuration file defaults to `config/config.yaml` (or `config/config.yml`) in the working directory of the executable. +It is possible to override the configuration filepath using the environment variable `WG_PORTAL_CONFIG`. For example: `WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal`. -Also, environment variable substitution in config file is supported. Refer to [syntax](https://github.com/a8m/envsubst?tab=readme-ov-file#docs). +Also, environment variable substitution in the config file is supported. Refer to the [syntax](https://github.com/a8m/envsubst?tab=readme-ov-file#docs). Configuration examples are available on the [Examples](./examples.md) page. @@ -15,6 +15,7 @@ Configuration examples are available on the [Examples](./examples.md) page. core: admin_user: admin@wgportal.local admin_password: wgportal + admin_api_token: "" editable_keys: true create_default_peer: false create_default_peer_on_creation: false @@ -35,6 +36,7 @@ advanced: config_storage_path: "" expiry_check_interval: 15m rule_prio_offset: 20000 + route_table_offset: 20000 api_admin_only: true database: @@ -42,6 +44,7 @@ database: slow_query_threshold: "0" type: sqlite dsn: data/sqlite.db + encryption_passphrase: "" statistics: use_ping_checks: true @@ -79,6 +82,7 @@ web: session_secret: very_secret csrf_secret: extremely_secret request_logging: false + expose_host_info: false cert_file: "" key_File: "" @@ -282,7 +286,7 @@ Controls how WireGuard Portal collects and reports usage statistics, including p ### `listening_address` - **Default:** `:8787` -- **Description:** Address and port for the integrated Prometheus metric server (e.g., `:8787` or `127.0.0.1:8888`). +- **Description:** Address and port for the integrated Prometheus metric server (e.g., `:8787` or `127.0.0.1:8787`). --- @@ -576,7 +580,8 @@ Without a valid `external_url`, the login process may fail due to CSRF protectio ### `listening_address` - **Default:** `:8888` -- **Description:** The listening port of the web server. +- **Description:** The listening address and port for the web server (e.g., `:8888` to bind on all interfaces or `127.0.0.1:8888` to bind only on the loopback interface). + Ensure that access to WireGuard Portal is protected against unauthorized access, especially if binding to all interfaces. ### `external_url` - **Default:** `http://localhost:8888` @@ -607,6 +612,10 @@ Without a valid `external_url`, the login process may fail due to CSRF protectio - **Default:** `false` - **Description:** Log all HTTP requests. +### `expose_host_info` +- **Default:** `false` +- **Description:** Expose the hostname and version of the WireGuard Portal server in an HTTP header. This is useful for debugging but may expose sensitive information. + ### `cert_file` - **Default:** *(empty)* - **Description:** (Optional) Path to the TLS certificate file. diff --git a/docs/documentation/getting-started/binaries.md b/docs/documentation/getting-started/binaries.md index 5b657c5..5aed082 100644 --- a/docs/documentation/getting-started/binaries.md +++ b/docs/documentation/getting-started/binaries.md @@ -3,23 +3,31 @@ These binary versions can be manually downloaded and installed. ## Download +Make sure that you download the correct binary for your architecture. The available binaries are: + +- `wg-portal_linux_amd64` - Linux x86_64 +- `wg-portal_linux_arm64` - Linux ARM 64-bit +- `wg-portal_linux_arm_v7` - Linux ARM 32-bit + With `curl`: - ```shell - curl -L -o wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 - ``` +```shell +curl -L -o wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 +``` With `wget`: - ```shell - wget -O wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 - ``` +```shell +wget -O wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 +``` with `gh cli`: - ```shell - gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64' - ``` +```shell +gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64' +``` + + ## Install @@ -28,7 +36,7 @@ sudo mkdir -p /opt/wg-portal sudo install wg-portal /opt/wg-portal/ ``` -## Unreleased +## Unreleased versions (master branch builds) + +Unreleased versions can be fetched directly from the artifacts section of the [GitHub Workflow](https://github.com/h44z/wg-portal/actions/workflows/docker-publish.yml?query=branch%3Amaster). -Unreleased versions could be downloaded from -[GitHub Workflow](https://github.com/h44z/wg-portal/actions/workflows/docker-publish.yml?query=branch%3Amaster) artifacts also. diff --git a/docs/documentation/getting-started/docker.md b/docs/documentation/getting-started/docker.md index ab606b1..da1b63a 100644 --- a/docs/documentation/getting-started/docker.md +++ b/docs/documentation/getting-started/docker.md @@ -10,10 +10,10 @@ The recommended method for deploying WireGuard Portal is via Docker Compose for A sample docker-compose.yml (managing WireGuard interfaces directly on the host) is provided below: ```yaml ---8<-- "docker-compose.yml::17" +--8<-- "docker-compose.yml::19" ``` -By default, the webserver is listening on port **8888**. +By default, the webserver for the UI is listening on port **8888** on all available interfaces. Volumes for `/app/data` and `/app/config` should be used ensure data persistence across container restarts. @@ -32,6 +32,8 @@ WireGuard Portal supports managing WireGuard interfaces through three distinct d network_mode: "host" ... ``` + > :warning: If host networking is used, the WireGuard Portal UI will be accessible on all the host's IP addresses if the listening address is set to `:8888` in the configuration file. + To avoid this, you can bind the listening address to a specific IP address, for example, the loopback address (`127.0.0.1:8888`). It is also possible to deploy firewall rules to restrict access to the WireGuard Portal UI. - **Within the WireGuard Portal Docker container**: WireGuard interfaces can be managed directly from within the WireGuard Portal container itself. @@ -39,7 +41,7 @@ WireGuard Portal supports managing WireGuard interfaces through three distinct d ```yaml services: wg-portal: - image: wgportal/wg-portal:latest + image: wgportal/wg-portal:v2 container_name: wg-portal ... cap_add: @@ -65,7 +67,7 @@ WireGuard Portal supports managing WireGuard interfaces through three distinct d ```yaml services: wg-portal: - image: wgportal/wg-portal:latest + image: wgportal/wg-portal:v2 container_name: wg-portal ... cap_add: @@ -118,11 +120,11 @@ These are official releases of WireGuard Portal. They correspond to the GitHub t Once these tags show up in this repository, they will never change. -For production deployments of WireGuard Portal, we strongly recommend using one of these tags, e.g. **wgportal/wg-portal:1.0.19**, instead of the latest or canary tags. +For production deployments of WireGuard Portal, we strongly recommend using one of these tags, e.g. `wgportal/wg-portal:2.0.0`, instead of the latest or canary tags. -If you only want to stay at the same major or major+minor version, use either `v[MAJOR]` or `[MAJOR].[MINOR]` tags. For example `v1` or `1.0`. +If you only want to stay at the same major or major+minor version, use either `v[MAJOR]` or `[MAJOR].[MINOR]` tags. For example `v2` or `2.0`. -Version **1** is currently **stable**, version **2** is in **development**. +Version **2** is the current stable release. Version **1** has moved to legacy status and is no longer recommended. #### latest @@ -149,7 +151,7 @@ You should mount those directories as a volume: A detailed description of the configuration options can be found [here](../configuration/overview.md). -If you want to access configuration files in wg-quick format, you can mount the `/etc/wireguard` directory to a location of your choice. +If you want to access configuration files in wg-quick format, you can mount the `/etc/wireguard` directory inside the container to a location of your choice. Also enable the `config_storage_path` option in the configuration file: ```yaml advanced: diff --git a/docs/documentation/getting-started/reverse-proxy.md b/docs/documentation/getting-started/reverse-proxy.md index 10b689d..e1fad58 100644 --- a/docs/documentation/getting-started/reverse-proxy.md +++ b/docs/documentation/getting-started/reverse-proxy.md @@ -44,7 +44,7 @@ services: - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https' wg-portal: - image: wgportal/wg-portal:latest + image: wgportal/wg-portal:v2 container_name: wg-portal restart: unless-stopped logging: diff --git a/docs/documentation/getting-started/sources.md b/docs/documentation/getting-started/sources.md index 265e5b9..36e9b71 100644 --- a/docs/documentation/getting-started/sources.md +++ b/docs/documentation/getting-started/sources.md @@ -22,4 +22,5 @@ make build ## Install Compiled binary will be available in `./dist` directory. + For installation instructions, check the [Binaries](./binaries.md) section. diff --git a/docs/documentation/monitoring/prometheus.md b/docs/documentation/monitoring/prometheus.md index 03d618a..a360fcf 100644 --- a/docs/documentation/monitoring/prometheus.md +++ b/docs/documentation/monitoring/prometheus.md @@ -13,7 +13,7 @@ By default, WG-Portal exposes Prometheus metrics on port `8787` if interface/pee ## Prometheus Config -Add following scrape job to your Prometheus config file: +Add the following scrape job to your Prometheus config file: ```yaml # prometheus.yaml diff --git a/docs/documentation/overview.md b/docs/documentation/overview.md index 03456ac..a3c8b3e 100644 --- a/docs/documentation/overview.md +++ b/docs/documentation/overview.md @@ -1 +1 @@ ---8<-- "README.md:20:47" +--8<-- "README.md:12:41" diff --git a/docs/documentation/upgrade/v1.md b/docs/documentation/upgrade/v1.md index 4fd2c8a..52bdbe7 100644 --- a/docs/documentation/upgrade/v1.md +++ b/docs/documentation/upgrade/v1.md @@ -1,5 +1,4 @@ -For production deployments of WireGuard Portal, we strongly recommend using version 1. -If you want to use version 2, please be aware that it is still a release candidate and not yet fully stable. +Major upgrades between different versions may require special procedures, which are described in the following sections. ## Upgrade from v1 to v2 @@ -14,7 +13,9 @@ To upgrade from a previous SQLite database, start wg-portal like: ./wg-portal-amd64 -migrateFrom=old_wg_portal.db ``` -You can also specify the database type using the parameter **-migrateFromType**, supported types: mysql, mssql, postgres or sqlite. +You can also specify the database type using the parameter **-migrateFromType**. +Supported database types: `mysql`, `mssql`, `postgres` or `sqlite`. + For example: ```shell @@ -29,8 +30,8 @@ If you are using Docker, you can adapt the docker-compose.yml file to start the ```yaml services: wg-portal: - image: wgportal/wg-portal:latest + image: wgportal/wg-portal:v2 # ... other settings restart: no - command: ["-migrateFrom=/app/data/wg_portal.db"] + command: ["-migrateFrom=/app/data/old_wg_portal.db"] ``` diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7f1fb2f..f12f2f7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -29,7 +29,7 @@ "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", "sass-embedded": "^1.86.3", - "vite": "6.3.2" + "vite": "6.3.4" } }, "node_modules/@babel/helper-string-parser": { @@ -2012,13 +2012,13 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2" }, "engines": { @@ -2043,18 +2043,18 @@ "license": "MIT" }, "node_modules/vite": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.2.tgz", - "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==", + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", + "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", - "tinyglobby": "^0.2.12" + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" diff --git a/frontend/package.json b/frontend/package.json index 8e226b0..baf850f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,6 +29,6 @@ "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", "sass-embedded": "^1.86.3", - "vite": "6.3.2" + "vite": "6.3.4" } } diff --git a/frontend/src/assets/custom.scss b/frontend/src/assets/custom.scss index c126c04..5d12373 100644 --- a/frontend/src/assets/custom.scss +++ b/frontend/src/assets/custom.scss @@ -5,6 +5,10 @@ $web-font-path: false; @import "bootstrap/scss/bootstrap"; @import "bootswatch/dist/lux/bootswatch"; +// fix strange border width bug in bootswatch 5.3 +:root { + --bs-border-width: 1px; +} // for future use, once bootswatch supports @use /* diff --git a/frontend/src/lang/translations/de.json b/frontend/src/lang/translations/de.json index 6815274..32a4251 100644 --- a/frontend/src/lang/translations/de.json +++ b/frontend/src/lang/translations/de.json @@ -26,7 +26,7 @@ "placeholder": "Bitte geben Sie Ihren Benutzernamen ein" }, "password": { - "label": "Kennwort", + "label": "Passwort", "placeholder": "Bitte geben Sie Ihr Passwort ein" }, "button": "Anmelden" @@ -38,6 +38,7 @@ "lang": "Sprache ändern", "profile": "Mein Profil", "settings": "Einstellungen", + "audit": "Event Protokoll", "login": "Anmelden", "logout": "Abmelden", "keygen": "Schlüsselgenerator" @@ -80,77 +81,77 @@ }, "interfaces": { "headline": "Schnittstellenverwaltung", - "headline-peers": "Current VPN Peers", - "headline-endpoints": "Current Endpoints", + "headline-peers": "Aktuelle VPN-Peers", + "headline-endpoints": "Aktuelle Endpunkte", "no-interface": { - "default-selection": "No Interface available", - "headline": "No interfaces found...", - "abstract": "Click the plus button above to create a new WireGuard interface." + "default-selection": "Keine Schnittstelle verfügbar", + "headline": "Keine Schnittstellen gefunden...", + "abstract": "Klicken Sie auf die Plus-Schaltfläche oben, um eine neue WireGuard-Schnittstelle zu erstellen." }, "no-peer": { - "headline": "No peers available", - "abstract": "Currently, there are no peers available for the selected WireGuard interface." + "headline": "Keine Peers verfügbar", + "abstract": "Derzeit sind keine Peers für die ausgewählte WireGuard-Schnittstelle verfügbar." }, "table-heading": { "name": "Name", - "user": "User", + "user": "Benutzer", "ip": "IP's", - "endpoint": "Endpoint", + "endpoint": "Endpunkt", "status": "Status" }, "interface": { - "headline": "Interface status for", - "mode": "mode", - "key": "Public Key", - "endpoint": "Public Endpoint", - "port": "Listening Port", - "peers": "Enabled Peers", - "total-peers": "Total Peers", - "endpoints": "Enabled Endpoints", - "total-endpoints": "Total Endpoints", - "ip": "IP Address", - "default-allowed-ip": "Default allowed IPs", - "dns": "DNS Servers", + "headline": "Schnittstellenstatus für", + "mode": "Modus", + "key": "Öffentlicher Schlüssel", + "endpoint": "Öffentlicher Endpunkt", + "port": "Port", + "peers": "Aktive Peers", + "total-peers": "Gesamtanzahl Peers", + "endpoints": "Aktive Endpunkte", + "total-endpoints": "Gesamtanzahl Endpunkte", + "ip": "IP-Adresse", + "default-allowed-ip": "Standard Erlaubte-IPs", + "dns": "DNS-Server", "mtu": "MTU", - "default-keep-alive": "Default Keepalive Interval", - "button-show-config": "Show configuration", - "button-download-config": "Download configuration", - "button-store-config": "Store configuration for wg-quick", - "button-edit": "Edit interface" + "default-keep-alive": "Standard Keepalive-Intervall", + "button-show-config": "Konfiguration anzeigen", + "button-download-config": "Konfiguration herunterladen", + "button-store-config": "Konfiguration für wg-quick speichern", + "button-edit": "Schnittstelle bearbeiten" }, - "button-add-interface": "Add Interface", - "button-add-peer": "Add Peer", - "button-add-peers": "Add Multiple Peers", - "button-show-peer": "Show Peer", - "button-edit-peer": "Edit Peer", - "peer-disabled": "Peer is disabled, reason:", - "peer-expiring": "Peer is expiring at", - "peer-connected": "Connected", - "peer-not-connected": "Not Connected", - "peer-handshake": "Last handshake:" + "button-add-interface": "Schnittstelle hinzufügen", + "button-add-peer": "Peer hinzufügen", + "button-add-peers": "Mehrere Peers hinzufügen", + "button-show-peer": "Peer anzeigen", + "button-edit-peer": "Peer bearbeiten", + "peer-disabled": "Peer ist deaktiviert, Grund:", + "peer-expiring": "Peer läuft ab am", + "peer-connected": "Verbunden", + "peer-not-connected": "Nicht verbunden", + "peer-handshake": "Letzter Handshake:" }, "users": { "headline": "Benutzerverwaltung", "table-heading": { "id": "ID", "email": "E-Mail", - "firstname": "Firstname", - "lastname": "Lastname", - "source": "Source", + "firstname": "Vorname", + "lastname": "Nachname", + "source": "Quelle", "peers": "Peers", "admin": "Admin" }, "no-user": { - "headline": "No users available", - "abstract": "Currently, there are no users registered with WireGuard Portal." + "headline": "Keine Benutzer verfügbar", + "abstract": "Derzeit sind keine Benutzer im WireGuard-Portal registriert." }, - "button-add-user": "Add User", - "button-show-user": "Show User", - "button-edit-user": "Edit User", - "user-disabled": "User is disabled, reason:", - "user-locked": "Account is locked, reason:", - "admin": "User has administrator privileges", - "no-admin": "User has no administrator privileges" + "button-add-user": "Benutzer hinzufügen", + "button-show-user": "Benutzer anzeigen", + "button-edit-user": "Benutzer bearbeiten", + "user-disabled": "Benutzer ist deaktiviert, Grund:", + "user-locked": "Konto ist gesperrt, Grund:", + "admin": "Benutzer hat Administratorrechte", + "no-admin": "Benutzer hat keine Administratorrechte" }, "profile": { "headline": "Meine VPN-Konfigurationen", @@ -158,16 +159,16 @@ "name": "Name", "ip": "IP's", "stats": "Status", - "interface": "Server Interface" + "interface": "Server-Schnittstelle" }, "no-peer": { - "headline": "No peers available", - "abstract": "Currently, there are no peers associated with your user profile." + "headline": "Keine Peers verfügbar", + "abstract": "Derzeit sind keine Peers mit Ihrem Benutzerprofil verknüpft." }, - "peer-connected": "Connected", - "button-add-peer": "Add Peer", - "button-show-peer": "Show Peer", - "button-edit-peer": "Edit Peer" + "peer-connected": "Verbunden", + "button-add-peer": "Peer hinzufügen", + "button-show-peer": "Peer anzeigen", + "button-edit-peer": "Peer bearbeiten" }, "settings": { "headline": "Einstellungen", @@ -189,345 +190,362 @@ "api-link": "API Dokumentation" } }, + "audit": { + "headline": "Eventprotokoll", + "abstract": "Hier finden Sie das Eventprotokoll aller im WireGuard-Portal vorgenommenen Aktionen.", + "no-entries": { + "headline": "Keine Protokolleinträge verfügbar", + "abstract": "Derzeit sind keine Eventprotokolle aufgezeichnet." + }, + "entries-headline": "Protokolleinträge", + "table-heading": { + "id": "#", + "time": "Zeit", + "user": "Benutzer", + "severity": "Schweregrad", + "origin": "Ursprung", + "message": "Nachricht" + } + }, "keygen": { "headline": "WireGuard Key Generator", "abstract": "Hier können Sie WireGuard Schlüsselpaare generieren. Die Schlüssel werden lokal auf Ihrem Computer generiert und niemals an den Server gesendet.", "headline-keypair": "Neues Schlüsselpaar", - "headline-preshared-key": "Neuer Pre-shared Key", + "headline-preshared-key": "Neuer Pre-Shared Key", "button-generate": "Erzeugen", "private-key": { - "label": "Private Key", + "label": "Privater Schlüssel", "placeholder": "Der private Schlüssel" }, "public-key": { - "label": "Public Key", + "label": "Öffentlicher Schlüssel", "placeholder": "Der öffentliche Schlüssel" }, "preshared-key": { - "label": "Preshared Key", - "placeholder": "Der Pre-shared Schlüssel" + "label": "Pre-Shared Key", + "placeholder": "Der geteilte Schlüssel" } }, "modals": { "user-view": { - "headline": "User Account:", - "tab-user": "Information", + "headline": "Benutzerkonto:", + "tab-user": "Informationen", "tab-peers": "Peers", - "headline-info": "User Information:", - "headline-notes": "Notes:", + "headline-info": "Benutzerinformationen:", + "headline-notes": "Notizen:", "email": "E-Mail", - "firstname": "Firstname", - "lastname": "Lastname", - "phone": "Phone number", - "department": "Department", - "disabled": "Account Disabled", - "locked": "Account Locked", - "no-peers": "User has no associated peers.", + "firstname": "Vorname", + "lastname": "Nachname", + "phone": "Telefonnummer", + "department": "Abteilung", + "api-enabled": "API-Zugriff", + "disabled": "Konto deaktiviert", + "locked": "Konto gesperrt", + "no-peers": "Benutzer hat keine zugeordneten Peers.", "peers": { "name": "Name", - "interface": "Interface", + "interface": "Schnittstelle", "ip": "IP's" } }, "user-edit": { - "headline-edit": "Edit user:", - "headline-new": "New user", - "header-general": "General", - "header-personal": "User Information", - "header-notes": "Notes", - "header-state": "State", + "headline-edit": "Benutzer bearbeiten:", + "headline-new": "Neuer Benutzer", + "header-general": "Allgemein", + "header-personal": "Benutzerinformationen", + "header-notes": "Notizen", + "header-state": "Status", "identifier": { - "label": "Identifier", - "placeholder": "The unique user identifier" + "label": "Kennung", + "placeholder": "Die eindeutige Benutzerkennung" }, "source": { - "label": "Source", - "placeholder": "The user source" + "label": "Quelle", + "placeholder": "Die Benutzerquelle" }, "password": { - "label": "Password", - "placeholder": "A super secret password", - "description": "Leave this field blank to keep current password." + "label": "Passwort", + "placeholder": "Ein super geheimes Passwort", + "description": "Lassen Sie dieses Feld leer, um das aktuelle Passwort beizubehalten." }, "email": { - "label": "Email", - "placeholder": "The email address" + "label": "E-Mail", + "placeholder": "Die E-Mail-Adresse" }, "phone": { - "label": "Phone", - "placeholder": "The phone number" + "label": "Telefon", + "placeholder": "Die Telefonnummer" }, "department": { - "label": "Department", - "placeholder": "The department" + "label": "Abteilung", + "placeholder": "Die Abteilung" }, "firstname": { - "label": "Firstname", - "placeholder": "Firstname" + "label": "Vorname", + "placeholder": "Vorname" }, "lastname": { - "label": "Lastname", - "placeholder": "Lastname" + "label": "Nachname", + "placeholder": "Nachname" }, "notes": { - "label": "Notes", + "label": "Notizen", "placeholder": "" }, "disabled": { - "label": "Disabled (no WireGuard connection and no login possible)" + "label": "Deaktiviert (keine WireGuard-Verbindung und kein Login möglich)" }, "locked": { - "label": "Locked (no login possible, WireGuard connections still work)" + "label": "Gesperrt (kein Login möglich, WireGuard-Verbindungen funktionieren weiterhin)" }, "admin": { - "label": "Is Admin" + "label": "Ist Administrator" } }, "interface-view": { - "headline": "Config for Interface:" + "headline": "Konfiguration für Schnittstelle:" }, "interface-edit": { - "headline-edit": "Edit Interface:", - "headline-new": "New Interface", - "tab-interface": "Interface", - "tab-peerdef": "Peer Defaults", - "header-general": "General", - "header-network": "Network", - "header-crypto": "Cryptography", - "header-hooks": "Interface Hooks", + "headline-edit": "Schnittstelle bearbeiten:", + "headline-new": "Neue Schnittstelle", + "tab-interface": "Schnittstelle", + "tab-peerdef": "Peer-Standardeinstellungen", + "header-general": "Allgemein", + "header-network": "Netzwerk", + "header-crypto": "Kryptografie", + "header-hooks": "Schnittstellen-Hooks", "header-peer-hooks": "Hooks", - "header-state": "State", + "header-state": "Status", "identifier": { - "label": "Identifier", - "placeholder": "The unique interface identifier" + "label": "Kennung", + "placeholder": "Die eindeutige Schnittstellenkennung" }, "mode": { - "label": "Interface Mode", - "server": "Server Mode", - "client": "Client Mode", - "any": "Unknown Mode" + "label": "Schnittstellenmodus", + "server": "Server-Modus", + "client": "Client-Modus", + "any": "Unbekannter Modus" }, "display-name": { - "label": "Display Name", - "placeholder": "The descriptive name for the interface" + "label": "Anzeigename", + "placeholder": "Der beschreibende Name für die Schnittstelle" }, "private-key": { - "label": "Private Key", - "placeholder": "The private key" + "label": "Privater Schlüssel", + "placeholder": "Der private Schlüssel" }, "public-key": { - "label": "Public Key", - "placeholder": "The public key" + "label": "Öffentlicher Schlüssel", + "placeholder": "Der öffentliche Schlüssel" }, "ip": { - "label": "IP Addresses", - "placeholder": "IP Addresses (CIDR format)" + "label": "IP-Adressen", + "placeholder": "IP-Adressen (CIDR-Format)" }, "listen-port": { - "label": "Listen Port", - "placeholder": "The listening port" + "label": "Port", + "placeholder": "Der Port der WireGuard Schnittstelle" }, "dns": { - "label": "DNS Server", - "placeholder": "The DNS servers that should be used" + "label": "DNS-Server", + "placeholder": "Die zu verwendenden DNS-Server" }, "dns-search": { - "label": "DNS Search Domains", - "placeholder": "DNS search prefixes" + "label": "DNS-Suchdomänen", + "placeholder": "DNS-Suchpräfixe" }, "mtu": { "label": "MTU", - "placeholder": "The interface MTU (0 = keep default)" + "placeholder": "Die Schnittstellen-MTU (0 = Standard beibehalten)" }, "firewall-mark": { - "label": "Firewall Mark", - "placeholder": "Firewall mark that is applied to outgoing traffic. (0 = automatic)" + "label": "Firewall-Markierung", + "placeholder": "Firewall-Markierung, die auf ausgehenden Datenverkehr angewendet wird. (0 = automatisch)" }, "routing-table": { - "label": "Routing Table", - "placeholder": "The routing table ID", - "description": "Special cases: off = do not manage routes, 0 = automatic" + "label": "Routing-Tabelle", + "placeholder": "Die Routing-Tabellen-ID", + "description": "Spezialfälle: off = Routen nicht verwalten, 0 = automatisch" }, "pre-up": { "label": "Pre-Up", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "post-up": { "label": "Post-Up", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "pre-down": { "label": "Pre-Down", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "post-down": { "label": "Post-Down", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "disabled": { - "label": "Interface Disabled" + "label": "Schnittstelle deaktiviert" }, "save-config": { - "label": "Automatically save wg-quick config" + "label": "wg-quick Konfiguration automatisch speichern" }, "defaults": { "endpoint": { - "label": "Endpoint Address", - "placeholder": "Endpoint Address", - "description": "The endpoint address that peers will connect to. (e.g. wg.example.com or wg.example.com:51820)" + "label": "Endpunktadresse", + "placeholder": "Endpunktadresse", + "description": "Die Endpunktadresse, mit der sich Peers verbinden. (z.B. wg.example.com oder wg.example.com:51820)" }, "networks": { - "label": "IP Networks", - "placeholder": "Network Addresses", - "description": "Peers will get IP addresses from those subnets." + "label": "IP-Netzwerke", + "placeholder": "Netzwerkadressen", + "description": "Peers erhalten IP-Adressen aus diesen Subnetzen." }, "allowed-ip": { - "label": "Allowed IP Addresses", - "placeholder": "Default Allowed IP Addresses" + "label": "Erlaubte IP-Adressen", + "placeholder": "Erlaubte IP-Adressen für Peers" }, "mtu": { "label": "MTU", - "placeholder": "The client MTU (0 = keep default)" + "placeholder": "Die Client-MTU (0 = Standard beibehalten)" }, "keep-alive": { - "label": "Keep Alive Interval", - "placeholder": "Persistent Keepalive (0 = default)" + "label": "Keepalive-Intervall", + "placeholder": "Persistentes Keepalive (0 = Standard)" } }, - - "button-apply-defaults": "Apply Peer Defaults" + "button-apply-defaults": "Peer-Standardeinstellungen anwenden" }, "peer-view": { "headline-peer": "Peer:", - "headline-endpoint": "Endpoint:", - "section-info": "Peer Information", - "section-status": "Current Status", - "section-config": "Configuration", - "identifier": "Identifier", - "ip": "IP Addresses", - "user": "Associated User", - "notes": "Notes", - "expiry-status": "Expires At", - "disabled-status": "Disabled At", - "traffic": "Traffic", - "connection-status": "Connection Stats", - "upload": "Uploaded Bytes (from Server to Peer)", - "download": "Downloaded Bytes (from Peer to Server)", - "pingable": "Is Pingable", - "handshake": "Last Handshake", - "connected-since": "Connected since", - "endpoint": "Endpoint", - "button-download": "Download configuration", - "button-email": "Send configuration via E-Mail" + "headline-endpoint": "Endpunkt:", + "section-info": "Peer-Informationen", + "section-status": "Aktueller Status", + "section-config": "Konfiguration", + "identifier": "Kennung", + "ip": "IP-Adressen", + "user": "Zugeordneter Benutzer", + "notes": "Notizen", + "expiry-status": "Läuft ab am", + "disabled-status": "Deaktiviert am", + "traffic": "Datenverkehr", + "connection-status": "Verbindungsstatistiken", + "upload": "Hochgeladene Bytes (vom Server zum Peer)", + "download": "Heruntergeladene Bytes (vom Peer zum Server)", + "pingable": "Pingbar", + "handshake": "Letzter Handshake", + "connected-since": "Verbunden seit", + "endpoint": "Endpunkt", + "button-download": "Konfiguration herunterladen", + "button-email": "Konfiguration per E-Mail senden" }, "peer-edit": { - "headline-edit-peer": "Edit peer:", - "headline-edit-endpoint": "Edit endpoint:", - "headline-new-peer": "Create peer", - "headline-new-endpoint": "Create endpoint", - "header-general": "General", - "header-network": "Network", - "header-crypto": "Cryptography", - "header-hooks": "Hooks (Executed on Peer)", - "header-state": "State", + "headline-edit-peer": "Peer bearbeiten:", + "headline-edit-endpoint": "Endpunkt bearbeiten:", + "headline-new-peer": "Peer erstellen", + "headline-new-endpoint": "Endpunkt erstellen", + "header-general": "Allgemein", + "header-network": "Netzwerk", + "header-crypto": "Kryptografie", + "header-hooks": "Hooks (beim Peer ausgeführt)", + "header-state": "Status", "display-name": { - "label": "Display Name", - "placeholder": "The descriptive name for the peer" + "label": "Anzeigename", + "placeholder": "Der beschreibende Name für den Peer" }, "linked-user": { - "label": "Linked User", - "placeholder": "The user account which owns this peer" + "label": "Verknüpfter Benutzer", + "placeholder": "Das Benutzerkonto, dem dieser Peer gehört" }, "private-key": { - "label": "Private Key", - "placeholder": "The private key", + "label": "Privater Schlüssel", + "placeholder": "Der private Schlüssel", "help": "Der private Schlüssel wird sicher auf dem Server gespeichert. Wenn der Benutzer bereits eine Kopie besitzt, kann dieses Feld entfallen. Der Server funktioniert auch ausschließlich mit dem öffentlichen Schlüssel des Peers." }, "public-key": { - "label": "Public Key", - "placeholder": "The public key" + "label": "Öffentlicher Schlüssel", + "placeholder": "Der öffentliche Schlüssel" }, "preshared-key": { - "label": "Preshared Key", - "placeholder": "Optional pre-shared key" + "label": "Pre-Shared Key", + "placeholder": "Optionaler geteilter Schlüssel" }, "endpoint-public-key": { - "label": "Endpoint public Key", - "placeholder": "The public key of the remote endpoint" + "label": "Öffentlicher Endpunktschlüssel", + "placeholder": "Der öffentliche Schlüssel des entfernten Endpunkts" }, "endpoint": { - "label": "Endpoint Address", - "placeholder": "The address of the remote endpoint" + "label": "Endpunktadresse", + "placeholder": "Die Adresse des entfernten Endpunkts" }, "ip": { - "label": "IP Addresses", - "placeholder": "IP Addresses (CIDR format)" + "label": "IP-Adressen", + "placeholder": "IP-Adressen (CIDR-Format)" }, "allowed-ip": { - "label": "Allowed IP Addresses", - "placeholder": "Allowed IP Addresses (CIDR format)" + "label": "Erlaubte IP-Adressen", + "placeholder": "Erlaubte IP-Adressen (CIDR-Format)" }, "extra-allowed-ip": { - "label": "Extra allowed IP Addresses", - "placeholder": "Extra allowed IP's (Server Sided)", - "description": "Those IP's will be added on the remote WireGuard interface as allowed IP's." + "label": "Zusätzliche erlaubte IP-Adressen", + "placeholder": "Zusätzliche erlaubte IP's (Server-seitig)", + "description": "Diese IPs werden an der entfernten WireGuard-Schnittstelle als erlaubte IPs hinzugefügt." }, "dns": { - "label": "DNS Server", - "placeholder": "The DNS servers that should be used" + "label": "DNS-Server", + "placeholder": "Die zu verwendenden DNS-Server" }, "dns-search": { - "label": "DNS Search Domains", - "placeholder": "DNS search prefixes" + "label": "DNS-Suchdomänen", + "placeholder": "DNS-Suchpräfixe" }, "keep-alive": { - "label": "Keep Alive Interval", - "placeholder": "Persistent Keepalive (0 = default)" + "label": "Keepalive-Intervall", + "placeholder": "Persistentes Keepalive (0 = Standard)" }, "mtu": { "label": "MTU", - "placeholder": "The client MTU (0 = keep default)" + "placeholder": "Die Client-MTU (0 = Standard beibehalten)" }, "pre-up": { "label": "Pre-Up", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "post-up": { "label": "Post-Up", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "pre-down": { "label": "Pre-Down", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "post-down": { "label": "Post-Down", - "placeholder": "One or multiple bash commands separated by ;" + "placeholder": "Ein oder mehrere Bash-Befehle, getrennt durch ;" }, "disabled": { - "label": "Peer Disabled" + "label": "Peer deaktiviert" }, "ignore-global": { - "label": "Ignore global settings" + "label": "Globale Einstellungen ignorieren" }, "expires-at": { - "label": "Expiry date" + "label": "Ablaufdatum" } }, "peer-multi-create": { - "headline-peer": "Create multiple peers", - "headline-endpoint": "Create multiple endpoints", + "headline-peer": "Mehrere Peers erstellen", + "headline-endpoint": "Mehrere Endpunkte erstellen", "identifiers": { - "label": "User Identifiers", - "placeholder": "User Identifiers", - "description": "A user identifier (the username) for which a peer should be created." + "label": "Benutzerkennungen", + "placeholder": "Benutzerkennungen", + "description": "Eine Benutzerkennung (der Benutzername), für die ein Peer erstellt werden soll." }, "prefix": { "headline-peer": "Peer:", - "headline-endpoint": "Endpoint:", - "label": "Display Name Prefix", - "placeholder": "The prefix", - "description": "A prefix that is added to the peers display name." + "headline-endpoint": "Endpunkt:", + "label": "Anzeigename-Präfix", + "placeholder": "Das Präfix", + "description": "Ein Präfix, das dem Anzeigenamen des Peers hinzugefügt wird." } } } diff --git a/frontend/src/views/AuditView.vue b/frontend/src/views/AuditView.vue index 982233e..108827a 100644 --- a/frontend/src/views/AuditView.vue +++ b/frontend/src/views/AuditView.vue @@ -81,7 +81,7 @@ onMounted(async () => {
- diff --git a/frontend/src/views/InterfaceView.vue b/frontend/src/views/InterfaceView.vue index 82912b5..1084081 100644 --- a/frontend/src/views/InterfaceView.vue +++ b/frontend/src/views/InterfaceView.vue @@ -416,7 +416,7 @@ onMounted(async () => {
- diff --git a/frontend/src/views/ProfileView.vue b/frontend/src/views/ProfileView.vue index ebfa091..a5daec2 100644 --- a/frontend/src/views/ProfileView.vue +++ b/frontend/src/views/ProfileView.vue @@ -178,7 +178,7 @@ onMounted(async () => { {{ $t('general.pagination.size')}}:
- diff --git a/frontend/src/views/UserView.vue b/frontend/src/views/UserView.vue index c9b34d3..4c96284 100644 --- a/frontend/src/views/UserView.vue +++ b/frontend/src/views/UserView.vue @@ -116,7 +116,7 @@ onMounted(() => {
- diff --git a/mkdocs.yml b/mkdocs.yml index 5b285fd..9bafbe5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,6 +30,15 @@ plugins: - minify: minify_html: true - swagger-ui-tag + - mike: + # These fields are all optional; the defaults are as below... + alias_type: symlink + redirect_template: null + deploy_prefix: '' + canonical_version: null + version_selector: true + css_dir: css + javascript_dir: js extra: version: