mirror of
https://github.com/h44z/wg-portal.git
synced 2025-06-27 16:57:01 +00:00
Merge branch 'master' into stable
This commit is contained in:
commit
18296673d7
6
.github/workflows/docker-publish.yml
vendored
6
.github/workflows/docker-publish.yml
vendored
@ -4,7 +4,7 @@ on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
push:
|
||||
branches: [master, stable, legacy]
|
||||
branches: [master]
|
||||
# Publish vX.X.X tags as releases.
|
||||
tags: ["v*.*.*"]
|
||||
|
||||
@ -64,12 +64,12 @@ jobs:
|
||||
# major and major.minor tags are not available for alpha or beta releases
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=semver,pattern=v{{major}}.{{minor}}
|
||||
type=semver,pattern=v{{major}}
|
||||
# add v{{major}} tag, even for beta or release-canidate releases
|
||||
type=match,pattern=(v\d),group=1,enable=${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
||||
# add {{major}} tag, even for beta releases or release-canidate releases
|
||||
type=match,pattern=v(\d),group=1,enable=${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
||||
# set latest tag for default branch
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
|
9
.github/workflows/pages.yml
vendored
9
.github/workflows/pages.yml
vendored
@ -27,7 +27,14 @@ jobs:
|
||||
run: pip install mike mkdocs-material[imaging] mkdocs-minify-plugin mkdocs-swagger-ui-tag
|
||||
|
||||
- name: Publish documentation
|
||||
run: mike deploy --push --update-aliases ${{ github.ref_name }} latest
|
||||
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
|
||||
run: mike deploy --push ${{ github.ref_name }}
|
||||
env:
|
||||
GIT_COMMITTER_NAME: "github-actions[bot]"
|
||||
GIT_COMMITTER_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
- name: Publish latest documentation
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
run: mike deploy --push --update-aliases ${{ github.ref_name }} latest
|
||||
env:
|
||||
GIT_COMMITTER_NAME: "github-actions[bot]"
|
||||
GIT_COMMITTER_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
|
@ -72,7 +72,8 @@ auth:
|
||||
|
||||
auth:
|
||||
oidc:
|
||||
# a sample Entra ID provider with environment variable substitution
|
||||
# A sample Entra ID provider with environment variable substitution.
|
||||
# Only users with an @outlook.com email address are allowed to register or login.
|
||||
- id: azure
|
||||
provider_name: azure
|
||||
display_name: Login with</br>Entra ID
|
||||
@ -80,6 +81,8 @@ auth:
|
||||
base_url: "https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0"
|
||||
client_id: "${AZURE_CLIENT_ID}"
|
||||
client_secret: "${AZURE_CLIENT_SECRET}"
|
||||
allowed_domains:
|
||||
- "outlook.com"
|
||||
extra_scopes:
|
||||
- profile
|
||||
- email
|
||||
|
@ -368,6 +368,10 @@ Below are the properties for each OIDC provider entry inside `auth.oidc`:
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A list of additional OIDC scopes (e.g., `profile`, `email`).
|
||||
|
||||
#### `allowed_domains`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
|
||||
|
||||
#### `field_map`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** Maps OIDC claims to WireGuard Portal user fields.
|
||||
@ -437,6 +441,10 @@ Below are the properties for each OAuth provider entry inside `auth.oauth`:
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A list of OAuth scopes.
|
||||
|
||||
#### `allowed_domains`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
|
||||
|
||||
#### `field_map`
|
||||
- **Default:** *(empty)*
|
||||
- **Description:** Maps OAuth attributes to WireGuard Portal fields.
|
||||
|
@ -110,31 +110,33 @@ WireGuard Portal supports managing WireGuard interfaces through three distinct d
|
||||
## Image Versioning
|
||||
|
||||
All images are hosted on Docker Hub at [https://hub.docker.com/r/wgportal/wg-portal](https://hub.docker.com/r/wgportal/wg-portal) or in the [GitHub Container Registry](https://github.com/h44z/wg-portal/pkgs/container/wg-portal).
|
||||
|
||||
Version **2** is the current stable release. Version **1** has moved to legacy status and is no longer recommended.
|
||||
|
||||
There are three types of tags in the repository:
|
||||
|
||||
#### Semantic versioned tags
|
||||
|
||||
For example, `2.0.0-rc.1` or `v2.0.0-rc.1`.
|
||||
|
||||
These are official releases of WireGuard Portal. They correspond to the GitHub tags that we make, and you can see the release notes for them here: [https://github.com/h44z/wg-portal/releases](https://github.com/h44z/wg-portal/releases).
|
||||
These are official releases of WireGuard Portal. For production deployments of WireGuard Portal, we strongly recommend using one of these versioned tags instead of the latest or canary tags.
|
||||
|
||||
Once these tags show up in this repository, they will never change.
|
||||
There are different types of these 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.
|
||||
- Major version tags: `v2` or `2`. These tags always refer to the latest image for WireGuard Portal version **2**.
|
||||
- Minor version tags: `v2.x` or `2.0`. These tags always refer to the latest image for WireGuard Portal version **2.x**.
|
||||
- Specific version tags (patch version): `v2.0.0` or `2.0.0`. These tags denote a very specific release. They correspond to the GitHub tags that we make, and you can see the release notes for them here: [https://github.com/h44z/wg-portal/releases](https://github.com/h44z/wg-portal/releases). Once these tags for a specific version show up in the Docker repository, they will never change.
|
||||
|
||||
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`.
|
||||
#### The `latest` tag
|
||||
|
||||
Version **2** is the current stable release. Version **1** has moved to legacy status and is no longer recommended.
|
||||
The lastest tag is the latest stable release of WireGuard Portal. For version **2**, this is the same as the `v2` tag.
|
||||
|
||||
#### latest
|
||||
#### The `master` tag
|
||||
|
||||
This is the most recent build to master! It changes a lot and is very unstable.
|
||||
This is the most recent build to the main branch! It changes a lot and is very unstable.
|
||||
|
||||
We recommend that you don't use it except for development purposes.
|
||||
We recommend that you don't use it except for development purposes or to test the latest features.
|
||||
|
||||
#### Branch tags
|
||||
|
||||
For each commit in the master and the stable branch, a corresponding Docker image is build. These images use the `master` or `stable` tags.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -692,6 +692,7 @@ paths:
|
||||
tags:
|
||||
- Interfaces
|
||||
put:
|
||||
description: This endpoint updates an existing interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).
|
||||
operationId: interfaces_handleUpdatePut
|
||||
parameters:
|
||||
- description: The interface identifier.
|
||||
@ -739,6 +740,7 @@ paths:
|
||||
- Interfaces
|
||||
/interface/new:
|
||||
post:
|
||||
description: This endpoint creates a new interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).
|
||||
operationId: interfaces_handleCreatePost
|
||||
parameters:
|
||||
- description: The interface data.
|
||||
@ -779,6 +781,34 @@ paths:
|
||||
summary: Create a new interface record.
|
||||
tags:
|
||||
- Interfaces
|
||||
/interface/prepare:
|
||||
get:
|
||||
description: This endpoint returns a new interface with default values (fresh key pair, valid name, new IP address pool, ...).
|
||||
operationId: interfaces_handlePrepareGet
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.Interface'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
security:
|
||||
- BasicAuth: []
|
||||
summary: Prepare a new interface record.
|
||||
tags:
|
||||
- Interfaces
|
||||
/metrics/by-interface/{id}:
|
||||
get:
|
||||
operationId: metrics_handleMetricsForInterfaceGet
|
||||
@ -967,7 +997,7 @@ paths:
|
||||
tags:
|
||||
- Peers
|
||||
put:
|
||||
description: Only admins can update existing records.
|
||||
description: Only admins can update existing records. The peer record must contain all required fields (e.g., public key, allowed IPs).
|
||||
operationId: peers_handleUpdatePut
|
||||
parameters:
|
||||
- description: The peer identifier.
|
||||
@ -1078,7 +1108,7 @@ paths:
|
||||
- Peers
|
||||
/peer/new:
|
||||
post:
|
||||
description: Only admins can create new records.
|
||||
description: Only admins can create new records. The peer record must contain all required fields (e.g., public key, allowed IPs).
|
||||
operationId: peers_handleCreatePost
|
||||
parameters:
|
||||
- description: The peer data.
|
||||
@ -1119,6 +1149,48 @@ paths:
|
||||
summary: Create a new peer record.
|
||||
tags:
|
||||
- Peers
|
||||
/peer/prepare/{id}:
|
||||
get:
|
||||
description: This endpoint is used to prepare a new peer record. The returned data contains a fresh key pair and valid ip address.
|
||||
operationId: peers_handlePrepareGet
|
||||
parameters:
|
||||
- description: The interface identifier.
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.Peer'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
security:
|
||||
- BasicAuth: []
|
||||
summary: Prepare a new peer record for the given WireGuard interface.
|
||||
tags:
|
||||
- Peers
|
||||
/provisioning/data/peer-config:
|
||||
get:
|
||||
description: Normal users can only access their own record. Admins can access all records.
|
||||
|
@ -24,7 +24,7 @@
|
||||
<div id="toasts"></div>
|
||||
|
||||
<!-- main application -->
|
||||
<div id="app"></div>
|
||||
<div id="app" class="d-flex flex-column flex-grow-1"></div>
|
||||
|
||||
<!-- vue teleport will add modals and dialogs here -->
|
||||
<div id="modals"></div>
|
||||
|
@ -140,6 +140,7 @@ const currentYear = ref(new Date().getFullYear())
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer></template>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
|
@ -20,14 +20,14 @@
|
||||
"delete": "Eliminar"
|
||||
},
|
||||
"login": {
|
||||
"headline": "Por favor, inicie sessão",
|
||||
"headline": "Por favor, inicie a sessão",
|
||||
"username": {
|
||||
"label": "Nome de utilizador",
|
||||
"placeholder": "Introduza o seu nome de utilizador"
|
||||
"placeholder": "Por favor, insira o seu nome de utilizador"
|
||||
},
|
||||
"password": {
|
||||
"label": "Palavra-passe",
|
||||
"placeholder": "Introduza a sua palavra-passe"
|
||||
"placeholder": "Por favor, insira a sua palavra-passe"
|
||||
},
|
||||
"button": "Iniciar sessão"
|
||||
},
|
||||
@ -40,143 +40,513 @@
|
||||
"settings": "Definições",
|
||||
"audit": "Registo de Auditoria",
|
||||
"login": "Iniciar Sessão",
|
||||
"logout": "Terminar Sessão"
|
||||
"logout": "Terminar Sessão",
|
||||
"keygen": "Gerador de Chave"
|
||||
},
|
||||
"home": {
|
||||
"title": "Início",
|
||||
"card": {
|
||||
"interfaces": "Interfaces",
|
||||
"users": "Utilizadores"
|
||||
"headline": "WireGuard® Portal VPN",
|
||||
"info-headline": "Mais Informações",
|
||||
"abstract": "WireGuard® é uma VPN extremamente simples, mas rápida e moderna que utiliza criptografia de última geração. O seu objetivo é ser mais rápida, simples, leve e útil que o IPsec, enquanto evita grandes dores de cabeça. Pretende ser consideravelmente mais eficiente que o OpenVPN.",
|
||||
"installation": {
|
||||
"box-header": "Instalação do WireGuard",
|
||||
"headline": "Instalação",
|
||||
"content": "As instruções de instalação para o software cliente podem ser encontradas no site oficial do WireGuard.",
|
||||
"button": "Abrir Instruções"
|
||||
},
|
||||
"about-wg": {
|
||||
"box-header": "Sobre o WireGuard",
|
||||
"headline": "Sobre",
|
||||
"content": "WireGuard® é uma VPN extremamente simples, mas rápida e moderna que utiliza criptografia de última geração.",
|
||||
"button": "Mais"
|
||||
},
|
||||
"about-portal": {
|
||||
"box-header": "Sobre o WireGuard Portal",
|
||||
"headline": "WireGuard Portal",
|
||||
"content": "WireGuard Portal é um portal web de configuração simples para o WireGuard.",
|
||||
"button": "Mais"
|
||||
},
|
||||
"profiles": {
|
||||
"headline": "Perfis VPN",
|
||||
"abstract": "Pode aceder e baixar as suas configurações pessoais de VPN através do seu Perfil de Utilizador.",
|
||||
"content": "Para encontrar todos os seus perfis configurados, clique no botão abaixo.",
|
||||
"button": "Abrir meu perfil"
|
||||
},
|
||||
"admin": {
|
||||
"headline": "Área de Administração",
|
||||
"abstract": "Na área de administração, pode gerir os peers do WireGuard, a interface do servidor e os utilizadores que têm permissão para aceder ao Portal WireGuard.",
|
||||
"content": "",
|
||||
"button-admin": "Abrir Administração do Servidor",
|
||||
"button-user": "Abrir Administração de Utilizadores"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces",
|
||||
"create": "Criar Interface",
|
||||
"name": "Nome",
|
||||
"address": "Endereço",
|
||||
"listen-port": "Porta de Escuta",
|
||||
"public-key": "Chave Pública",
|
||||
"private-key": "Chave Privada",
|
||||
"actions": "Ações",
|
||||
"delete-dialog": {
|
||||
"title": "Eliminar Interface",
|
||||
"text": "Tem a certeza de que deseja eliminar a interface '{{name}}'?"
|
||||
"headline": "Administração de Interfaces",
|
||||
"headline-peers": "Peers VPN Atuais",
|
||||
"headline-endpoints": "Endpoints Atuais",
|
||||
"no-interface": {
|
||||
"default-selection": "Nenhuma interface disponível",
|
||||
"headline": "Nenhuma interface encontrada...",
|
||||
"abstract": "Clique no botão + acima para criar uma nova interface WireGuard."
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nome",
|
||||
"placeholder": "Introduza um nome exclusivo para a interface"
|
||||
},
|
||||
"address": {
|
||||
"label": "Endereço",
|
||||
"placeholder": "Introduza um endereço válido (ex: 10.0.0.1/24)"
|
||||
},
|
||||
"listen-port": {
|
||||
"label": "Porta de Escuta",
|
||||
"placeholder": "Introduza a porta onde o WireGuard irá escutar (ex: 51820)"
|
||||
},
|
||||
"private-key": {
|
||||
"label": "Chave Privada",
|
||||
"placeholder": "Será gerada automaticamente se não for fornecida"
|
||||
}
|
||||
}
|
||||
"no-peer": {
|
||||
"headline": "Nenhum peer disponível",
|
||||
"abstract": "Atualmente, não há peers disponíveis para a interface WireGuard selecionada."
|
||||
},
|
||||
"table-heading": {
|
||||
"name": "Nome",
|
||||
"user": "Utilizador",
|
||||
"ip": "IPs",
|
||||
"endpoint": "Endpoint",
|
||||
"status": "Status"
|
||||
},
|
||||
"interface": {
|
||||
"headline": "Status da interface para",
|
||||
"mode": "modo",
|
||||
"key": "Chave Pública",
|
||||
"endpoint": "Endpoint Público",
|
||||
"port": "Porta de Escuta",
|
||||
"peers": "Peers Ativados",
|
||||
"total-peers": "Total de Peers",
|
||||
"endpoints": "Endpoints Ativados",
|
||||
"total-endpoints": "Total de Endpoints",
|
||||
"ip": "Endereço IP",
|
||||
"default-allowed-ip": "IPs permitidos por padrão",
|
||||
"dns": "Servidores DNS",
|
||||
"mtu": "MTU",
|
||||
"default-keep-alive": "Intervalo de Keepalive Padrão",
|
||||
"button-show-config": "Mostrar configuração",
|
||||
"button-download-config": "Baixar configuração",
|
||||
"button-store-config": "Armazenar configuração para wg-quick",
|
||||
"button-edit": "Editar interface"
|
||||
},
|
||||
"button-add-interface": "Adicionar Interface",
|
||||
"button-add-peer": "Adicionar Peer",
|
||||
"button-add-peers": "Adicionar Vários Peers",
|
||||
"button-show-peer": "Mostrar Peer",
|
||||
"button-edit-peer": "Editar Peer",
|
||||
"peer-disabled": "Peer desativado, razão:",
|
||||
"peer-expiring": "Peer expira em",
|
||||
"peer-connected": "Conectado",
|
||||
"peer-not-connected": "Não Conectado",
|
||||
"peer-handshake": "Último handshake:"
|
||||
},
|
||||
"users": {
|
||||
"title": "Utilizadores",
|
||||
"create": "Criar Utilizador",
|
||||
"name": "Nome",
|
||||
"email": "Email",
|
||||
"enabled": "Ativo",
|
||||
"is-admin": "Administrador",
|
||||
"actions": "Ações",
|
||||
"edit": "Editar",
|
||||
"delete-dialog": {
|
||||
"title": "Eliminar Utilizador",
|
||||
"text": "Tem a certeza de que deseja eliminar o utilizador '{{nome}}'?"
|
||||
"headline": "Administração de Utilizadores",
|
||||
"table-heading": {
|
||||
"id": "ID",
|
||||
"email": "E-Mail",
|
||||
"firstname": "Primeiro Nome",
|
||||
"lastname": "Último Nome",
|
||||
"source": "Fonte",
|
||||
"peers": "Peers",
|
||||
"admin": "Administrador"
|
||||
},
|
||||
"form": {
|
||||
"name": {
|
||||
"label": "Nome",
|
||||
"placeholder": "Introduza o nome do utilizador"
|
||||
"no-user": {
|
||||
"headline": "Nenhum utilizador disponível",
|
||||
"abstract": "Atualmente, não há utilizadores registados no Portal WireGuard."
|
||||
},
|
||||
"button-add-user": "Adicionar Utilizador",
|
||||
"button-show-user": "Mostrar Utilizador",
|
||||
"button-edit-user": "Editar Utilizador",
|
||||
"user-disabled": "Utilizador desativado, razão:",
|
||||
"user-locked": "Conta bloqueada, razão:",
|
||||
"admin": "O utilizador tem privilégios de administrador",
|
||||
"no-admin": "O utilizador não tem privilégios de administrador"
|
||||
},
|
||||
"profile": {
|
||||
"headline": "Os Meus Peers VPN",
|
||||
"table-heading": {
|
||||
"name": "Nome",
|
||||
"ip": "IPs",
|
||||
"stats": "Status",
|
||||
"interface": "Interface do Servidor"
|
||||
},
|
||||
"no-peer": {
|
||||
"headline": "Nenhum peer disponível",
|
||||
"abstract": "Atualmente, não há peers associados ao seu perfil de utilizador."
|
||||
},
|
||||
"peer-connected": "Conectado",
|
||||
"button-add-peer": "Adicionar Peer",
|
||||
"button-show-peer": "Mostrar Peer",
|
||||
"button-edit-peer": "Editar Peer"
|
||||
},
|
||||
"settings": {
|
||||
"headline": "Definições",
|
||||
"abstract": "Aqui pode alterar suas Definições pessoais.",
|
||||
"api": {
|
||||
"headline": "Definições da API",
|
||||
"abstract": "Aqui pode configurar as definições da API RESTful.",
|
||||
"active-description": "A API está atualmente ativa para a sua conta de utilizador. Todos os pedidos para a API são autenticadas com Basic Auth. Use as seguintes credenciais para autenticação.",
|
||||
"inactive-description": "A API está atualmente inativa. Pressione o botão abaixo para ativá-la.",
|
||||
"user-label": "Nome de utilizador API:",
|
||||
"user-placeholder": "O utilizador da API",
|
||||
"token-label": "Senha da API:",
|
||||
"token-placeholder": "O token da API",
|
||||
"token-created-label": "Acesso API concedido em: ",
|
||||
"button-disable-title": "Desativar API, invalidando o token atual.",
|
||||
"button-disable-text": "Desativar API",
|
||||
"button-enable-title": "Ativar API, gerando um novo token.",
|
||||
"button-enable-text": "Ativar API",
|
||||
"api-link": "Documentação da API"
|
||||
}
|
||||
},
|
||||
"audit": {
|
||||
"headline": "Registo de Auditoria",
|
||||
"abstract": "Aqui pode encontrar o registo de auditoria de todas as ações realizadas no WireGuard Portal.",
|
||||
"no-entries": {
|
||||
"headline": "Nenhuma entrada no registo",
|
||||
"abstract": "Atualmente, não há entradas de registo de auditoria gravadas."
|
||||
},
|
||||
"entries-headline": "Entradas do Registo",
|
||||
"table-heading": {
|
||||
"id": "#",
|
||||
"time": "Hora",
|
||||
"user": "Utilizador",
|
||||
"severity": "Gravidade",
|
||||
"origin": "Origem",
|
||||
"message": "Mensagem"
|
||||
}
|
||||
},
|
||||
"keygen": {
|
||||
"headline": "Gerador de Chaves WireGuard",
|
||||
"abstract": "Gere novas chaves WireGuard. As chaves são geradas no seu browser e nunca são enviadas para o servidor.",
|
||||
"headline-keypair": "Novo Par de Chaves",
|
||||
"headline-preshared-key": "Nova Chave Pré-Partilhada",
|
||||
"button-generate": "Gerar",
|
||||
"private-key": {
|
||||
"label": "Chave Privada",
|
||||
"placeholder": "A chave privada"
|
||||
},
|
||||
"public-key": {
|
||||
"label": "Chave Pública",
|
||||
"placeholder": "A chave pública"
|
||||
},
|
||||
"preshared-key": {
|
||||
"label": "Chave Pré-Partilhada",
|
||||
"placeholder": "A chave pré-partilhada"
|
||||
}
|
||||
},
|
||||
"modals": {
|
||||
"user-view": {
|
||||
"headline": "Conta de Utilizador:",
|
||||
"tab-user": "Informação",
|
||||
"tab-peers": "Peers",
|
||||
"headline-info": "Informação do Utilizador:",
|
||||
"headline-notes": "Notas:",
|
||||
"email": "E-Mail",
|
||||
"firstname": "Primeiro Nome",
|
||||
"lastname": "Último Nome",
|
||||
"phone": "Número de Telefone",
|
||||
"department": "Departamento",
|
||||
"api-enabled": "Acesso API",
|
||||
"disabled": "Conta Desativada",
|
||||
"locked": "Conta Bloqueada",
|
||||
"no-peers": "O utilizador não tem peers associados.",
|
||||
"peers": {
|
||||
"name": "Nome",
|
||||
"interface": "Interface",
|
||||
"ip": "IP's"
|
||||
}
|
||||
},
|
||||
"user-edit": {
|
||||
"headline-edit": "Editar utilizador:",
|
||||
"headline-new": "Novo utilizador",
|
||||
"header-general": "Geral",
|
||||
"header-personal": "Informação do Utilizador",
|
||||
"header-notes": "Notas",
|
||||
"header-state": "Estado",
|
||||
"identifier": {
|
||||
"label": "Identificador",
|
||||
"placeholder": "O identificador único do utilizador"
|
||||
},
|
||||
"email": {
|
||||
"label": "Email",
|
||||
"placeholder": "Introduza o email do utilizador"
|
||||
"source": {
|
||||
"label": "Fonte",
|
||||
"placeholder": "A fonte do utilizador"
|
||||
},
|
||||
"password": {
|
||||
"label": "Palavra-passe",
|
||||
"placeholder": "Deixe em branco para manter a atual"
|
||||
"placeholder": "Uma palavra-passe super secreta",
|
||||
"description": "Deixe este campo em branco para manter a palavra-passe atual."
|
||||
},
|
||||
"is-admin": {
|
||||
"label": "Administrador"
|
||||
"email": {
|
||||
"label": "Email",
|
||||
"placeholder": "O endereço de e-mail"
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Ativo"
|
||||
"phone": {
|
||||
"label": "Telefone",
|
||||
"placeholder": "O número de telefone"
|
||||
},
|
||||
"department": {
|
||||
"label": "Departamento",
|
||||
"placeholder": "O departamento"
|
||||
},
|
||||
"firstname": {
|
||||
"label": "Primeiro Nome",
|
||||
"placeholder": "Primeiro Nome"
|
||||
},
|
||||
"lastname": {
|
||||
"label": "Último Nome",
|
||||
"placeholder": "Último Nome"
|
||||
},
|
||||
"notes": {
|
||||
"label": "Notas",
|
||||
"placeholder": ""
|
||||
},
|
||||
"disabled": {
|
||||
"label": "Desativado (sem conexão WireGuard e login possível)"
|
||||
},
|
||||
"locked": {
|
||||
"label": "Bloqueado (sem login possível, as conexões WireGuard ainda funcionam)"
|
||||
},
|
||||
"admin": {
|
||||
"label": "É Administrador"
|
||||
}
|
||||
}
|
||||
},
|
||||
"peers": {
|
||||
"title": "Peers",
|
||||
"create": "Criar Peer",
|
||||
"public-key": "Chave Pública",
|
||||
"preshared-key": "Chave Pré-partilhada",
|
||||
"endpoint": "Endpoint",
|
||||
"allowed-ips": "IPs Permitidos",
|
||||
"latest-handshake": "Último Handshake",
|
||||
"transfer-rx": "Recebido",
|
||||
"transfer-tx": "Enviado",
|
||||
"persistent-keepalive": "Keepalive Persistente",
|
||||
"actions": "Ações",
|
||||
"edit": "Editar",
|
||||
"delete-dialog": {
|
||||
"title": "Eliminar Peer",
|
||||
"text": "Tem a certeza de que deseja eliminar este peer?"
|
||||
},
|
||||
"form": {
|
||||
"interface-view": {
|
||||
"headline": "Configuração para a Interface:"
|
||||
},
|
||||
"interface-edit": {
|
||||
"headline-edit": "Editar Interface:",
|
||||
"headline-new": "Nova Interface",
|
||||
"tab-interface": "Interface",
|
||||
"tab-peerdef": "Padrões de Peer",
|
||||
"header-general": "Geral",
|
||||
"header-network": "Rede",
|
||||
"header-crypto": "Criptografia",
|
||||
"header-hooks": "Hooks da Interface",
|
||||
"header-peer-hooks": "Hooks",
|
||||
"header-state": "Estado",
|
||||
"identifier": {
|
||||
"label": "Identificador",
|
||||
"placeholder": "O identificador único da interface"
|
||||
},
|
||||
"mode": {
|
||||
"label": "Modo da Interface",
|
||||
"server": "Modo Servidor",
|
||||
"client": "Modo Cliente",
|
||||
"any": "Modo Desconhecido"
|
||||
},
|
||||
"display-name": {
|
||||
"label": "Nome de Exibição",
|
||||
"placeholder": "O nome descritivo para a interface"
|
||||
},
|
||||
"private-key": {
|
||||
"label": "Chave Privada",
|
||||
"placeholder": "A chave privada"
|
||||
},
|
||||
"public-key": {
|
||||
"label": "Chave Pública",
|
||||
"placeholder": "Introduza a chave pública do peer"
|
||||
"placeholder": "A chave pública"
|
||||
},
|
||||
"ip": {
|
||||
"label": "Endereços IP",
|
||||
"placeholder": "Endereços IP (formato CIDR)"
|
||||
},
|
||||
"listen-port": {
|
||||
"label": "Porta de Escuta",
|
||||
"placeholder": "A porta de escuta"
|
||||
},
|
||||
"dns": {
|
||||
"label": "Servidor DNS",
|
||||
"placeholder": "Os servidores DNS que devem ser usados"
|
||||
},
|
||||
"dns-search": {
|
||||
"label": "Domínios de Pesquisa DNS",
|
||||
"placeholder": "Prefixos de pesquisa DNS"
|
||||
},
|
||||
"mtu": {
|
||||
"label": "MTU",
|
||||
"placeholder": "O MTU da interface (0 = manter o valor padrão)"
|
||||
},
|
||||
"firewall-mark": {
|
||||
"label": "Marca de Firewall",
|
||||
"placeholder": "Marca de firewall aplicada ao tráfego de saída. (0 = automático)"
|
||||
},
|
||||
"routing-table": {
|
||||
"label": "Tabela de Roteamento",
|
||||
"placeholder": "O ID da tabela de roteamento",
|
||||
"description": "Casos especiais: off = não gerenciar rotas, 0 = automático"
|
||||
},
|
||||
"pre-up": {
|
||||
"label": "Pre-Up",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"post-up": {
|
||||
"label": "Post-Up",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"pre-down": {
|
||||
"label": "Pre-Down",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"post-down": {
|
||||
"label": "Post-Down",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"disabled": {
|
||||
"label": "Interface Desativada"
|
||||
},
|
||||
"save-config": {
|
||||
"label": "Guardar configuração wg-quick automaticamente"
|
||||
},
|
||||
"defaults": {
|
||||
"endpoint": {
|
||||
"label": "Endereço do Endpoint",
|
||||
"placeholder": "Endereço do Endpoint",
|
||||
"description": "O endereço do endpoint ao qual os peers se irão conectar. (ex. wg.exemplo.com ou wg.exemplo.com:51820)"
|
||||
},
|
||||
"networks": {
|
||||
"label": "Redes IP",
|
||||
"placeholder": "Endereços de Rede",
|
||||
"description": "Os peers irão obter endereços IP a partir dessas sub-redes."
|
||||
},
|
||||
"allowed-ip": {
|
||||
"label": "Endereços IP Permitidos",
|
||||
"placeholder": "Endereços IP Permitidos por padrão"
|
||||
},
|
||||
"mtu": {
|
||||
"label": "MTU",
|
||||
"placeholder": "O MTU do cliente (0 = manter o valor padrão)"
|
||||
},
|
||||
"keep-alive": {
|
||||
"label": "Intervalo de Keep Alive",
|
||||
"placeholder": "Keepalive persistente (0 = padrão)"
|
||||
}
|
||||
},
|
||||
"button-apply-defaults": "Aplicar Padrões de Peer"
|
||||
},
|
||||
"peer-view": {
|
||||
"headline-peer": "Peer:",
|
||||
"headline-endpoint": "Endpoint:",
|
||||
"section-info": "Informação do Peer",
|
||||
"section-status": "Estado Atual",
|
||||
"section-config": "Configuração",
|
||||
"identifier": "Identificador",
|
||||
"ip": "Endereços IP",
|
||||
"user": "Utilizador Associado",
|
||||
"notes": "Notas",
|
||||
"expiry-status": "Expira em",
|
||||
"disabled-status": "Desativado em",
|
||||
"traffic": "Tráfego",
|
||||
"connection-status": "Estatísticas de Conexão",
|
||||
"upload": "Bytes Enviados (do Servidor para o Peer)",
|
||||
"download": "Bytes Recebidos (do Peer para o Servidor)",
|
||||
"pingable": "É Pingável",
|
||||
"handshake": "Último Handshake",
|
||||
"connected-since": "Conectado desde",
|
||||
"endpoint": "Endpoint",
|
||||
"button-download": "Baixar configuração",
|
||||
"button-email": "Enviar configuração por E-Mail"
|
||||
},
|
||||
"peer-edit": {
|
||||
"headline-edit-peer": "Editar peer:",
|
||||
"headline-edit-endpoint": "Editar endpoint:",
|
||||
"headline-new-peer": "Criar peer",
|
||||
"headline-new-endpoint": "Criar endpoint",
|
||||
"header-general": "Geral",
|
||||
"header-network": "Rede",
|
||||
"header-crypto": "Criptografia",
|
||||
"header-hooks": "Hooks (Executados no Peer)",
|
||||
"header-state": "Estado",
|
||||
"display-name": {
|
||||
"label": "Nome de Exibição",
|
||||
"placeholder": "O nome descritivo para o peer"
|
||||
},
|
||||
"linked-user": {
|
||||
"label": "Utilizador Associado",
|
||||
"placeholder": "A conta de utilizador que possui este peer"
|
||||
},
|
||||
"private-key": {
|
||||
"label": "Chave Privada",
|
||||
"placeholder": "A chave privada",
|
||||
"help": "A chave privada é armazenada de forma segura no servidor. Se o utilizador já tiver uma cópia, pode omitir este campo. O servidor ainda funciona exclusivamente com a chave pública do peer."
|
||||
},
|
||||
"public-key": {
|
||||
"label": "Chave Pública",
|
||||
"placeholder": "A chave pública"
|
||||
},
|
||||
"preshared-key": {
|
||||
"label": "Chave Pré-partilhada",
|
||||
"placeholder": "Opcional: Chave partilhada adicional para maior segurança"
|
||||
"label": "Chave Pré-Partilhada",
|
||||
"placeholder": "Chave pré-partilhada opcional"
|
||||
},
|
||||
"endpoint-public-key": {
|
||||
"label": "Chave Pública do Endpoint",
|
||||
"placeholder": "A chave pública do endpoint remoto"
|
||||
},
|
||||
"endpoint": {
|
||||
"label": "Endpoint",
|
||||
"placeholder": "Endereço público do peer (ex: 1.2.3.4:51820)"
|
||||
"label": "Endereço do Endpoint",
|
||||
"placeholder": "O endereço do endpoint remoto"
|
||||
},
|
||||
"allowed-ips": {
|
||||
"label": "IPs Permitidos",
|
||||
"placeholder": "Lista de IPs (ex: 10.0.0.2/32, 192.168.1.0/24)"
|
||||
"ip": {
|
||||
"label": "Endereços IP",
|
||||
"placeholder": "Endereços IP (formato CIDR)"
|
||||
},
|
||||
"persistent-keepalive": {
|
||||
"label": "Keepalive Persistente",
|
||||
"placeholder": "Ex: 25 (em segundos)"
|
||||
"allowed-ip": {
|
||||
"label": "Endereços IP Permitidos",
|
||||
"placeholder": "Endereços IP permitidos"
|
||||
},
|
||||
"extra-allowed-ip": {
|
||||
"label": "Endereços IP adicionais permitidos",
|
||||
"placeholder": "IPs adicionais permitidos (lado do servidor)",
|
||||
"description": "Esses IPs serão adicionados à interface WireGuard remota como IPs permitidos."
|
||||
},
|
||||
"dns": {
|
||||
"label": "Servidor DNS",
|
||||
"placeholder": "Os servidores DNS que devem ser utilizados"
|
||||
},
|
||||
"dns-search": {
|
||||
"label": "Domínios de Pesquisa DNS",
|
||||
"placeholder": "Prefixos de pesquisa DNS"
|
||||
},
|
||||
"keep-alive": {
|
||||
"label": "Intervalo de Keep Alive",
|
||||
"placeholder": "Keepalive persistente (0 = padrão)"
|
||||
},
|
||||
"mtu": {
|
||||
"label": "MTU",
|
||||
"placeholder": "O MTU do cliente (0 = manter o padrão)"
|
||||
},
|
||||
"pre-up": {
|
||||
"label": "Pre-Up",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"post-up": {
|
||||
"label": "Post-Up",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"pre-down": {
|
||||
"label": "Pre-Down",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"post-down": {
|
||||
"label": "Post-Down",
|
||||
"placeholder": "Um ou vários comandos bash separados por ;"
|
||||
},
|
||||
"disabled": {
|
||||
"label": "Peer Desativado"
|
||||
},
|
||||
"ignore-global": {
|
||||
"label": "Ignorar definições globais"
|
||||
},
|
||||
"expires-at": {
|
||||
"label": "Data de expiração"
|
||||
}
|
||||
},
|
||||
"peer-multi-create": {
|
||||
"headline-peer": "Criar múltiplos peers",
|
||||
"headline-endpoint": "Criar múltiplos endpoints",
|
||||
"identifiers": {
|
||||
"label": "Identificadores de utilizador",
|
||||
"placeholder": "Identificadores de utilizador",
|
||||
"description": "Um identificador de utilizador (nome de utilizador) para o qual um peer deve ser criado."
|
||||
},
|
||||
"prefix": {
|
||||
"headline-peer": "Peer:",
|
||||
"headline-endpoint": "Endpoint:",
|
||||
"label": "Prefixo do nome exibido",
|
||||
"placeholder": "O prefixo",
|
||||
"description": "Um prefixo que será adicionado ao nome exibido do peer."
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Definições",
|
||||
"password": {
|
||||
"label": "Nova Palavra-passe",
|
||||
"placeholder": "Deixe em branco para manter a atual"
|
||||
},
|
||||
"save": "Guardar Alterações"
|
||||
},
|
||||
"audit": {
|
||||
"title": "Registo de Auditoria",
|
||||
"username": "Utilizador",
|
||||
"ip": "Endereço IP",
|
||||
"method": "Método",
|
||||
"path": "Caminho",
|
||||
"status": "Estado",
|
||||
"timestamp": "Data/Hora"
|
||||
},
|
||||
"errors": {
|
||||
"required": "Este campo é obrigatório",
|
||||
"invalid-email": "Endereço de email inválido",
|
||||
"invalid-address": "Endereço inválido",
|
||||
"invalid-endpoint": "Endpoint inválido",
|
||||
"invalid-allowed-ips": "Formato de IPs Permitidos inválido"
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ export const profileStore = defineStore('profile', {
|
||||
return apiWrapper.post(`${baseUrl}/${base64_url_encode(currentUser)}/api/enable`)
|
||||
.then(this.setUser)
|
||||
.catch(error => {
|
||||
this.setPeers([])
|
||||
this.fetching = false
|
||||
console.log("Failed to activate API for ", currentUser, ": ", error)
|
||||
notify({
|
||||
title: "Backend Connection Failure",
|
||||
@ -143,7 +143,7 @@ export const profileStore = defineStore('profile', {
|
||||
return apiWrapper.post(`${baseUrl}/${base64_url_encode(currentUser)}/api/disable`)
|
||||
.then(this.setUser)
|
||||
.catch(error => {
|
||||
this.setPeers([])
|
||||
this.fetching = false
|
||||
console.log("Failed to deactivate API for ", currentUser, ": ", error)
|
||||
notify({
|
||||
title: "Backend Connection Failure",
|
||||
|
15
go.mod
15
go.mod
@ -16,19 +16,19 @@ require (
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/swaggo/swag v1.16.4
|
||||
github.com/vardius/message-bus v1.1.5
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
github.com/vishvananda/netlink v1.3.1
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5
|
||||
github.com/yeqown/go-qrcode/writer/compressed v1.0.1
|
||||
golang.org/x/crypto v0.37.0
|
||||
golang.org/x/oauth2 v0.29.0
|
||||
golang.org/x/sys v0.32.0
|
||||
golang.org/x/crypto v0.38.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/sys v0.33.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/driver/postgres v1.5.11
|
||||
gorm.io/driver/sqlserver v1.5.4
|
||||
gorm.io/gorm v1.25.12
|
||||
gorm.io/gorm v1.26.1
|
||||
)
|
||||
|
||||
require (
|
||||
@ -62,7 +62,6 @@ require (
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
@ -82,8 +81,8 @@ require (
|
||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/tools v0.32.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
|
102
go.sum
102
go.sum
@ -44,24 +44,16 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
|
||||
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
|
||||
github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU=
|
||||
github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY=
|
||||
github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU=
|
||||
github.com/go-ldap/ldap/v3 v3.4.11/go.mod h1:bY7t0FLK8OAVpp/vV6sSlpz3EQDGcQwc8pF0ujLgKvM=
|
||||
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
|
||||
@ -83,8 +75,6 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI=
|
||||
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
|
||||
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
@ -98,12 +88,10 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2V
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@ -117,8 +105,6 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.3 h1:PO1wNKj/bTAwxSJnO1Z4Ai8j4magtqg2SLNjEDzcXQo=
|
||||
github.com/jackc/pgx/v5 v5.7.3/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
|
||||
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
@ -179,16 +165,10 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmd
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus-community/pro-bing v0.6.1 h1:EQukUOma9YFZRPe4DGSscxUf9LH07rpqwisNWjSZrgU=
|
||||
github.com/prometheus-community/pro-bing v0.6.1/go.mod h1:jNCOI3D7pmTCeaoF41cNS6uaxeFY/Gmc3ffwbuJVzAQ=
|
||||
github.com/prometheus-community/pro-bing v0.7.0 h1:KFYFbxC2f2Fp6c+TyxbCOEarf7rbnzr9Gw8eIb0RfZA=
|
||||
github.com/prometheus-community/pro-bing v0.7.0/go.mod h1:Moob9dvlY50Bfq6i88xIwfyw7xLFHH69LUgx9n5zqCE=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
||||
@ -218,9 +198,8 @@ github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817 h1:q0hKh5a5FRkhuTb5
|
||||
github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||
github.com/vardius/message-bus v1.1.5 h1:YSAC2WB4HRlwc4neFPTmT88kzzoiQ+9WRRbej/E/LZc=
|
||||
github.com/vardius/message-bus v1.1.5/go.mod h1:6xladCV2lMkUAE4bzzS85qKOiB5miV7aBVRafiTJGqw=
|
||||
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
|
||||
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
|
||||
@ -237,25 +216,16 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -268,28 +238,18 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -303,16 +263,11 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@ -320,13 +275,9 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
@ -337,18 +288,12 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
|
||||
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -356,8 +301,6 @@ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uI
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10/go.mod h1:T97yPqesLiNrOYxkwmhMI0ZIlJDm+p0PMR8eRVeR5tQ=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -378,35 +321,26 @@ gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g=
|
||||
gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
gorm.io/gorm v1.26.1 h1:ghB2gUI9FkS46luZtn6DLZ0f6ooBJ5IbVej2ENFDjRw=
|
||||
gorm.io/gorm v1.26.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
modernc.org/cc/v4 v4.26.0 h1:QMYvbVduUGH0rrO+5mqF/PSPPRZNpRtg2CLELy7vUpA=
|
||||
modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo=
|
||||
modernc.org/ccgo/v4 v4.23.16/go.mod h1:nNma8goMTY7aQZQNTyN9AIoJfxav4nvTnvKThAeMDdo=
|
||||
modernc.org/cc/v4 v4.26.0/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.26.0 h1:gVzXaDzGeBYJ2uXTOpR8FR7OlksDOe9jxnjhIKCsiTc=
|
||||
modernc.org/ccgo/v4 v4.26.0/go.mod h1:Sem8f7TFUtVXkG2fiaChQtyyfkqhJBg/zjEJBkmuAVY=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw=
|
||||
modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
|
||||
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/libc v1.63.0 h1:wKzb61wOGCzgahQBORb1b0dZonh8Ufzl/7r4Yf1D5YA=
|
||||
modernc.org/libc v1.63.0/go.mod h1:wDzH1mgz1wUIEwottFt++POjGRO9sgyQKrpXaz3x89E=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g=
|
||||
modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/memory v1.10.0 h1:fzumd51yQ1DxcOxSO+S6X7+QTuVU+n8/Aj7swYjFfC4=
|
||||
modernc.org/memory v1.10.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.36.1 h1:bDa8BJUH4lg6EGkLbahKe/8QqoF8p9gArSc6fTqYhyQ=
|
||||
modernc.org/sqlite v1.36.1/go.mod h1:7MPwH7Z6bREicF9ZVUR78P1IKuxfZ8mRIDHD0iD+8TU=
|
||||
modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI=
|
||||
modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
|
@ -118,6 +118,7 @@
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "This endpoint updates an existing interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
@ -250,6 +251,7 @@
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "This endpoint creates a new interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
@ -309,6 +311,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/interface/prepare": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "This endpoint returns a new interface with default values (fresh key pair, valid name, new IP address pool, ...).",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Interfaces"
|
||||
],
|
||||
"summary": "Prepare a new interface record.",
|
||||
"operationId": "interfaces_handlePrepareGet",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Interface"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/metrics/by-interface/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -547,7 +593,7 @@
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Only admins can update existing records.",
|
||||
"description": "Only admins can update existing records. The peer record must contain all required fields (e.g., public key, allowed IPs).",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
@ -779,7 +825,7 @@
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Only admins can create new records.",
|
||||
"description": "Only admins can create new records. The peer record must contain all required fields (e.g., public key, allowed IPs).",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
@ -839,6 +885,71 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/peer/prepare/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BasicAuth": []
|
||||
}
|
||||
],
|
||||
"description": "This endpoint is used to prepare a new peer record. The returned data contains a fresh key pair and valid ip address.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Peers"
|
||||
],
|
||||
"summary": "Prepare a new peer record for the given WireGuard interface.",
|
||||
"operationId": "peers_handlePrepareGet",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "The interface identifier.",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Peer"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/models.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/provisioning/data/peer-config": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -748,6 +748,8 @@ paths:
|
||||
tags:
|
||||
- Interfaces
|
||||
put:
|
||||
description: This endpoint updates an existing interface with the provided data.
|
||||
All required fields must be filled (e.g. name, private key, public key, ...).
|
||||
operationId: interfaces_handleUpdatePut
|
||||
parameters:
|
||||
- description: The interface identifier.
|
||||
@ -795,6 +797,8 @@ paths:
|
||||
- Interfaces
|
||||
/interface/new:
|
||||
post:
|
||||
description: This endpoint creates a new interface with the provided data. All
|
||||
required fields must be filled (e.g. name, private key, public key, ...).
|
||||
operationId: interfaces_handleCreatePost
|
||||
parameters:
|
||||
- description: The interface data.
|
||||
@ -835,6 +839,35 @@ paths:
|
||||
summary: Create a new interface record.
|
||||
tags:
|
||||
- Interfaces
|
||||
/interface/prepare:
|
||||
get:
|
||||
description: This endpoint returns a new interface with default values (fresh
|
||||
key pair, valid name, new IP address pool, ...).
|
||||
operationId: interfaces_handlePrepareGet
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.Interface'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
security:
|
||||
- BasicAuth: []
|
||||
summary: Prepare a new interface record.
|
||||
tags:
|
||||
- Interfaces
|
||||
/metrics/by-interface/{id}:
|
||||
get:
|
||||
operationId: metrics_handleMetricsForInterfaceGet
|
||||
@ -1024,7 +1057,8 @@ paths:
|
||||
tags:
|
||||
- Peers
|
||||
put:
|
||||
description: Only admins can update existing records.
|
||||
description: Only admins can update existing records. The peer record must contain
|
||||
all required fields (e.g., public key, allowed IPs).
|
||||
operationId: peers_handleUpdatePut
|
||||
parameters:
|
||||
- description: The peer identifier.
|
||||
@ -1136,7 +1170,8 @@ paths:
|
||||
- Peers
|
||||
/peer/new:
|
||||
post:
|
||||
description: Only admins can create new records.
|
||||
description: Only admins can create new records. The peer record must contain
|
||||
all required fields (e.g., public key, allowed IPs).
|
||||
operationId: peers_handleCreatePost
|
||||
parameters:
|
||||
- description: The peer data.
|
||||
@ -1177,6 +1212,49 @@ paths:
|
||||
summary: Create a new peer record.
|
||||
tags:
|
||||
- Peers
|
||||
/peer/prepare/{id}:
|
||||
get:
|
||||
description: This endpoint is used to prepare a new peer record. The returned
|
||||
data contains a fresh key pair and valid ip address.
|
||||
operationId: peers_handlePrepareGet
|
||||
parameters:
|
||||
- description: The interface identifier.
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/models.Peer'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/models.Error'
|
||||
security:
|
||||
- BasicAuth: []
|
||||
summary: Prepare a new peer record for the given WireGuard interface.
|
||||
tags:
|
||||
- Peers
|
||||
/provisioning/data/peer-config:
|
||||
get:
|
||||
description: Normal users can only access their own record. Admins can access
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
type InterfaceServiceInterfaceManagerRepo interface {
|
||||
GetAllInterfacesAndPeers(ctx context.Context) ([]domain.Interface, [][]domain.Peer, error)
|
||||
GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Interface, []domain.Peer, error)
|
||||
PrepareInterface(ctx context.Context) (*domain.Interface, error)
|
||||
CreateInterface(ctx context.Context, in *domain.Interface) (*domain.Interface, error)
|
||||
UpdateInterface(ctx context.Context, in *domain.Interface) (*domain.Interface, []domain.Peer, error)
|
||||
DeleteInterface(ctx context.Context, id domain.InterfaceIdentifier) error
|
||||
@ -60,6 +61,19 @@ func (s InterfaceService) GetById(ctx context.Context, id domain.InterfaceIdenti
|
||||
return interfaceData, interfacePeers, nil
|
||||
}
|
||||
|
||||
func (s InterfaceService) Prepare(ctx context.Context) (*domain.Interface, error) {
|
||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
interfaceData, err := s.interfaces.PrepareInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return interfaceData, nil
|
||||
}
|
||||
|
||||
func (s InterfaceService) Create(ctx context.Context, iface *domain.Interface) (*domain.Interface, error) {
|
||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||
return nil, err
|
||||
|
@ -13,6 +13,7 @@ type PeerServicePeerManagerRepo interface {
|
||||
GetPeer(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error)
|
||||
GetUserPeers(ctx context.Context, id domain.UserIdentifier) ([]domain.Peer, error)
|
||||
GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Interface, []domain.Peer, error)
|
||||
PreparePeer(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error)
|
||||
CreatePeer(ctx context.Context, peer *domain.Peer) (*domain.Peer, error)
|
||||
UpdatePeer(ctx context.Context, peer *domain.Peer) (*domain.Peer, error)
|
||||
DeletePeer(ctx context.Context, id domain.PeerIdentifier) error
|
||||
@ -95,6 +96,19 @@ func (s PeerService) GetById(ctx context.Context, id domain.PeerIdentifier) (*do
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
func (s PeerService) Prepare(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error) {
|
||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer, err := s.peers.PreparePeer(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
func (s PeerService) Create(ctx context.Context, peer *domain.Peer) (*domain.Peer, error) {
|
||||
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||
return nil, err
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
type InterfaceEndpointInterfaceService interface {
|
||||
GetAll(context.Context) ([]domain.Interface, [][]domain.Peer, error)
|
||||
GetById(context.Context, domain.InterfaceIdentifier) (*domain.Interface, []domain.Peer, error)
|
||||
Prepare(context.Context) (*domain.Interface, error)
|
||||
Create(context.Context, *domain.Interface) (*domain.Interface, error)
|
||||
Update(context.Context, domain.InterfaceIdentifier, *domain.Interface) (*domain.Interface, []domain.Peer, error)
|
||||
Delete(context.Context, domain.InterfaceIdentifier) error
|
||||
@ -49,6 +50,7 @@ func (e InterfaceEndpoint) RegisterRoutes(g *routegroup.Bundle) {
|
||||
apiGroup.HandleFunc("GET /all", e.handleAllGet())
|
||||
apiGroup.HandleFunc("GET /by-id/{id}", e.handleByIdGet())
|
||||
|
||||
apiGroup.HandleFunc("GET /prepare", e.handlePrepareGet())
|
||||
apiGroup.HandleFunc("POST /new", e.handleCreatePost())
|
||||
apiGroup.HandleFunc("PUT /by-id/{id}", e.handleUpdatePut())
|
||||
apiGroup.HandleFunc("DELETE /by-id/{id}", e.handleDelete())
|
||||
@ -112,11 +114,38 @@ func (e InterfaceEndpoint) handleByIdGet() http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// handlePrepareGet returns a gorm handler function.
|
||||
//
|
||||
// @ID interfaces_handlePrepareGet
|
||||
// @Tags Interfaces
|
||||
// @Summary Prepare a new interface record.
|
||||
// @Description This endpoint returns a new interface with default values (fresh key pair, valid name, new IP address pool, ...).
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.Interface
|
||||
// @Failure 401 {object} models.Error
|
||||
// @Failure 403 {object} models.Error
|
||||
// @Failure 500 {object} models.Error
|
||||
// @Router /interface/prepare [get]
|
||||
// @Security BasicAuth
|
||||
func (e InterfaceEndpoint) handlePrepareGet() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
iface, err := e.interfaces.Prepare(r.Context())
|
||||
if err != nil {
|
||||
status, model := ParseServiceError(err)
|
||||
respond.JSON(w, status, model)
|
||||
return
|
||||
}
|
||||
|
||||
respond.JSON(w, http.StatusOK, models.NewInterface(iface, nil))
|
||||
}
|
||||
}
|
||||
|
||||
// handleCreatePost returns a gorm handler function.
|
||||
//
|
||||
// @ID interfaces_handleCreatePost
|
||||
// @Tags Interfaces
|
||||
// @Summary Create a new interface record.
|
||||
// @Description This endpoint creates a new interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).
|
||||
// @Param request body models.Interface true "The interface data."
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.Interface
|
||||
@ -155,6 +184,7 @@ func (e InterfaceEndpoint) handleCreatePost() http.HandlerFunc {
|
||||
// @ID interfaces_handleUpdatePut
|
||||
// @Tags Interfaces
|
||||
// @Summary Update an interface record.
|
||||
// @Description This endpoint updates an existing interface with the provided data. All required fields must be filled (e.g. name, private key, public key, ...).
|
||||
// @Param id path string true "The interface identifier."
|
||||
// @Param request body models.Interface true "The interface data."
|
||||
// @Produce json
|
||||
|
@ -16,6 +16,7 @@ type PeerService interface {
|
||||
GetForInterface(context.Context, domain.InterfaceIdentifier) ([]domain.Peer, error)
|
||||
GetForUser(context.Context, domain.UserIdentifier) ([]domain.Peer, error)
|
||||
GetById(context.Context, domain.PeerIdentifier) (*domain.Peer, error)
|
||||
Prepare(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error)
|
||||
Create(context.Context, *domain.Peer) (*domain.Peer, error)
|
||||
Update(context.Context, domain.PeerIdentifier, *domain.Peer) (*domain.Peer, error)
|
||||
Delete(context.Context, domain.PeerIdentifier) error
|
||||
@ -51,6 +52,7 @@ func (e PeerEndpoint) RegisterRoutes(g *routegroup.Bundle) {
|
||||
apiGroup.HandleFunc("GET /by-user/{id}", e.handleAllForUserGet())
|
||||
apiGroup.HandleFunc("GET /by-id/{id}", e.handleByIdGet())
|
||||
|
||||
apiGroup.With(e.authenticator.LoggedIn(ScopeAdmin)).HandleFunc("GET /prepare/{id}", e.handlePrepareGet())
|
||||
apiGroup.With(e.authenticator.LoggedIn(ScopeAdmin)).HandleFunc("POST /new", e.handleCreatePost())
|
||||
apiGroup.With(e.authenticator.LoggedIn(ScopeAdmin)).HandleFunc("PUT /by-id/{id}", e.handleUpdatePut())
|
||||
apiGroup.With(e.authenticator.LoggedIn(ScopeAdmin)).HandleFunc("DELETE /by-id/{id}", e.handleDelete())
|
||||
@ -156,12 +158,48 @@ func (e PeerEndpoint) handleByIdGet() http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// handlePrepareGet returns a gorm handler function.
|
||||
//
|
||||
// @ID peers_handlePrepareGet
|
||||
// @Tags Peers
|
||||
// @Summary Prepare a new peer record for the given WireGuard interface.
|
||||
// @Description This endpoint is used to prepare a new peer record. The returned data contains a fresh key pair and valid ip address.
|
||||
// @Param id path string true "The interface identifier."
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.Peer
|
||||
// @Failure 400 {object} models.Error
|
||||
// @Failure 401 {object} models.Error
|
||||
// @Failure 403 {object} models.Error
|
||||
// @Failure 404 {object} models.Error
|
||||
// @Failure 500 {object} models.Error
|
||||
// @Router /peer/prepare/{id} [get]
|
||||
// @Security BasicAuth
|
||||
func (e PeerEndpoint) handlePrepareGet() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := request.Path(r, "id")
|
||||
if id == "" {
|
||||
respond.JSON(w, http.StatusBadRequest,
|
||||
models.Error{Code: http.StatusBadRequest, Message: "missing interface id"})
|
||||
return
|
||||
}
|
||||
|
||||
peer, err := e.peers.Prepare(r.Context(), domain.InterfaceIdentifier(id))
|
||||
if err != nil {
|
||||
status, model := ParseServiceError(err)
|
||||
respond.JSON(w, status, model)
|
||||
return
|
||||
}
|
||||
|
||||
respond.JSON(w, http.StatusOK, models.NewPeer(peer))
|
||||
}
|
||||
}
|
||||
|
||||
// handleCreatePost returns a gorm handler function.
|
||||
//
|
||||
// @ID peers_handleCreatePost
|
||||
// @Tags Peers
|
||||
// @Summary Create a new peer record.
|
||||
// @Description Only admins can create new records.
|
||||
// @Description Only admins can create new records. The peer record must contain all required fields (e.g., public key, allowed IPs).
|
||||
// @Param request body models.Peer true "The peer data."
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.Peer
|
||||
@ -200,7 +238,7 @@ func (e PeerEndpoint) handleCreatePost() http.HandlerFunc {
|
||||
// @ID peers_handleUpdatePut
|
||||
// @Tags Peers
|
||||
// @Summary Update a peer record.
|
||||
// @Description Only admins can update existing records.
|
||||
// @Description Only admins can update existing records. The peer record must contain all required fields (e.g., public key, allowed IPs).
|
||||
// @Param id path string true "The peer identifier."
|
||||
// @Param request body models.Peer true "The peer data."
|
||||
// @Produce json
|
||||
|
@ -63,6 +63,8 @@ type AuthenticatorOauth interface {
|
||||
ParseUserInfo(raw map[string]any) (*domain.AuthenticatorUserInfo, error)
|
||||
// RegistrationEnabled returns whether registration is enabled for the OAuth authenticator.
|
||||
RegistrationEnabled() bool
|
||||
// GetAllowedDomains returns the list of whitelisted domains
|
||||
GetAllowedDomains() []string
|
||||
}
|
||||
|
||||
// AuthenticatorLdap is the interface for all LDAP authenticators.
|
||||
@ -392,6 +394,23 @@ func (a *Authenticator) randString(nByte int) (string, error) {
|
||||
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
func isDomainAllowed(email string, allowedDomains []string) bool {
|
||||
if len(allowedDomains) == 0 {
|
||||
return true
|
||||
}
|
||||
parts := strings.Split(email, "@")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
domain := strings.ToLower(parts[1])
|
||||
for _, allowed := range allowedDomains {
|
||||
if domain == strings.ToLower(allowed) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// OauthLoginStep2 finishes the oauth authentication flow by exchanging the code for an access token and
|
||||
// fetching the user information.
|
||||
func (a *Authenticator) OauthLoginStep2(ctx context.Context, providerId, nonce, code string) (*domain.User, error) {
|
||||
@ -431,6 +450,10 @@ func (a *Authenticator) OauthLoginStep2(ctx context.Context, providerId, nonce,
|
||||
return nil, fmt.Errorf("unable to process user information: %w", err)
|
||||
}
|
||||
|
||||
if !isDomainAllowed(userInfo.Email, oauthProvider.GetAllowedDomains()) {
|
||||
return nil, fmt.Errorf("user is not in allowed domains: %w", err)
|
||||
}
|
||||
|
||||
if user.IsLocked() || user.IsDisabled() {
|
||||
a.bus.Publish(app.TopicAuditLoginFailed, domain.AuditEventWrapper[audit.AuthEvent]{
|
||||
Ctx: ctx,
|
||||
|
@ -27,6 +27,7 @@ type PlainOauthAuthenticator struct {
|
||||
userAdminMapping *config.OauthAdminMapping
|
||||
registrationEnabled bool
|
||||
userInfoLogging bool
|
||||
allowedDomains []string
|
||||
}
|
||||
|
||||
func newPlainOauthAuthenticator(
|
||||
@ -56,6 +57,7 @@ func newPlainOauthAuthenticator(
|
||||
provider.userAdminMapping = &cfg.AdminMapping
|
||||
provider.registrationEnabled = cfg.RegistrationEnabled
|
||||
provider.userInfoLogging = cfg.LogUserInfo
|
||||
provider.allowedDomains = cfg.AllowedDomains
|
||||
|
||||
return provider, nil
|
||||
}
|
||||
@ -65,6 +67,10 @@ func (p PlainOauthAuthenticator) GetName() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p PlainOauthAuthenticator) GetAllowedDomains() []string {
|
||||
return p.allowedDomains
|
||||
}
|
||||
|
||||
// RegistrationEnabled returns whether registration is enabled for the OAuth authenticator.
|
||||
func (p PlainOauthAuthenticator) RegistrationEnabled() bool {
|
||||
return p.registrationEnabled
|
||||
|
@ -24,6 +24,7 @@ type OidcAuthenticator struct {
|
||||
userAdminMapping *config.OauthAdminMapping
|
||||
registrationEnabled bool
|
||||
userInfoLogging bool
|
||||
allowedDomains []string
|
||||
}
|
||||
|
||||
func newOidcAuthenticator(
|
||||
@ -57,6 +58,7 @@ func newOidcAuthenticator(
|
||||
provider.userAdminMapping = &cfg.AdminMapping
|
||||
provider.registrationEnabled = cfg.RegistrationEnabled
|
||||
provider.userInfoLogging = cfg.LogUserInfo
|
||||
provider.allowedDomains = cfg.AllowedDomains
|
||||
|
||||
return provider, nil
|
||||
}
|
||||
@ -66,6 +68,10 @@ func (o OidcAuthenticator) GetName() string {
|
||||
return o.name
|
||||
}
|
||||
|
||||
func (o OidcAuthenticator) GetAllowedDomains() []string {
|
||||
return o.allowedDomains
|
||||
}
|
||||
|
||||
// RegistrationEnabled returns whether registration is enabled for this authenticator.
|
||||
func (o OidcAuthenticator) RegistrationEnabled() bool {
|
||||
return o.registrationEnabled
|
||||
|
@ -188,6 +188,9 @@ type OpenIDConnectProvider struct {
|
||||
// ExtraScopes specifies optional requested permissions.
|
||||
ExtraScopes []string `yaml:"extra_scopes"`
|
||||
|
||||
// AllowedDomains defines the list of allowed domains
|
||||
AllowedDomains []string `yaml:"allowed_domains"`
|
||||
|
||||
// FieldMap is used to map the names of the user-info endpoint fields to wg-portal fields
|
||||
FieldMap OauthFields `yaml:"field_map"`
|
||||
|
||||
@ -226,6 +229,9 @@ type OAuthProvider struct {
|
||||
// Scope specifies optional requested permissions.
|
||||
Scopes []string `yaml:"scopes"`
|
||||
|
||||
// AllowedDomains defines the list of allowed domains
|
||||
AllowedDomains []string `yaml:"allowed_domains"`
|
||||
|
||||
// FieldMap is used to map the names of the user-info endpoint fields to wg-portal fields
|
||||
FieldMap OauthFields `yaml:"field_map"`
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user