mirror of
https://github.com/WGDashboard/WGDashboard.git
synced 2026-08-04 15:03:02 +00:00
Compare commits
119 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56ac97b15c | |||
| 21570cb27f | |||
| 0cf3ec2965 | |||
| 3c493be351 | |||
| 1128c332ae | |||
| 65645d6775 | |||
| 46d15959b1 | |||
| 8e9ab60ce7 | |||
| ca8f47b73e | |||
| c098aea151 | |||
| 68be16bf81 | |||
| 9d88a602cd | |||
| 9e8ca0e630 | |||
| 0343e8f915 | |||
| 2a5043424e | |||
| 7df99a12d0 | |||
| 59c88853de | |||
| 6574b216fb | |||
| 6da668616b | |||
| 9a1ac86ee6 | |||
| dae13faf25 | |||
| cdd7901b7d | |||
| be2ac265bb | |||
| 3cdeb4c5b5 | |||
| 4d15555e7d | |||
| 769f96fdc7 | |||
| 4f99096d80 | |||
| 3bc88a3006 | |||
| 9982841993 | |||
| 4bff8e1d4d | |||
| d837012d86 | |||
| 96dd08e6c7 | |||
| b524fcd88b | |||
| 1658b73724 | |||
| 1f28539bff | |||
| e9fb32d9a8 | |||
| bd91b3c97a | |||
| dfcd80de5b | |||
| 85cbf498c0 | |||
| ee6586e50d | |||
| 4c59f81c85 | |||
| 1db476e1b9 | |||
| 7cb845a65d | |||
| 3da0039004 | |||
| 3d966b928f | |||
| 58fa826862 | |||
| 2be7e08b7c | |||
| aa8bfe179a | |||
| 8207c1209c | |||
| 20a6cfdec3 | |||
| 71077880ad | |||
| d51889a222 | |||
| ece7cd1896 | |||
| 4d20d00631 | |||
| 6ec8d2f201 | |||
| 195ef37928 | |||
| b16f0aa3c2 | |||
| dc26b13ea6 | |||
| b66a619e81 | |||
| dd93cbcb42 | |||
| a5be721f39 | |||
| 40c0a91afa | |||
| 35e1a3af25 | |||
| 91de807557 | |||
| 9d5478e3e3 | |||
| b07be518fb | |||
| 35be7ca3db | |||
| 36521a7d70 | |||
| 3520087dce | |||
| d354e8ad38 | |||
| 4be7cd4073 | |||
| b04be970e6 | |||
| de81384f88 | |||
| 071a4765b9 | |||
| fbaa15cb8d | |||
| c9abfa5f61 | |||
| d3d7c7e678 | |||
| 930c4169c5 | |||
| 90614a6360 | |||
| ef8459415b | |||
| 365f07da0b | |||
| 8d00cca321 | |||
| 1fffa33dd5 | |||
| ff34e4f8c8 | |||
| af385a4537 | |||
| e2ff34ce1d | |||
| 2ac9fea881 | |||
| 9e59ad0ebc | |||
| 18c2568c22 | |||
| d58e082336 | |||
| fedf7db8a4 | |||
| 523fee7b42 | |||
| 624206d5a7 | |||
| fa9d9f24b5 | |||
| c42bc47761 | |||
| 24e0f514d7 | |||
| 1744570086 | |||
| 9669782b0c | |||
| 03eddd2846 | |||
| 26b82745fc | |||
| abc82369d9 | |||
| f1764d3822 | |||
| 8fd15b9ca6 | |||
| 5f62e9ac69 | |||
| 8eb7e97d6e | |||
| 3b03099700 | |||
| 8d6eb4bb41 | |||
| 387adfee8c | |||
| a33d6bfc9a | |||
| 5726627058 | |||
| 14b5885814 | |||
| 3d8cdcaf84 | |||
| f1448b0e52 | |||
| 6e92b2b6a2 | |||
| 18ee8822d9 | |||
| 326628d258 | |||
| 566dda93f3 | |||
| 5c28e639ae | |||
| 3dfe740780 |
+1
-1
@@ -30,7 +30,7 @@ RUN go version && \
|
||||
# AWG TOOLS BUILDING STAGE
|
||||
# Base: Alpine
|
||||
#
|
||||
FROM alpine:3.23 AS awg-tools
|
||||
FROM alpine:3.24 AS awg-tools
|
||||
|
||||
# Install needed dependencies.
|
||||
RUN apk add --no-cache \
|
||||
|
||||
+70
-1
@@ -105,7 +105,7 @@ Updating the WGDashboard container should be through 'The Docker Way' - by pulli
|
||||
| `username` | Any non‐empty string | `-` | `admin` | Username for the WGDashboard web interface account. |
|
||||
| `password` | Any non‐empty string | `-` | `s3cr3tP@ss` | Password for the WGDashboard web interface account (stored hashed). |
|
||||
| `enable_totp` | `true`, `false` | `true` | `false` | Enable TOTP‐based two‐factor authentication for the account. |
|
||||
| `wg_autostart` | Wireguard interface name | `false` | `true` | Auto‐start the WireGuard client when the container launches. |
|
||||
| `wg_autostart` | Wireguard interface name | `- ` | `wg0` | Automatically start the specified WireGuard interface when the container starts |
|
||||
| `email_server` | SMTP server address | `-` | `smtp.gmail.com` | SMTP server for sending email notifications. |
|
||||
| `email_port` | SMTP port number | `-` | `587` | Port for connecting to the SMTP server. |
|
||||
| `email_encryption` | `TLS`, `SSL`, etc. | `-` | `TLS` | Encryption method for email communication. |
|
||||
@@ -213,6 +213,75 @@ ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||
- Access the web interface via `http://your-ip:10086` (or whichever port you specified in the compose).
|
||||
- The first time run will auto-generate WireGuard keys and configs (configs are generated from the template).
|
||||
|
||||
## 🧑💻 Local Development with Docker
|
||||
|
||||
You can develop against WGDashboard locally by mounting the `src/` directory into the container. This lets you edit Python and frontend code on your host and see changes reflected immediately (with a service restart for Python).
|
||||
|
||||
Create a `docker/compose-local.yaml` alongside the existing `compose.yaml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
wgdashboard:
|
||||
image: ghcr.io/wgdashboard/wgdashboard:latest
|
||||
restart: unless-stopped
|
||||
container_name: wgdashboard
|
||||
|
||||
ports:
|
||||
- 10086:10086/tcp
|
||||
- 51820:51820/udp
|
||||
|
||||
volumes:
|
||||
- aconf:/etc/amnezia/amneziawg
|
||||
- conf:/etc/wireguard
|
||||
- data:/data
|
||||
# Mount local src for live editing
|
||||
- ../src:/opt/wgdashboard/src
|
||||
# Keep venv in a named volume so it isn't overwritten by the mount
|
||||
- venv:/opt/wgdashboard/src/venv
|
||||
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
|
||||
volumes:
|
||||
aconf:
|
||||
conf:
|
||||
data:
|
||||
venv:
|
||||
```
|
||||
|
||||
The key additions compared to the production compose file:
|
||||
- `../src:/opt/wgdashboard/src` — mounts your local `src/` directory into the container so code changes are reflected without rebuilding the image.
|
||||
- `venv:/opt/wgdashboard/src/venv` — keeps the Python virtual environment in a named Docker volume. Without this, the host mount would overwrite the venv created during image build.
|
||||
|
||||
To start the development container:
|
||||
|
||||
```bash
|
||||
cd docker
|
||||
docker compose -f compose-local.yaml up -d
|
||||
```
|
||||
|
||||
After editing Python files (e.g. `src/dashboard.py`), restart the container to pick up changes:
|
||||
|
||||
```bash
|
||||
docker restart wgdashboard
|
||||
```
|
||||
|
||||
For frontend changes, install dependencies and rebuild the Vue app on your host:
|
||||
|
||||
```bash
|
||||
cd src/static/app
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Then restart the container so it serves the updated dist files:
|
||||
|
||||
```bash
|
||||
docker restart wgdashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Closing remarks:
|
||||
|
||||
For feedback please submit an issue to the repository. Or message dselen@nerthus.nl.
|
||||
|
||||
+2
-2
@@ -100,7 +100,7 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
|
||||
date = datetime.datetime.now(tz=datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
emailSender = EmailSender(dashboardConfig)
|
||||
if not emailSender.ready():
|
||||
if not emailSender.is_ready():
|
||||
return ResponseObject(False, "We can't send you an email due to your Administrator has not setup email service. Please contact your administrator.")
|
||||
|
||||
data = request.get_json()
|
||||
@@ -244,4 +244,4 @@ def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration],
|
||||
|
||||
return ResponseObject(status, message)
|
||||
|
||||
return client
|
||||
return client
|
||||
|
||||
+140
-47
@@ -2,13 +2,15 @@ import logging
|
||||
import random, shutil, sqlite3, configparser, hashlib, ipaddress, json, os, secrets, subprocess
|
||||
import time, re, uuid, bcrypt, psutil, pyotp, threading
|
||||
import traceback
|
||||
from functools import wraps
|
||||
from urllib.parse import unquote
|
||||
from uuid import uuid4
|
||||
from zipfile import ZipFile
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import sqlalchemy
|
||||
from jinja2 import Template
|
||||
from flask import Flask, request, render_template, session, send_file, current_app
|
||||
from flask import Flask, request, render_template, session, send_file, current_app, redirect, url_for
|
||||
from flask_cors import CORS
|
||||
from icmplib import ping, traceroute
|
||||
from flask.json.provider import DefaultJSONProvider
|
||||
@@ -30,6 +32,7 @@ from modules.PeerJobs import PeerJobs
|
||||
from modules.DashboardConfig import DashboardConfig
|
||||
from modules.WireguardConfiguration import WireguardConfiguration
|
||||
from modules.AmneziaConfiguration import AmneziaConfiguration
|
||||
from modules.DashboardOIDC import DashboardOIDC
|
||||
|
||||
from client import createClientBlueprint
|
||||
|
||||
@@ -68,6 +71,21 @@ def ResponseObject(status=True, message=None, data=None, status_code = 200) -> F
|
||||
response.content_type = "application/json"
|
||||
return response
|
||||
|
||||
def require_fields(*fields):
|
||||
"""Decorator that validates required fields in request.json."""
|
||||
def decorator(f):
|
||||
@wraps(f)
|
||||
def decorated(*args, **kwargs):
|
||||
data = request.json
|
||||
if data is None:
|
||||
return ResponseObject(False, "Request body must be JSON", status_code=400)
|
||||
missing = [field for field in fields if field not in data]
|
||||
if missing:
|
||||
return ResponseObject(False, f"Missing required fields: {', '.join(missing)}", status_code=400)
|
||||
return f(*args, **kwargs)
|
||||
return decorated
|
||||
return decorator
|
||||
|
||||
'''
|
||||
Flask App
|
||||
'''
|
||||
@@ -208,6 +226,7 @@ with app.app_context():
|
||||
NewConfigurationTemplates: NewConfigurationTemplates = NewConfigurationTemplates()
|
||||
InitWireguardConfigurationsList(startup=True)
|
||||
DashboardClients: DashboardClients = DashboardClients(WireguardConfigurations)
|
||||
AdminOIDC = DashboardOIDC("Admin")
|
||||
app.register_blueprint(createClientBlueprint(WireguardConfigurations, DashboardConfig, DashboardClients))
|
||||
|
||||
_, APP_PREFIX = DashboardConfig.GetConfig("Server", "app_prefix")
|
||||
@@ -262,6 +281,8 @@ def auth_req():
|
||||
f'{appPrefix}/api/sharePeer/get',
|
||||
f'{appPrefix}/api/isTotpEnabled',
|
||||
f'{appPrefix}/api/locale',
|
||||
f'{appPrefix}/api/oidc/providers',
|
||||
f'{appPrefix}/api/oidc/authenticate',
|
||||
]
|
||||
|
||||
|
||||
@@ -299,6 +320,38 @@ def API_ValidateAuthentication():
|
||||
def API_RequireAuthentication():
|
||||
return ResponseObject(data=DashboardConfig.GetConfig("Server", "auth_req")[1])
|
||||
|
||||
# OIDC for Admin
|
||||
@app.get(f'{APP_PREFIX}/api/oidc/providers')
|
||||
def API_OIDC_GetProviders():
|
||||
_, oidc = DashboardConfig.GetConfig("OIDC", "admin_enable")
|
||||
if not oidc:
|
||||
return ResponseObject(status=False, message="OIDC is disabled")
|
||||
|
||||
return ResponseObject(data=AdminOIDC.GetProviders())
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/oidc/authenticate')
|
||||
def API_OIDC_Authenticate():
|
||||
_, oidc = DashboardConfig.GetConfig("OIDC", "admin_enable")
|
||||
if not oidc:
|
||||
return ResponseObject(False, "OIDC is disabled")
|
||||
|
||||
requestData = request.get_json()
|
||||
status, data = AdminOIDC.VerifyToken(**requestData)
|
||||
if not status:
|
||||
return ResponseObject(False, "OIDC Authentication Failed. Reason: " + data)
|
||||
session['role'] = 'admin'
|
||||
authToken = hashlib.sha256(f'${data['sid']}{datetime.now()}{app.secret_key}'.encode()).hexdigest()
|
||||
session['username'] = authToken
|
||||
session['signInMethod'] = 'OIDC'
|
||||
session['signInPayload'] = {
|
||||
"Provider": requestData.get('provider'),
|
||||
"Payload": data
|
||||
}
|
||||
resp = ResponseObject()
|
||||
resp.set_cookie('authToken', authToken)
|
||||
return resp
|
||||
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/authenticate')
|
||||
def API_AuthenticateLogin():
|
||||
data = request.get_json()
|
||||
@@ -318,7 +371,10 @@ def API_AuthenticateLogin():
|
||||
totpEnabled = DashboardConfig.GetConfig("Account", "enable_totp")[1]
|
||||
totpValid = False
|
||||
if totpEnabled:
|
||||
totpValid = pyotp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).now() == data['totp']
|
||||
totp_code = str(data.get("totp", "")).strip()
|
||||
totpValid = pyotp.TOTP(
|
||||
DashboardConfig.GetConfig("Account", "totp_key")[1]
|
||||
).verify(totp_code, valid_window=1)
|
||||
|
||||
if (valid
|
||||
and data['username'] == DashboardConfig.GetConfig("Account", "username")[1]
|
||||
@@ -327,6 +383,7 @@ def API_AuthenticateLogin():
|
||||
authToken = hashlib.sha256(f"{data['username']}{datetime.now()}".encode()).hexdigest()
|
||||
session['role'] = 'admin'
|
||||
session['username'] = authToken
|
||||
session['signInMethod'] = 'local'
|
||||
resp = ResponseObject(True, DashboardConfig.GetConfig("Other", "welcome_session")[1])
|
||||
resp.set_cookie("authToken", authToken)
|
||||
session.permanent = True
|
||||
@@ -342,6 +399,14 @@ def API_AuthenticateLogin():
|
||||
def API_SignOut():
|
||||
resp = ResponseObject(True, "")
|
||||
resp.delete_cookie("authToken")
|
||||
if session.get('signInMethod') == "OIDC":
|
||||
status, oidc_config = AdminOIDC.GetProviderConfiguration(session.get('signInPayload').get("Provider"))
|
||||
signOut = requests.get(
|
||||
oidc_config.get("end_session_endpoint"),
|
||||
params={
|
||||
'id_token_hint': session.get('signInPayload').get("Payload").get('sid')
|
||||
}
|
||||
)
|
||||
session.clear()
|
||||
return resp
|
||||
|
||||
@@ -1204,52 +1269,75 @@ def API_getDashboardTheme():
|
||||
def API_getDashboardVersion():
|
||||
return ResponseObject(data=DashboardConfig.GetConfig("Server", "version")[1])
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/savePeerScheduleJob')
|
||||
@app.post(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('Configuration', 'Peer', 'Field', 'Operator', 'Value', 'Action')
|
||||
def API_savePeerScheduleJob():
|
||||
data = request.json
|
||||
if "Job" not in data.keys():
|
||||
return ResponseObject(False, "Please specify job")
|
||||
job: dict = data['Job']
|
||||
if "Peer" not in job.keys() or "Configuration" not in job.keys():
|
||||
return ResponseObject(False, "Please specify peer and configuration")
|
||||
configuration = WireguardConfigurations.get(job['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
f, fp = configuration.searchPeer(job['Peer'])
|
||||
if not f:
|
||||
return ResponseObject(False, "Peer does not exist")
|
||||
|
||||
|
||||
s, p = AllPeerJobs.saveJob(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
if s:
|
||||
return ResponseObject(s, data=p)
|
||||
return ResponseObject(s, message=p)
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/deletePeerScheduleJob')
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
peerKey = unquote(data['Peer'])
|
||||
found, _ = configuration.searchPeer(peerKey)
|
||||
if not found:
|
||||
return ResponseObject(False, "Peer does not exist", status_code=404)
|
||||
|
||||
jobID = data.get('JobID', str(uuid4()))
|
||||
if len(AllPeerJobs.searchJobById(jobID)) > 0:
|
||||
return ResponseObject(False, "Job already exists", status_code=409)
|
||||
|
||||
success, result = AllPeerJobs.saveJob(PeerJob(
|
||||
jobID, data['Configuration'], peerKey, data['Field'], data['Operator'], data['Value'],
|
||||
datetime.now(), data.get('ExpireDate'), data['Action']))
|
||||
if success:
|
||||
return ResponseObject(success, data=result)
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.put(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('JobID', 'Configuration', 'Peer', 'Field', 'Operator', 'Value', 'Action')
|
||||
def API_updatePeerScheduleJob():
|
||||
data = request.json
|
||||
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
peerKey = unquote(data['Peer'])
|
||||
found, _ = configuration.searchPeer(peerKey)
|
||||
if not found:
|
||||
return ResponseObject(False, "Peer does not exist", status_code=404)
|
||||
|
||||
existing = AllPeerJobs.searchJobById(data['JobID'])
|
||||
if len(existing) == 0:
|
||||
return ResponseObject(False, "Job does not exist", status_code=404)
|
||||
|
||||
success, result = AllPeerJobs.saveJob(PeerJob(
|
||||
data['JobID'], data['Configuration'], peerKey, data['Field'], data['Operator'], data['Value'],
|
||||
datetime.now(), data.get('ExpireDate'), data['Action']))
|
||||
if success:
|
||||
return ResponseObject(success, data=result)
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.delete(f'{APP_PREFIX}/api/PeerScheduleJob')
|
||||
@require_fields('JobID', 'Configuration', 'Peer')
|
||||
def API_deletePeerScheduleJob():
|
||||
data = request.json
|
||||
if "Job" not in data.keys():
|
||||
return ResponseObject(False, "Please specify job")
|
||||
job: dict = data['Job']
|
||||
if "Peer" not in job.keys() or "Configuration" not in job.keys():
|
||||
return ResponseObject(False, "Please specify peer and configuration")
|
||||
configuration = WireguardConfigurations.get(job['Configuration'])
|
||||
|
||||
configuration = WireguardConfigurations.get(data['Configuration'])
|
||||
if configuration is None:
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
# f, fp = configuration.searchPeer(job['Peer'])
|
||||
# if not f:
|
||||
# return ResponseObject(False, "Peer does not exist")
|
||||
return ResponseObject(False, "Configuration does not exist", status_code=404)
|
||||
|
||||
s, p = AllPeerJobs.deleteJob(PeerJob(
|
||||
job['JobID'], job['Configuration'], job['Peer'], job['Field'], job['Operator'], job['Value'],
|
||||
job['CreationDate'], job['ExpireDate'], job['Action']))
|
||||
if s:
|
||||
return ResponseObject(s)
|
||||
return ResponseObject(s, message=p)
|
||||
peerKey = unquote(data['Peer'])
|
||||
success, result = AllPeerJobs.deleteJob(PeerJob(
|
||||
data['JobID'], data['Configuration'], peerKey, data.get('Field', ''),
|
||||
data.get('Operator', ''), data.get('Value', ''),
|
||||
datetime.now(), data.get('ExpireDate'), data.get('Action', '')))
|
||||
if success:
|
||||
return ResponseObject(success, message="Job deleted successfully")
|
||||
return ResponseObject(success, message=result)
|
||||
|
||||
@app.get(f'{APP_PREFIX}/api/getPeerScheduleJobLogs/<configName>')
|
||||
@app.get(f'{APP_PREFIX}/api/PeerScheduleJobLogs/<configName>')
|
||||
def API_getPeerScheduleJobLogs(configName):
|
||||
if configName not in WireguardConfigurations.keys():
|
||||
return ResponseObject(False, "Configuration does not exist")
|
||||
@@ -1274,11 +1362,11 @@ def API_ping_getAllPeersIpAddress():
|
||||
for x in allowed_ip:
|
||||
try:
|
||||
ip = ipaddress.ip_network(x, strict=False)
|
||||
if ip.num_addresses == 1:
|
||||
parsed.append(str(ip.network_address))
|
||||
except ValueError as e:
|
||||
app.logger.error(f"Failed to parse IP address of {p.id} - {c.Name}")
|
||||
host = list(ip.hosts())
|
||||
if len(host) == 1:
|
||||
parsed.append(str(host[0]))
|
||||
|
||||
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
|
||||
if len(p.name) > 0:
|
||||
cips[f"{p.name} - {p.id}"] = {
|
||||
@@ -1415,11 +1503,15 @@ def API_Welcome_GetTotpLink():
|
||||
@app.post(f'{APP_PREFIX}/api/Welcome_VerifyTotpLink')
|
||||
def API_Welcome_VerifyTotpLink():
|
||||
data = request.get_json()
|
||||
totp = pyotp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).now()
|
||||
if totp == data['totp']:
|
||||
totp_code = str(data.get("totp", "")).strip()
|
||||
totpValid = pyotp.TOTP(
|
||||
DashboardConfig.GetConfig("Account", "totp_key")[1]
|
||||
).verify(totp_code, valid_window=1)
|
||||
|
||||
if totpValid:
|
||||
DashboardConfig.SetConfig("Account", "totp_verified", "true")
|
||||
DashboardConfig.SetConfig("Account", "enable_totp", "true")
|
||||
return ResponseObject(totp == data['totp'])
|
||||
return ResponseObject(totpValid)
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/Welcome_Finish')
|
||||
def API_Welcome_Finish():
|
||||
@@ -1511,7 +1603,8 @@ def API_Email_Send():
|
||||
subject = Template(data.get('Subject', '')).render(peer=p.toJson(), configurationFile=download)
|
||||
if data.get('IncludeAttachment', False):
|
||||
u = str(uuid4())
|
||||
attachmentName = f'{u}.conf'
|
||||
peerName = p.toJson().get('name', '').strip()
|
||||
attachmentName = f'{peerName if peerName else u}.conf'
|
||||
with open(os.path.join('./attachments', attachmentName,), 'w+') as f:
|
||||
f.write(download['file'])
|
||||
|
||||
|
||||
@@ -32,11 +32,15 @@ class AmneziaConfiguration(WireguardConfiguration):
|
||||
self.H2 = 2
|
||||
self.H3 = 3
|
||||
self.H4 = 4
|
||||
self.I1 = "0"
|
||||
self.I2 = "0"
|
||||
self.I3 = "0"
|
||||
self.I4 = "0"
|
||||
self.I5 = "0"
|
||||
self.I1 = ""
|
||||
self.I2 = ""
|
||||
self.I3 = ""
|
||||
self.I4 = ""
|
||||
self.I5 = ""
|
||||
self.J1 = ""
|
||||
self.J2 = ""
|
||||
self.J3 = ""
|
||||
self.Itime = ""
|
||||
|
||||
super().__init__(DashboardConfig, AllPeerJobs, AllPeerShareLinks, DashboardWebHooks, name, data, backup, startup, wg=False)
|
||||
|
||||
@@ -79,7 +83,11 @@ class AmneziaConfiguration(WireguardConfiguration):
|
||||
"I2": self.I2,
|
||||
"I3": self.I3,
|
||||
"I4": self.I4,
|
||||
"I5": self.I5
|
||||
"I5": self.I5,
|
||||
"J1": self.J1,
|
||||
"J2": self.J2,
|
||||
"J3": self.J3,
|
||||
"Itime": self.Itime
|
||||
}
|
||||
|
||||
def createDatabase(self, dbName = None):
|
||||
|
||||
@@ -87,8 +87,9 @@ class AmneziaPeer(Peer):
|
||||
|
||||
if psk_exist: os.remove(uid)
|
||||
|
||||
if len(updateAllowedIp.decode().strip("\n")) != 0:
|
||||
current_app.logger.error(f"Update peer failed when updating Allowed IPs.\nInput: {newAllowedIPs}\nOutput: {updateAllowedIp.decode().strip('\n')}")
|
||||
output = updateAllowedIp.decode().strip("\n")
|
||||
if len(output) != 0:
|
||||
current_app.logger.error(f"Update peer failed when updating Allowed IPs.\nInput: {newAllowedIPs}\nOutput: {output}")
|
||||
return False, "Internal server error"
|
||||
|
||||
command = [f"{self.configuration.Protocol}-quick", "save", self.configuration.Name]
|
||||
|
||||
@@ -12,7 +12,7 @@ from .Utilities import (GetRemoteEndpoint, ValidateDNSAddress)
|
||||
from .DashboardAPIKey import DashboardAPIKey
|
||||
|
||||
class DashboardConfig:
|
||||
DashboardVersion = 'v4.3.3'
|
||||
DashboardVersion = 'v4.3.4'
|
||||
ConfigurationPath = os.getenv('CONFIGURATION_PATH', '.')
|
||||
ConfigurationFilePath = os.path.join(ConfigurationPath, 'wg-dashboard.ini')
|
||||
|
||||
@@ -51,7 +51,8 @@ class DashboardConfig:
|
||||
"peer_display_mode": "grid",
|
||||
"remote_endpoint": GetRemoteEndpoint(),
|
||||
"peer_MTU": "1420",
|
||||
"peer_keep_alive": "21"
|
||||
"peer_keep_alive": "21",
|
||||
"peer_preshared_key_default": "false"
|
||||
},
|
||||
"Other": {
|
||||
"welcome_session": "true"
|
||||
@@ -146,14 +147,17 @@ class DashboardConfig:
|
||||
if col_name not in existing_columns:
|
||||
type_str = col_type().compile(dialect=self.engine.dialect)
|
||||
current_app.logger.info(f"Adding missing column '{col_name}' to table '{table_name}'")
|
||||
conn.execute(db.text(f'ALTER TABLE "{table_name}" ADD COLUMN "{col_name}" {type_str}'))
|
||||
preparer = self.engine.dialect.identifier_preparer
|
||||
quoted_table = preparer.quote_identifier(table_name)
|
||||
quoted_column = preparer.quote_identifier(col_name)
|
||||
conn.execute(db.text(f"ALTER TABLE {quoted_table} ADD COLUMN {quoted_column} {type_str}"))
|
||||
|
||||
def getConnectionString(self, database) -> str or None:
|
||||
sqlitePath = os.path.join(DashboardConfig.ConfigurationPath, "db")
|
||||
|
||||
|
||||
if not os.path.isdir(sqlitePath):
|
||||
os.mkdir(sqlitePath)
|
||||
|
||||
|
||||
if self.GetConfig("Database", "type")[1] == "postgresql":
|
||||
cn = f'postgresql+psycopg2://{self.GetConfig("Database", "username")[1]}:{self.GetConfig("Database", "password")[1]}@{self.GetConfig("Database", "host")[1]}/{database}'
|
||||
elif self.GetConfig("Database", "type")[1] == "mysql":
|
||||
|
||||
@@ -82,13 +82,18 @@ class DashboardOIDC:
|
||||
|
||||
headers = jwt.get_unverified_header(id_token)
|
||||
kid = headers["kid"]
|
||||
|
||||
|
||||
key = next(k for k in jwks["keys"] if k["kid"] == kid)
|
||||
|
||||
|
||||
alg = key.get("alg") or headers.get("alg")
|
||||
supported_algs = oidc_config.get("id_token_signing_alg_values_supported")
|
||||
if supported_algs and alg not in supported_algs:
|
||||
return False, f"Unsupported token signing algorithm: {alg}"
|
||||
|
||||
payload = jwt.decode(
|
||||
id_token,
|
||||
key,
|
||||
algorithms=[key["alg"]],
|
||||
algorithms=[alg],
|
||||
audience=provider_info.get('client_id'),
|
||||
issuer=issuer,
|
||||
access_token=access_token
|
||||
@@ -134,7 +139,7 @@ class DashboardOIDC:
|
||||
'openid_configuration': oidc_config
|
||||
}
|
||||
self.provider_secret[k] = providers[k]['client_secret']
|
||||
current_app.logger.info(f"Registered OIDC Provider: {k}")
|
||||
current_app.logger.info(f"Registered OIDC Provider[{self.mode}]: {k}")
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to register OIDC config for {k}", exc_info=e)
|
||||
except Exception as e:
|
||||
|
||||
+5
-1
@@ -206,7 +206,11 @@ class Peer:
|
||||
"I2": self.configuration.I2,
|
||||
"I3": self.configuration.I3,
|
||||
"I4": self.configuration.I4,
|
||||
"I5": self.configuration.I5
|
||||
"I5": self.configuration.I5,
|
||||
"J1": self.configuration.J1,
|
||||
"J2": self.configuration.J2,
|
||||
"J3": self.configuration.J3,
|
||||
"Itime": self.configuration.Itime
|
||||
})
|
||||
|
||||
peerSection = {
|
||||
|
||||
@@ -109,23 +109,31 @@ class WireguardConfiguration:
|
||||
}
|
||||
|
||||
if self.Protocol == 'awg':
|
||||
self.__parser["Interface"]["Jc"] = self.Jc
|
||||
self.__parser["Interface"]["Jc"] = self.Jc
|
||||
self.__parser["Interface"]["Jmin"] = self.Jmin
|
||||
self.__parser["Interface"]["Jmax"] = self.Jmax
|
||||
self.__parser["Interface"]["S1"] = self.S1
|
||||
self.__parser["Interface"]["S2"] = self.S2
|
||||
self.__parser["Interface"]["S3"] = self.S3
|
||||
self.__parser["Interface"]["S4"] = self.S4
|
||||
self.__parser["Interface"]["H1"] = self.H1
|
||||
self.__parser["Interface"]["H2"] = self.H2
|
||||
self.__parser["Interface"]["H3"] = self.H3
|
||||
self.__parser["Interface"]["H4"] = self.H4
|
||||
self.__parser["Interface"]["I1"] = self.I1
|
||||
self.__parser["Interface"]["I2"] = self.I2
|
||||
self.__parser["Interface"]["I3"] = self.I3
|
||||
self.__parser["Interface"]["I4"] = self.I4
|
||||
self.__parser["Interface"]["I5"] = self.I5
|
||||
values = {
|
||||
"Jc": self.Jc,
|
||||
"Jmin": self.Jmin,
|
||||
"Jmax": self.Jmax,
|
||||
"S1": self.S1,
|
||||
"S2": self.S2,
|
||||
"S3": self.S3,
|
||||
"S4": self.S4,
|
||||
"H1": self.H1,
|
||||
"H2": self.H2,
|
||||
"H3": self.H3,
|
||||
"H4": self.H4,
|
||||
"I1": self.I1,
|
||||
"I2": self.I2,
|
||||
"I3": self.I3,
|
||||
"I4": self.I4,
|
||||
"I5": self.I5,
|
||||
"J1": self.J1,
|
||||
"J2": self.J2,
|
||||
"J3": self.J3,
|
||||
"Itime": self.Itime
|
||||
}
|
||||
for key, value in values.items():
|
||||
if value != None and str(value).strip():
|
||||
self.__parser["Interface"][key] = str(value)
|
||||
|
||||
if "Backup" not in data.keys():
|
||||
self.createDatabase()
|
||||
@@ -1007,8 +1015,10 @@ class WireguardConfiguration:
|
||||
with open(self.configPath, 'r') as f:
|
||||
original = [l.rstrip("\n") for l in f.readlines()]
|
||||
allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort", "Table"]
|
||||
awgKeys = []
|
||||
if self.Protocol == 'awg':
|
||||
allowEdit += ["Jc", "Jmin", "Jmax", "S1", "S2", "S3", "S4", "H1", "H2", "H3", "H4", "I1", "I2", "I3", "I4", "I5"]
|
||||
awgKeys = ["Jc", "Jmin", "Jmax", "S1", "S2", "S3", "S4", "H1", "H2", "H3", "H4", "I1", "I2", "I3", "I4", "I5", "J1", "J2", "J3", "Itime"]
|
||||
allowEdit += awgKeys
|
||||
start = original.index("[Interface]")
|
||||
try:
|
||||
end = original.index("[Peer]")
|
||||
@@ -1022,7 +1032,10 @@ class WireguardConfiguration:
|
||||
if split[0] not in allowEdit:
|
||||
new.append(original[line])
|
||||
for key in allowEdit:
|
||||
new.insert(1, f"{key} = {str(newData[key]).strip()}")
|
||||
val = str(newData.get(key, "")).strip()
|
||||
if key in awgKeys and val == "":
|
||||
continue
|
||||
new.insert(1, f"{key} = {val}")
|
||||
new.append("")
|
||||
for line in range(end, len(original)):
|
||||
new.append(original[line])
|
||||
@@ -1072,6 +1085,11 @@ class WireguardConfiguration:
|
||||
doRenameStatement("_restrict_access")
|
||||
doRenameStatement("_deleted")
|
||||
doRenameStatement("_transfer")
|
||||
conn.execute(
|
||||
self.infoTable.update()
|
||||
.where(self.infoTable.c.ID == self.Name)
|
||||
.values(ID=newConfigurationName)
|
||||
)
|
||||
|
||||
self.AllPeerJobs.updateJobConfigurationName(self.Name, newConfigurationName)
|
||||
shutil.copy(
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
bcrypt==5.0.0
|
||||
ifcfg==0.24
|
||||
psutil==7.2.2
|
||||
pyotp==2.9.0
|
||||
pyotp==2.10.0
|
||||
Flask==3.1.2
|
||||
flask-cors==6.0.2
|
||||
flask-cors==6.0.5
|
||||
icmplib==3.0.4
|
||||
gunicorn==25.0.3
|
||||
requests==2.32.5
|
||||
gunicorn==26.0.0
|
||||
requests==2.34.2
|
||||
tcconfig==0.30.1
|
||||
sqlalchemy==2.0.46
|
||||
sqlalchemy==2.0.51
|
||||
sqlalchemy_utils==0.42.1
|
||||
psycopg[binary]==3.3.3
|
||||
PyMySQL==1.1.2
|
||||
psycopg[binary]==3.3.4
|
||||
PyMySQL==1.2.0
|
||||
tzlocal==5.3.1
|
||||
python-jose==3.5.0
|
||||
pydantic==2.12.5
|
||||
pydantic==2.13.4
|
||||
|
||||
@@ -11,6 +11,26 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WGDashboard</title>
|
||||
<base href="./">
|
||||
<style>
|
||||
#preloader{
|
||||
width: 100vw; height: 100vh; display: flex
|
||||
}
|
||||
#preloader_placeholder{
|
||||
width: 50px; height: 50px; background-color: #000; margin: auto;
|
||||
animation: 3s ease-in-out fadeInPreloader infinite;
|
||||
}
|
||||
@keyframes fadeInPreloader {
|
||||
0%{
|
||||
opacity: 0;
|
||||
}
|
||||
50%{
|
||||
opacity: 1;
|
||||
}
|
||||
100%{
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const isViteDevMode = document.querySelector('script[src*="@vite/client"]') !== null;
|
||||
const base = document.querySelector('base');
|
||||
@@ -20,7 +40,13 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
<div id="preloader">
|
||||
<div id="preloader_placeholder">
|
||||
<img style="width: 100%" src="./img/Logo-2-128x128.png" alt="WGDashboard Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="./src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Generated
+865
-1102
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app",
|
||||
"version": "4.3.3",
|
||||
"version": "4.3.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"module": "es2022",
|
||||
@@ -13,35 +13,35 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@volar/language-server": "2.4.28",
|
||||
"@vue/language-server": "3.2.4",
|
||||
"@vuepic/vue-datepicker": "^12.1.0",
|
||||
"@vue/language-server": "3.2.7",
|
||||
"@vuepic/vue-datepicker": "^14.0.0",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"@vueuse/shared": "^14.1.0",
|
||||
"@vueuse/shared": "^14.3.0",
|
||||
"animate.css": "^4.1.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"cidr-tools": "^11.3.2",
|
||||
"cidr-tools": "^12.0.2",
|
||||
"css-color-converter": "^2.0.0",
|
||||
"dayjs": "^1.11.19",
|
||||
"electron-builder": "^26.7.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"fuse.js": "^7.3.0",
|
||||
"i": "^0.3.7",
|
||||
"is-cidr": "^6.0.3",
|
||||
"npm": "^11.8.0",
|
||||
"ol": "^10.7.0",
|
||||
"npm": "^11.13.0",
|
||||
"ol": "^10.9.0",
|
||||
"pinia": "^3.0.4",
|
||||
"pinia-plugin-persistedstate": "^4.7.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"qrcodejs": "^1.0.0",
|
||||
"simple-code-editor": "^2.0.9",
|
||||
"uuid": "^13.0.0",
|
||||
"vue": "^3.5.31",
|
||||
"uuid": "^14.0.0",
|
||||
"vue": "^3.5.32",
|
||||
"vue-chartjs": "^5.3.3",
|
||||
"vue-router": "^5.0.4"
|
||||
"vue-router": "^5.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"vite": "^7.3.1"
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"vite": "^8.0.16"
|
||||
},
|
||||
"overrides": {
|
||||
"tar": "^7.5.6"
|
||||
|
||||
+14
-5
@@ -6,18 +6,27 @@ export default {
|
||||
components: {LocaleText},
|
||||
props: {
|
||||
data: Object,
|
||||
saving: Boolean
|
||||
saving: Boolean,
|
||||
defaultEnabled: Boolean
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
enable: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const hasKey = !!(this.data && this.data.preshared_key && this.data.preshared_key.length > 0)
|
||||
if (hasKey || this.defaultEnabled){
|
||||
this.enable = true
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
enable(){
|
||||
if (this.enable){
|
||||
this.data.preshared_key = window.wireguard.generateKeypair().presharedKey
|
||||
}else {
|
||||
if (this.enable) {
|
||||
if (!this.data.preshared_key){
|
||||
this.data.preshared_key = window.wireguard.generateKeypair().presharedKey
|
||||
}
|
||||
} else {
|
||||
this.data.preshared_key = ""
|
||||
}
|
||||
}
|
||||
@@ -48,4 +57,4 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -32,7 +32,7 @@ const peerData = ref({
|
||||
keepalive: parseInt(dashboardStore.Configuration.Peers.peer_keep_alive),
|
||||
mtu: parseInt(dashboardStore.Configuration.Peers.peer_mtu),
|
||||
preshared_key: "",
|
||||
preshared_key_bulkAdd: false,
|
||||
preshared_key_bulkAdd: Boolean(dashboardStore.Configuration.Peers.peer_preshared_key_default),
|
||||
allowed_ips_validation: true,
|
||||
})
|
||||
const availableIp = ref([])
|
||||
@@ -128,7 +128,7 @@ watch(() => {
|
||||
<EndpointAllowedIps :saving="saving" :data="peerData"></EndpointAllowedIps>
|
||||
<div class="row gy-3">
|
||||
<div class="col-sm" v-if="!peerData.bulkAdd">
|
||||
<PresharedKeyInput :saving="saving" :data="peerData" :bulk="peerData.bulkAdd"></PresharedKeyInput>
|
||||
<PresharedKeyInput :saving="saving" :data="peerData" :bulk="peerData.bulkAdd" :defaultEnabled="Boolean(dashboardStore.Configuration.Peers.peer_preshared_key_default)"></PresharedKeyInput>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
@@ -177,4 +177,4 @@ watch(() => {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -36,7 +36,7 @@ export default {
|
||||
keepalive: parseInt(this.dashboardStore.Configuration.Peers.peer_keep_alive),
|
||||
mtu: parseInt(this.dashboardStore.Configuration.Peers.peer_mtu),
|
||||
preshared_key: "",
|
||||
preshared_key_bulkAdd: false,
|
||||
preshared_key_bulkAdd: Boolean(this.dashboardStore.Configuration.Peers.peer_preshared_key_default),
|
||||
},
|
||||
availableIp: undefined,
|
||||
availableIpSearchString: "",
|
||||
@@ -133,7 +133,7 @@ export default {
|
||||
<hr class="mb-0 mt-2">
|
||||
<div class="row gy-3">
|
||||
<div class="col-sm" v-if="!this.data.bulkAdd">
|
||||
<PresharedKeyInput :saving="saving" :data="data" :bulk="this.data.bulkAdd"></PresharedKeyInput>
|
||||
<PresharedKeyInput :saving="saving" :data="data" :bulk="this.data.bulkAdd" :defaultEnabled="Boolean(this.dashboardStore.Configuration.Peers.peer_preshared_key_default)"></PresharedKeyInput>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
@@ -187,4 +187,4 @@ div{
|
||||
.card{
|
||||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
methods: {
|
||||
async fetchLog(){
|
||||
this.dataLoading = true;
|
||||
await fetchGet(`/api/getPeerScheduleJobLogs/${this.configurationInfo.Name}`, {}, (res) => {
|
||||
await fetchGet(`/api/PeerScheduleJobLogs/${this.configurationInfo.Name}`, {}, (res) => {
|
||||
this.data = res.data;
|
||||
this.logFetchTime = dayjs().format("YYYY-MM-DD HH:mm:ss")
|
||||
this.dataLoading = false;
|
||||
|
||||
+4
-7
@@ -2,7 +2,7 @@
|
||||
import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJobsComponents/scheduleDropdown.vue";
|
||||
import {ref} from "vue";
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
import {fetchPost} from "@/utilities/fetch.js";
|
||||
import {fetchPost, fetchPut, fetchDelete} from "@/utilities/fetch.js";
|
||||
import { VueDatePicker } from "@vuepic/vue-datepicker";
|
||||
import dayjs from "dayjs";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
@@ -46,9 +46,8 @@ export default {
|
||||
methods: {
|
||||
save(){
|
||||
if (this.job.Field && this.job.Operator && this.job.Action && this.job.Value){
|
||||
fetchPost(`/api/savePeerScheduleJob`, {
|
||||
Job: this.job
|
||||
}, (res) => {
|
||||
const fn = this.newJob ? fetchPost : fetchPut;
|
||||
fn(`/api/PeerScheduleJob`, this.job, (res) => {
|
||||
if (res.status){
|
||||
this.edit = false;
|
||||
this.store.newMessage("Server", "Peer job saved", "success")
|
||||
@@ -84,9 +83,7 @@ export default {
|
||||
},
|
||||
delete(){
|
||||
if(this.job.CreationDate){
|
||||
fetchPost(`/api/deletePeerScheduleJob`, {
|
||||
Job: this.job
|
||||
}, (res) => {
|
||||
fetchDelete(`/api/PeerScheduleJob`, this.job, (res) => {
|
||||
if (!res.status){
|
||||
this.store.newMessage("Server", res.message, "danger")
|
||||
this.$emit('delete')
|
||||
|
||||
@@ -22,6 +22,8 @@ import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefau
|
||||
targetData="peer_mtu" title="MTU"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="peer_keep_alive" title="Persistent Keepalive"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="peer_preshared_key_default" title="Pre-Shared Key Default"></PeersDefaultSettingsInput>
|
||||
<PeersDefaultSettingsInput
|
||||
targetData="remote_endpoint" title="Peer Remote Endpoint"
|
||||
:warning="true" warningText="This will be changed globally, and will be apply to all peer's QR code and configuration file."
|
||||
@@ -34,4 +36,4 @@ import PeersDefaultSettingsInput from "@/components/settingsComponent/peersDefau
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -31,6 +31,11 @@ export default {
|
||||
mounted() {
|
||||
this.value = this.store.Configuration.Peers[this.targetData];
|
||||
},
|
||||
computed: {
|
||||
isBoolean(){
|
||||
return typeof this.value === "boolean"
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
async useValidation(){
|
||||
if(this.changed){
|
||||
@@ -67,7 +72,14 @@ export default {
|
||||
<LocaleText :t="this.title"></LocaleText>
|
||||
</small></strong>
|
||||
</label>
|
||||
<input type="text" class="form-control"
|
||||
<div v-if="isBoolean" class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
v-model="this.value"
|
||||
:id="this.uuid"
|
||||
@change="this.changed = true; useValidation()"
|
||||
:disabled="this.updating">
|
||||
</div>
|
||||
<input v-else type="text" class="form-control"
|
||||
:class="{'is-invalid': showInvalidFeedback, 'is-valid': isValid}"
|
||||
:id="this.uuid"
|
||||
v-model="this.value"
|
||||
@@ -88,4 +100,4 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup async>
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {fetchGet} from "@/utilities/fetch.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
const providers = ref([])
|
||||
const oidcEnabled = ref(false)
|
||||
|
||||
await fetchGet("/api/oidc/providers", {}, async (res) => {
|
||||
if (res.status){
|
||||
await Promise.all(Object.entries(res.data).map(([key, value]) => {
|
||||
return fetch(`${value.issuer}/.well-known/openid-configuration`).then((res) => {
|
||||
providers.value.push({
|
||||
Provider: key,
|
||||
ProviderInfo: value
|
||||
})
|
||||
}).catch(() => {
|
||||
console.log("Failed to request " + key)
|
||||
})
|
||||
}))
|
||||
oidcEnabled.value = providers.value.length > 0
|
||||
}
|
||||
})
|
||||
console.log(providers.value)
|
||||
const oidcUrl = (provider) => {
|
||||
const params = new URLSearchParams({
|
||||
client_id: provider.ProviderInfo.client_id,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname,
|
||||
response_type: 'code',
|
||||
state: provider.Provider,
|
||||
scope: 'openid email profile'
|
||||
})
|
||||
console.log(params.entries())
|
||||
const url = new URL(provider.ProviderInfo.openid_configuration.authorization_endpoint)
|
||||
url.search = params.toString()
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="oidcEnabled">
|
||||
<hr class="mb-4"/>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn bg-body border w-100 rounded-3"
|
||||
:href="oidcUrl(provider)"
|
||||
v-for="provider in providers" style="flex: 1 1 0;">
|
||||
<LocaleText :t="'Sign In With ' + provider.Provider"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
+57
-10
@@ -7,18 +7,65 @@ import '@vuepic/vue-datepicker/dist/main.css'
|
||||
import {createApp, markRaw} from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router/router.js'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
|
||||
|
||||
const app = createApp(App)
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const state = params.get('state')
|
||||
const code = params.get('code')
|
||||
|
||||
app.use(router)
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
pinia.use(({ store }) => {
|
||||
store.$router = markRaw(router)
|
||||
})
|
||||
if (state && code) {
|
||||
window.history.replaceState({}, '', window.location.pathname);
|
||||
console.log('After replaceState:', window.location.href);
|
||||
}
|
||||
|
||||
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
const initApp = async () => {
|
||||
const { default: router } = await import('./router/router.js')
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
pinia.use(({ store }) => {
|
||||
store.$router = markRaw(router)
|
||||
})
|
||||
|
||||
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
||||
console.log('After router import:', window.location.href)
|
||||
}
|
||||
|
||||
export const getUrl = (url) => {
|
||||
if (import.meta.env.MODE === 'development') {
|
||||
return url;
|
||||
}
|
||||
return `./.${url}`;
|
||||
}
|
||||
|
||||
if (state && code){
|
||||
await fetch(getUrl('/api/oidc/authenticate'), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
provider: state,
|
||||
code: code,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname
|
||||
})
|
||||
}).then(res => res.json()).then( async (res) => {
|
||||
if (res.status){
|
||||
window.location.replace(window.location.protocol + '//' + window.location.host + window.location.pathname)
|
||||
}else{
|
||||
await initApp()
|
||||
const store = DashboardConfigurationStore()
|
||||
store.newMessage('Server OIDC', res.message, 'danger')
|
||||
}
|
||||
})
|
||||
}else{
|
||||
await initApp()
|
||||
}
|
||||
|
||||
@@ -4,17 +4,21 @@ const getHeaders = () => {
|
||||
let headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
const store = DashboardConfigurationStore();
|
||||
const crossServer = store.getActiveCrossServer();
|
||||
if (crossServer){
|
||||
headers['wg-dashboard-apikey'] = crossServer.apiKey
|
||||
if (crossServer.headers){
|
||||
for (let header of Object.values(crossServer.headers)){
|
||||
if (header.key && header.value && !Object.keys(headers).includes(header.key)){
|
||||
headers[header.key] = header.value
|
||||
}
|
||||
}
|
||||
}
|
||||
try{
|
||||
const store = DashboardConfigurationStore();
|
||||
const crossServer = store.getActiveCrossServer();
|
||||
if (crossServer){
|
||||
headers['wg-dashboard-apikey'] = crossServer.apiKey
|
||||
if (crossServer.headers){
|
||||
for (let header of Object.values(crossServer.headers)){
|
||||
if (header.key && header.value && !Object.keys(headers).includes(header.key)){
|
||||
headers[header.key] = header.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +26,13 @@ const getHeaders = () => {
|
||||
}
|
||||
|
||||
export const getUrl = (url) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
const apiKey = store.getActiveCrossServer();
|
||||
if (apiKey){
|
||||
return `${apiKey.host}${url}`
|
||||
}
|
||||
try{
|
||||
const store = DashboardConfigurationStore();
|
||||
const apiKey = store.getActiveCrossServer();
|
||||
if (apiKey){
|
||||
return `${apiKey.host}${url}`
|
||||
}
|
||||
}catch (e){}
|
||||
if (import.meta.env.MODE === 'development') {
|
||||
return url;
|
||||
}
|
||||
@@ -79,4 +85,50 @@ export const fetchPost = async (url, body, callback) => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchPut = async (url, body, callback) => {
|
||||
await fetch(`${getUrl(url)}`, {
|
||||
headers: getHeaders(),
|
||||
method: "PUT",
|
||||
body: JSON.stringify(body)
|
||||
}).then((x) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
if (!x.ok){
|
||||
if (x.status !== 200){
|
||||
if (x.status === 401){
|
||||
store.newMessage("WGDashboard", "Sign in session ended, please sign in again", "warning")
|
||||
}
|
||||
throw new Error(x.statusText)
|
||||
}
|
||||
}else{
|
||||
return x.json()
|
||||
}
|
||||
}).then(x => callback ? callback(x) : undefined).catch(x => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
|
||||
export const fetchDelete = async (url, body, callback) => {
|
||||
await fetch(`${getUrl(url)}`, {
|
||||
headers: getHeaders(),
|
||||
method: "DELETE",
|
||||
body: JSON.stringify(body)
|
||||
}).then((x) => {
|
||||
const store = DashboardConfigurationStore();
|
||||
if (!x.ok){
|
||||
if (x.status !== 200){
|
||||
if (x.status === 401){
|
||||
store.newMessage("WGDashboard", "Sign in session ended, please sign in again", "warning")
|
||||
}
|
||||
throw new Error(x.statusText)
|
||||
}
|
||||
}else{
|
||||
return x.json()
|
||||
}
|
||||
}).then(x => callback ? callback(x) : undefined).catch(x => {
|
||||
console.log("Error:", x)
|
||||
router.push({path: '/signin'})
|
||||
})
|
||||
}
|
||||
@@ -7,10 +7,11 @@ import {GetLocale} from "@/utilities/locale.js";
|
||||
import LocaleText from "@/components/text/localeText.vue";
|
||||
import SignInInput from "@/components/signIn/signInInput.vue";
|
||||
import SignInTOTP from "@/components/signIn/signInTOTP.vue";
|
||||
import SignInOIDC from "@/components/signIn/signInOIDC.vue";
|
||||
|
||||
export default {
|
||||
name: "signin",
|
||||
components: {SignInTOTP, SignInInput, LocaleText, RemoteServerList, Message},
|
||||
components: {SignInOIDC, SignInTOTP, SignInInput, LocaleText, RemoteServerList, Message},
|
||||
async setup(){
|
||||
const store = DashboardConfigurationStore()
|
||||
let theme = "dark"
|
||||
@@ -171,7 +172,7 @@ export default {
|
||||
</form>
|
||||
<RemoteServerList v-else></RemoteServerList>
|
||||
|
||||
<div class="d-flex mt-3" v-if="!this.store.IsElectronApp">
|
||||
<div class="d-flex mt-3 flex-column" v-if="!this.store.IsElectronApp">
|
||||
<div class="form-check form-switch ms-auto">
|
||||
<input
|
||||
v-model="this.store.CrossServerConfiguration.Enable"
|
||||
@@ -184,6 +185,8 @@ export default {
|
||||
<LocaleText t="Access Remote Server"></LocaleText>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<SignInOIDC />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Generated
+1542
-1711
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "client",
|
||||
"version": "v1.0",
|
||||
"version": "v1.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -9,20 +9,20 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.9.0",
|
||||
"bootstrap": "^5.3.6",
|
||||
"axios": "^1.18.0",
|
||||
"bootstrap": "^5.3.8",
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"oidc-client-ts": "^3.2.1",
|
||||
"pinia": "^3.0.2",
|
||||
"dayjs": "^1.11.21",
|
||||
"oidc-client-ts": "^3.5.0",
|
||||
"pinia": "^3.0.4",
|
||||
"qrcode": "^1.5.4",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.1"
|
||||
"uuid": "^14.0.0",
|
||||
"vue": "^3.5.35",
|
||||
"vue-router": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"vite": "^6.2.4",
|
||||
"vite-plugin-vue-devtools": "^7.7.2"
|
||||
"@vitejs/plugin-vue": "^6.0.6",
|
||||
"vite": "^8.0.16",
|
||||
"vite-plugin-vue-devtools": "^8.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from "@/router/router.js";
|
||||
import {createPinia} from "pinia";
|
||||
|
||||
import 'bootstrap/dist/js/bootstrap.bundle.js'
|
||||
@@ -13,7 +12,13 @@ const params = new URLSearchParams(window.location.search)
|
||||
const state = params.get('state')
|
||||
const code = params.get('code')
|
||||
|
||||
if (state && code) {
|
||||
window.history.replaceState({}, '', window.location.pathname);
|
||||
}
|
||||
|
||||
const initApp = async () => {
|
||||
debugger
|
||||
const { default: router } = await import('./router/router.js')
|
||||
const app = createApp(App)
|
||||
const serverInformation = await axiosGet("/api/serverInformation", {})
|
||||
app.use(createPinia())
|
||||
@@ -31,12 +36,10 @@ if (state && code){
|
||||
code: code,
|
||||
redirect_uri: window.location.protocol + '//' + window.location.host + window.location.pathname
|
||||
}).then(async (data) => {
|
||||
let url = new URL(window.location.href);
|
||||
url.search = '';
|
||||
history.replaceState({}, document.title, url.toString());
|
||||
|
||||
await initApp()
|
||||
if (!data.status){
|
||||
if (data.status){
|
||||
window.location.replace(window.location.protocol + '//' + window.location.host + window.location.pathname)
|
||||
}else {
|
||||
await initApp()
|
||||
const store = clientStore()
|
||||
store.newNotification(data.message, 'danger')
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{a5 as A,r as n,D as S,g as l,z as v}from"./index-DXzxfcZW.js";const b=A("DashboardClientAssignmentStore",()=>{const f=n({}),d=n([]),o=n({}),c=n([]),g=n(!1),r=n(""),i=S(),w=async()=>{await l("/api/clients/allClients",{},s=>{o.value=s.data})},y=async()=>{await l("/api/clients/allClientsRaw",{},s=>{c.value=s.data,console.log(c.value)})},m=s=>Object.values(o.value).flat().find(e=>e.ClientID===s),u=async(s,e)=>{await l("/api/clients/assignedClients",{ConfigurationName:s,Peer:e},a=>{d.value=a.data})};return{assignments:d,getAssignedClients:u,getClients:w,getClientsRaw:y,clients:o,unassignClient:async(s,e,a)=>{g.value=!0,await v("/api/clients/unassignClient",{AssignmentID:a},async t=>{t.status?(i.newMessage("Server","Unassign successfully!","success"),s&&e&&await u(s,e)):(i.newMessage("Server","Unassign Failed. Reason: "+t.message,"success"),console.error("Unassign Failed. Reason: "+t.message)),g.value=!1})},assignClient:async(s,e,a,t=!0)=>{r.value=a,await v("/api/clients/assignClient",{ConfigurationName:s,Peer:e,ClientID:a},async C=>{C.status?(i.newMessage("Server","Assign successfully!","success"),t&&await u(s,e)):(i.newMessage("Server","Assign Failed. Reason: "+C.message,"success"),console.error("Assign Failed. Reason: "+C.message)),r.value=""})},getClientById:m,unassigning:g,assigning:r,clientsRaw:c,allConfigurationsPeers:f,getAllConfigurationsPeers:async()=>{await l("/api/clients/allConfigurationsPeers",{},s=>{f.value=s.data})}}});export{b as D};
|
||||
import{a5 as A,r as n,D as S,g as l,z as v}from"./index-DM7YJCOo.js";const b=A("DashboardClientAssignmentStore",()=>{const f=n({}),d=n([]),o=n({}),c=n([]),g=n(!1),r=n(""),i=S(),w=async()=>{await l("/api/clients/allClients",{},s=>{o.value=s.data})},y=async()=>{await l("/api/clients/allClientsRaw",{},s=>{c.value=s.data,console.log(c.value)})},m=s=>Object.values(o.value).flat().find(e=>e.ClientID===s),u=async(s,e)=>{await l("/api/clients/assignedClients",{ConfigurationName:s,Peer:e},a=>{d.value=a.data})};return{assignments:d,getAssignedClients:u,getClients:w,getClientsRaw:y,clients:o,unassignClient:async(s,e,a)=>{g.value=!0,await v("/api/clients/unassignClient",{AssignmentID:a},async t=>{t.status?(i.newMessage("Server","Unassign successfully!","success"),s&&e&&await u(s,e)):(i.newMessage("Server","Unassign Failed. Reason: "+t.message,"success"),console.error("Unassign Failed. Reason: "+t.message)),g.value=!1})},assignClient:async(s,e,a,t=!0)=>{r.value=a,await v("/api/clients/assignClient",{ConfigurationName:s,Peer:e,ClientID:a},async C=>{C.status?(i.newMessage("Server","Assign successfully!","success"),t&&await u(s,e)):(i.newMessage("Server","Assign Failed. Reason: "+C.message,"success"),console.error("Assign Failed. Reason: "+C.message)),r.value=""})},getClientById:m,unassigning:g,assigning:r,clientsRaw:c,allConfigurationsPeers:f,getAllConfigurationsPeers:async()=>{await l("/api/clients/allConfigurationsPeers",{},s=>{f.value=s.data})}}});export{b as D};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as r,c as i,b as o,w as e,k as l,j as a,l as _,S as u,h as d,f as t}from"./index-DXzxfcZW.js";const m={name:"configuration"},f={class:"mt-md-5 mt-3 text-body"};function p(h,k,x,w,$,v){const n=d("RouterView");return t(),i("div",f,[o(n,null,{default:e(({Component:s,route:c})=>[o(l,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(_(s),{key:c.path,class:"z-1"}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",p]]);export{B as default};
|
||||
import{_ as r,c as i,b as o,w as e,k as l,j as a,l as _,S as u,h as d,f as t}from"./index-DM7YJCOo.js";const m={name:"configuration"},f={class:"mt-md-5 mt-3 text-body"};function p(h,k,x,w,$,v){const n=d("RouterView");return t(),i("div",f,[o(n,null,{default:e(({Component:s,route:c})=>[o(l,{name:"fade2",mode:"out-in"},{default:e(()=>[(t(),a(u,null,{default:e(()=>[(t(),a(_(s),{key:c.path,class:"z-1"}))]),_:2},1024))]),_:2},1024)]),_:1})])}const B=r(m,[["render",p]]);export{B as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as f,c as i,a as t,b as u,h as w,d as k,m as x,y,n as p,t as v,z as _,D as m,W as b,A as S,f as n,r as D,q as $,F as W,i as V}from"./index-DXzxfcZW.js";import{L as C}from"./localeText-Dmcj5qqx.js";const F={name:"dashboardSettingsInputWireguardConfigurationPath",components:{LocaleText:C},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const o=m(),s=b(),r=`input_${S()}`;return{store:o,uuid:r,WireguardConfigurationStore:s}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Server[this.targetData]},methods:{async useValidation(){this.changed&&(this.updating=!0,await _("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},o=>{o.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3),this.WireguardConfigurationStore.getConfigurations(),this.store.newMessage("Server","WireGuard configuration path saved","success")):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=o.message),this.changed=!1,this.updating=!1}))}}},I={class:"card"},T={class:"card-header"},A={class:"my-2"},L={class:"card-body"},M={class:"form-group"},N=["for"],P={class:"d-flex gap-2 align-items-start"},B={class:"flex-grow-1"},G=["id","disabled"],z={class:"invalid-feedback fw-bold"},U=["disabled"],q={key:0,class:"bi bi-save2-fill"},E={key:1,class:"spinner-border spinner-border-sm"},K={key:0,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1 mb-2"};function j(o,s,r,a,c,g){const d=w("LocaleText");return n(),i("div",I,[t("div",T,[t("h6",A,[u(d,{t:"Path"})])]),t("div",L,[t("div",M,[t("label",{for:this.uuid,class:"text-muted mb-1"},[t("strong",null,[t("small",null,[u(d,{t:this.title},null,8,["t"])])])],8,N),t("div",P,[t("div",B,[x(t("input",{type:"text",class:p(["form-control rounded-3",{"is-invalid":this.showInvalidFeedback,"is-valid":this.isValid}]),id:this.uuid,"onUpdate:modelValue":s[0]||(s[0]=e=>this.value=e),onKeydown:s[1]||(s[1]=e=>this.changed=!0),disabled:this.updating},null,42,G),[[y,this.value]]),t("div",z,v(this.invalidFeedback),1)]),t("button",{onClick:s[2]||(s[2]=e=>this.useValidation()),disabled:!this.changed,class:"ms-auto btn rounded-3 border-success-subtle bg-success-subtle text-success-emphasis"},[this.updating?(n(),i("span",E)):(n(),i("i",q))],8,U)]),r.warning?(n(),i("div",K,[t("small",null,[s[3]||(s[3]=t("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),u(d,{t:r.warningText},null,8,["t"])])])):k("",!0)])])])}const et=f(F,[["render",j]]),H={class:"card rounded-3"},J={class:"card-header"},O={class:"my-2"},Q={class:"card-body d-flex gap-2"},R={class:"list-group w-100"},X=["onClick"],Y={__name:"dashboardSettingsWireguardConfigurationAutostart",setup(o){const s=m(),r=b(),a=D(s.Configuration.WireGuardConfiguration.autostart),c=$(()=>r.Configurations.map(e=>e.Name)),g=async()=>{await _("/api/updateDashboardConfigurationItem",{section:"WireGuardConfiguration",key:"autostart",value:a.value},async e=>{e.status?(s.newMessage("Server","Start up configurations saved","success"),a.value=e.data):s.newMessage("Server","Start up configurations failed to save","danger")})},d=e=>{a.value.includes(e)?a.value=a.value.filter(h=>h!==e):a.value.push(e),g()};return(e,h)=>(n(),i("div",H,[t("div",J,[t("h6",O,[u(C,{t:"Toggle When Start Up"})])]),t("div",Q,[t("div",R,[(n(!0),i(W,null,V(c.value,l=>(n(),i("button",{type:"button",key:l,onClick:Z=>d(l),class:"list-group-item list-group-item-action py-2 w-100 d-flex align-items-center"},[t("samp",null,v(l),1),t("i",{class:p(["ms-auto",[a.value.includes(l)?"bi-check-circle-fill":"bi-circle"]])},null,2)],8,X))),128))])])]))}},at=f(Y,[["__scopeId","data-v-4aa2aed9"]]);export{et as D,at as a};
|
||||
import{_ as f,c as i,a as t,b as u,h as w,d as k,m as x,y,n as p,t as v,z as _,D as m,W as b,A as S,f as n,r as D,q as $,F as W,i as V}from"./index-DM7YJCOo.js";import{L as C}from"./localeText-BJvnc1lF.js";const F={name:"dashboardSettingsInputWireguardConfigurationPath",components:{LocaleText:C},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const o=m(),s=b(),r=`input_${S()}`;return{store:o,uuid:r,WireguardConfigurationStore:s}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Server[this.targetData]},methods:{async useValidation(){this.changed&&(this.updating=!0,await _("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},o=>{o.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3),this.WireguardConfigurationStore.getConfigurations(),this.store.newMessage("Server","WireGuard configuration path saved","success")):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=o.message),this.changed=!1,this.updating=!1}))}}},I={class:"card"},T={class:"card-header"},A={class:"my-2"},L={class:"card-body"},M={class:"form-group"},N=["for"],P={class:"d-flex gap-2 align-items-start"},B={class:"flex-grow-1"},G=["id","disabled"],z={class:"invalid-feedback fw-bold"},U=["disabled"],q={key:0,class:"bi bi-save2-fill"},E={key:1,class:"spinner-border spinner-border-sm"},K={key:0,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1 mb-2"};function j(o,s,r,a,c,g){const d=w("LocaleText");return n(),i("div",I,[t("div",T,[t("h6",A,[u(d,{t:"Path"})])]),t("div",L,[t("div",M,[t("label",{for:this.uuid,class:"text-muted mb-1"},[t("strong",null,[t("small",null,[u(d,{t:this.title},null,8,["t"])])])],8,N),t("div",P,[t("div",B,[x(t("input",{type:"text",class:p(["form-control rounded-3",{"is-invalid":this.showInvalidFeedback,"is-valid":this.isValid}]),id:this.uuid,"onUpdate:modelValue":s[0]||(s[0]=e=>this.value=e),onKeydown:s[1]||(s[1]=e=>this.changed=!0),disabled:this.updating},null,42,G),[[y,this.value]]),t("div",z,v(this.invalidFeedback),1)]),t("button",{onClick:s[2]||(s[2]=e=>this.useValidation()),disabled:!this.changed,class:"ms-auto btn rounded-3 border-success-subtle bg-success-subtle text-success-emphasis"},[this.updating?(n(),i("span",E)):(n(),i("i",q))],8,U)]),r.warning?(n(),i("div",K,[t("small",null,[s[3]||(s[3]=t("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),u(d,{t:r.warningText},null,8,["t"])])])):k("",!0)])])])}const et=f(F,[["render",j]]),H={class:"card rounded-3"},J={class:"card-header"},O={class:"my-2"},Q={class:"card-body d-flex gap-2"},R={class:"list-group w-100"},X=["onClick"],Y={__name:"dashboardSettingsWireguardConfigurationAutostart",setup(o){const s=m(),r=b(),a=D(s.Configuration.WireGuardConfiguration.autostart),c=$(()=>r.Configurations.map(e=>e.Name)),g=async()=>{await _("/api/updateDashboardConfigurationItem",{section:"WireGuardConfiguration",key:"autostart",value:a.value},async e=>{e.status?(s.newMessage("Server","Start up configurations saved","success"),a.value=e.data):s.newMessage("Server","Start up configurations failed to save","danger")})},d=e=>{a.value.includes(e)?a.value=a.value.filter(h=>h!==e):a.value.push(e),g()};return(e,h)=>(n(),i("div",H,[t("div",J,[t("h6",O,[u(C,{t:"Toggle When Start Up"})])]),t("div",Q,[t("div",R,[(n(!0),i(W,null,V(c.value,l=>(n(),i("button",{type:"button",key:l,onClick:Z=>d(l),class:"list-group-item list-group-item-action py-2 w-100 d-flex align-items-center"},[t("samp",null,v(l),1),t("i",{class:p(["ms-auto",[a.value.includes(l)?"bi-check-circle-fill":"bi-circle"]])},null,2)],8,X))),128))])])]))}},at=f(Y,[["__scopeId","data-v-4aa2aed9"]]);export{et as D,at as a};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
import{_ as O,J,W as Y,o as z,H as q,D as M,r as y,K as G,c as h,f as v,a as e,b as s,m as k,y as $,n as B,z as L,t as P,h as Q,a2 as X,d as N,s as D,j as R,F as I,i as H,I as ee,a3 as te,e as V,L as A,E as se,u as K,g as T,p as ne,q as oe,w as U,k as j,a4 as le,T as Z,B as ie,v as ae}from"./index-DXzxfcZW.js";import{L as n}from"./localeText-Dmcj5qqx.js";import{d as de}from"./dayjs.min-C-brjxlJ.js";const re={class:"card rounded-3 flex-grow-1 bg-danger-subtle border-danger-subtle border shadow"},ue={class:"card-body"},ce={class:"d-flex align-items-center gap-3 inputGroup"},me=["value"],fe={class:"mb-0"},ge={class:"d-flex mt-3"},be=["disabled"],ve={__name:"updateConfigurationName",props:{configurationName:String},emits:["close"],setup(d,{emit:r}){const t=d,f=r,o=J({data:"",valid:!1}),g=Y();z(()=>{q(()=>o.data,b=>{o.valid=/^[a-zA-Z0-9_=+.-]{1,15}$/.test(b)&&b.length>0&&!g.Configurations.find(_=>_.Name===b)})});const u=M(),x=y(!1),c=G(),a=async()=>{o.data&&(x.value=!0,clearInterval(u.Peers.RefreshInterval),await L("/api/renameWireguardConfiguration",{ConfigurationName:t.configurationName,NewConfigurationName:o.data},async b=>{b.status?(await g.getConfigurations(),u.newMessage("Server","Configuration renamed","success"),c.push(`/configuration/${o.data}/peers`)):(u.newMessage("Server",b.message,"danger"),x.value=!1)}))};return(b,_)=>(v(),h("div",re,[e("div",ue,[e("p",null,[s(n,{t:"To update this configuration's name, WGDashboard will execute the following operations:"})]),e("ol",null,[e("li",null,[s(n,{t:"Duplicate current configuration's database table and .conf file with the new name"})]),e("li",null,[s(n,{t:"Delete current configuration's database table and .conf file"})])]),e("div",ce,[e("input",{class:"form-control form-control-sm rounded-3",value:d.configurationName,disabled:""},null,8,me),_[3]||(_[3]=e("h3",{class:"mb-0"},[e("i",{class:"bi bi-arrow-right"})],-1)),k(e("input",{class:B(["form-control form-control-sm rounded-3",[o.data?o.valid?"is-valid":"is-invalid":""]]),id:"newConfigurationName","onUpdate:modelValue":_[0]||(_[0]=w=>o.data=w)},null,2),[[$,o.data]])]),e("div",{class:B(["invalid-feedback",{"d-block":!o.valid&&o.data}])},[s(n,{t:"Configuration name is invalid. Possible reasons:"}),e("ul",fe,[e("li",null,[s(n,{t:"Configuration name already exist"})]),e("li",null,[s(n,{t:"Configuration name can only contain 15 lower/uppercase alphabet, numbers, underscore, equal sign, plus sign, period and hyphen."})])])],2),e("div",ge,[e("button",{onClick:_[1]||(_[1]=w=>f("close")),class:"btn btn-sm bg-secondary-subtle border-secondary-subtle text-secondary-emphasis rounded-3"},[s(n,{t:"Cancel"})]),e("button",{onClick:_[2]||(_[2]=w=>a()),disabled:!o.data||x.value,class:"btn btn-sm btn-danger rounded-3 ms-auto"},[s(n,{t:"Save"})],8,be)])])]))}},pe=O(ve,[["__scopeId","data-v-33ea9576"]]),he={name:"Dropdown",props:{width:{type:String,default:"80px"},height:{type:String,default:"auto"},title:{type:String,default:""},disabled:{type:Boolean,default:!1},defaultDisplay:{type:Boolean,default:!1}}},ye={class:"title"};function xe(d,r,t,f,o,g){return v(),h("div",{class:B(["dropdown",{disabled:t.disabled}]),onClick:r[0]||(r[0]=(...u)=>d.toggleDropdown&&d.toggleDropdown(...u)),onFocusout:r[1]||(r[1]=(...u)=>d.hideDropdown&&d.hideDropdown(...u)),tabindex:"0"},[e("div",ye,[e("div",null,P(t.title),1)])],34)}const _e=O(he,[["render",xe]]),we={components:{Dropdown:_e},name:"CodeEditor",props:{lineNums:{type:Boolean,default:!1},modelValue:{type:String},value:{type:String},theme:{type:String,default:"github-dark"},tabSpaces:{type:Number,default:2},wrap:{type:Boolean,default:!1},readOnly:{type:Boolean,default:!1},autofocus:{type:Boolean,default:!1},header:{type:Boolean,default:!0},width:{type:String,default:"540px"},height:{type:String,default:"auto"},maxWidth:{type:String},minWidth:{type:String},maxHeight:{type:String},minHeight:{type:String},borderRadius:{type:String,default:"12px"},languages:{type:Array,default:function(){return[["javascript","JS"]]}},langListWidth:{type:String,default:"110px"},langListHeight:{type:String,default:"auto"},langListDisplay:{type:Boolean,default:!1},displayLanguage:{type:Boolean,default:!0},zIndex:{type:String,default:"0"},fontSize:{type:String,default:"17px"},padding:{type:String,default:"20px"}},directives:{highlight:{mounted(d,r){d.textContent=r.value},updated(d,r){d.scrolling?d.scrolling=!1:d.textContent=r.value}}},data(){return{scrollBarWidth:0,scrollBarHeight:0,top:0,left:0,languageClass:"hljs language-"+this.languages[0][0],languageTitle:this.languages[0][1]?this.languages[0][1]:this.languages[0][0],content:this.value,cursorPosition:0,insertTab:!1,lineNum:0,lineNumsWidth:0,scrolling:!1,textareaHeight:0,showLineNums:this.wrap?!1:this.lineNums}},computed:{tabWidth(){let d="";for(let r=0;r<this.tabSpaces;r++)d+=" ";return d},contentValue(){return this.modelValue==null?this.content+`
|
||||
import{_ as O,J,W as Y,o as z,H as q,D as M,r as y,K as G,c as h,f as v,a as e,b as s,m as k,y as $,n as B,z as L,t as P,h as Q,a2 as X,d as N,s as D,j as R,F as I,i as H,I as ee,a3 as te,e as V,L as A,E as se,u as K,g as T,p as ne,q as oe,w as U,k as j,a4 as le,T as Z,B as ie,v as ae}from"./index-DM7YJCOo.js";import{L as n}from"./localeText-BJvnc1lF.js";import{d as de}from"./dayjs.min-DZl6XMNW.js";const re={class:"card rounded-3 flex-grow-1 bg-danger-subtle border-danger-subtle border shadow"},ue={class:"card-body"},ce={class:"d-flex align-items-center gap-3 inputGroup"},me=["value"],fe={class:"mb-0"},ge={class:"d-flex mt-3"},be=["disabled"],ve={__name:"updateConfigurationName",props:{configurationName:String},emits:["close"],setup(d,{emit:r}){const t=d,f=r,o=J({data:"",valid:!1}),g=Y();z(()=>{q(()=>o.data,b=>{o.valid=/^[a-zA-Z0-9_=+.-]{1,15}$/.test(b)&&b.length>0&&!g.Configurations.find(_=>_.Name===b)})});const u=M(),x=y(!1),c=G(),a=async()=>{o.data&&(x.value=!0,clearInterval(u.Peers.RefreshInterval),await L("/api/renameWireguardConfiguration",{ConfigurationName:t.configurationName,NewConfigurationName:o.data},async b=>{b.status?(await g.getConfigurations(),u.newMessage("Server","Configuration renamed","success"),c.push(`/configuration/${o.data}/peers`)):(u.newMessage("Server",b.message,"danger"),x.value=!1)}))};return(b,_)=>(v(),h("div",re,[e("div",ue,[e("p",null,[s(n,{t:"To update this configuration's name, WGDashboard will execute the following operations:"})]),e("ol",null,[e("li",null,[s(n,{t:"Duplicate current configuration's database table and .conf file with the new name"})]),e("li",null,[s(n,{t:"Delete current configuration's database table and .conf file"})])]),e("div",ce,[e("input",{class:"form-control form-control-sm rounded-3",value:d.configurationName,disabled:""},null,8,me),_[3]||(_[3]=e("h3",{class:"mb-0"},[e("i",{class:"bi bi-arrow-right"})],-1)),k(e("input",{class:B(["form-control form-control-sm rounded-3",[o.data?o.valid?"is-valid":"is-invalid":""]]),id:"newConfigurationName","onUpdate:modelValue":_[0]||(_[0]=w=>o.data=w)},null,2),[[$,o.data]])]),e("div",{class:B(["invalid-feedback",{"d-block":!o.valid&&o.data}])},[s(n,{t:"Configuration name is invalid. Possible reasons:"}),e("ul",fe,[e("li",null,[s(n,{t:"Configuration name already exist"})]),e("li",null,[s(n,{t:"Configuration name can only contain 15 lower/uppercase alphabet, numbers, underscore, equal sign, plus sign, period and hyphen."})])])],2),e("div",ge,[e("button",{onClick:_[1]||(_[1]=w=>f("close")),class:"btn btn-sm bg-secondary-subtle border-secondary-subtle text-secondary-emphasis rounded-3"},[s(n,{t:"Cancel"})]),e("button",{onClick:_[2]||(_[2]=w=>a()),disabled:!o.data||x.value,class:"btn btn-sm btn-danger rounded-3 ms-auto"},[s(n,{t:"Save"})],8,be)])])]))}},pe=O(ve,[["__scopeId","data-v-33ea9576"]]),he={name:"Dropdown",props:{width:{type:String,default:"80px"},height:{type:String,default:"auto"},title:{type:String,default:""},disabled:{type:Boolean,default:!1},defaultDisplay:{type:Boolean,default:!1}}},ye={class:"title"};function xe(d,r,t,f,o,g){return v(),h("div",{class:B(["dropdown",{disabled:t.disabled}]),onClick:r[0]||(r[0]=(...u)=>d.toggleDropdown&&d.toggleDropdown(...u)),onFocusout:r[1]||(r[1]=(...u)=>d.hideDropdown&&d.hideDropdown(...u)),tabindex:"0"},[e("div",ye,[e("div",null,P(t.title),1)])],34)}const _e=O(he,[["render",xe]]),we={components:{Dropdown:_e},name:"CodeEditor",props:{lineNums:{type:Boolean,default:!1},modelValue:{type:String},value:{type:String},theme:{type:String,default:"github-dark"},tabSpaces:{type:Number,default:2},wrap:{type:Boolean,default:!1},readOnly:{type:Boolean,default:!1},autofocus:{type:Boolean,default:!1},header:{type:Boolean,default:!0},width:{type:String,default:"540px"},height:{type:String,default:"auto"},maxWidth:{type:String},minWidth:{type:String},maxHeight:{type:String},minHeight:{type:String},borderRadius:{type:String,default:"12px"},languages:{type:Array,default:function(){return[["javascript","JS"]]}},langListWidth:{type:String,default:"110px"},langListHeight:{type:String,default:"auto"},langListDisplay:{type:Boolean,default:!1},displayLanguage:{type:Boolean,default:!0},zIndex:{type:String,default:"0"},fontSize:{type:String,default:"17px"},padding:{type:String,default:"20px"}},directives:{highlight:{mounted(d,r){d.textContent=r.value},updated(d,r){d.scrolling?d.scrolling=!1:d.textContent=r.value}}},data(){return{scrollBarWidth:0,scrollBarHeight:0,top:0,left:0,languageClass:"hljs language-"+this.languages[0][0],languageTitle:this.languages[0][1]?this.languages[0][1]:this.languages[0][0],content:this.value,cursorPosition:0,insertTab:!1,lineNum:0,lineNumsWidth:0,scrolling:!1,textareaHeight:0,showLineNums:this.wrap?!1:this.lineNums}},computed:{tabWidth(){let d="";for(let r=0;r<this.tabSpaces;r++)d+=" ";return d},contentValue(){return this.modelValue==null?this.content+`
|
||||
`:this.modelValue+`
|
||||
`},scroll(){return this.height!="auto"}},methods:{updateValue(d){this.modelValue==null?this.content=d.target.value:this.$emit("update:modelValue",d.target.value)},changeLang(d){this.languageTitle=d[1]?d[1]:d[0],this.languageClass="language-"+d[0],this.$emit("lang",d[0])},tab(){if(document.execCommand("insertText"))document.execCommand("insertText",!1,this.tabWidth);else{const d=this.$refs.textarea.selectionStart;this.content=this.content.substring(0,d)+this.tabWidth+this.content.substring(d),this.cursorPosition=d+this.tabWidth.length,this.insertTab=!0}},calcScrollDistance(d){this.$refs.code.scrolling=!0,this.scrolling=!0,this.top=-d.target.scrollTop,this.left=-d.target.scrollLeft},resizer(){new ResizeObserver(t=>{this.scrollBarWidth=t[0].target.offsetWidth-t[0].target.clientWidth,this.scrollBarHeight=t[0].target.offsetHeight-t[0].target.clientHeight,this.textareaHeight=t[0].target.offsetHeight}).observe(this.$refs.textarea);const r=new ResizeObserver(t=>{this.lineNumsWidth=t[0].target.offsetWidth});this.$refs.lineNums&&r.observe(this.$refs.lineNums)},copy(){document.execCommand("copy")?(this.$refs.textarea.select(),document.execCommand("copy"),window.getSelection().removeAllRanges()):navigator.clipboard.writeText(this.$refs.textarea.value)},getLineNum(){const d=this.$refs.textarea.value;let r=0,t=d.indexOf(`
|
||||
`);for(;t!==-1;)r++,t=d.indexOf(`
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{H as I,q as w,P as S,J as k,Q as L,u as R}from"./index-DXzxfcZW.js";const W=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const X=Object.prototype.toString,Y=t=>X.call(t)==="[object Object]",$=()=>{};function C(t){return Array.isArray(t)?t:[t]}function q(t,a,r){return I(t,a,{...r,immediate:!0})}const O=W?window:void 0;function P(t){var a;const r=S(t);return(a=r?.$el)!==null&&a!==void 0?a:r}function T(...t){const a=(o,u,s,d)=>(o.addEventListener(u,s,d),()=>o.removeEventListener(u,s,d)),r=w(()=>{const o=C(S(t[0])).filter(u=>u!=null);return o.every(u=>typeof u!="string")?o:void 0});return q(()=>{var o,u;return[(o=(u=r.value)===null||u===void 0?void 0:u.map(s=>P(s)))!==null&&o!==void 0?o:[O].filter(s=>s!=null),C(S(r.value?t[1]:t[0])),C(R(r.value?t[2]:t[1])),S(r.value?t[3]:t[2])]},([o,u,s,d],p,c)=>{if(!o?.length||!u?.length||!s?.length)return;const f=Y(d)?{...d}:d,v=o.flatMap(b=>u.flatMap(h=>s.map(y=>a(b,h,y,f))));c(()=>{v.forEach(b=>b())})},{flush:"post"})}function B(t,a,r={}){const{window:o=O,ignore:u=[],capture:s=!0,detectIframe:d=!1,controls:p=!1}=r;if(!o)return p?{stop:$,cancel:$,trigger:$}:$;let c=!0;const f=e=>S(u).some(n=>{if(typeof n=="string")return Array.from(o.document.querySelectorAll(n)).some(i=>i===e.target||e.composedPath().includes(i));{const i=P(n);return i&&(e.target===i||e.composedPath().includes(i))}});function v(e){const n=S(e);return n&&n.$.subTree.shapeFlag===16}function b(e,n){const i=S(e),m=i.$.subTree&&i.$.subTree.children;return m==null||!Array.isArray(m)?!1:m.some(A=>A.el===n.target||n.composedPath().includes(A.el))}const h=e=>{const n=P(t);if(e.target!=null&&!(!(n instanceof Element)&&v(t)&&b(t,e))&&!(!n||n===e.target||e.composedPath().includes(n))){if("detail"in e&&e.detail===0&&(c=!f(e)),!c){c=!0;return}a(e)}};let y=!1;const E=[T(o,"click",e=>{y||(y=!0,setTimeout(()=>{y=!1},0),h(e))},{passive:!0,capture:s}),T(o,"pointerdown",e=>{const n=P(t);c=!f(e)&&!!(n&&!e.composedPath().includes(n))},{passive:!0}),d&&T(o,"blur",e=>{setTimeout(()=>{var n;const i=P(t);((n=o.document.activeElement)===null||n===void 0?void 0:n.tagName)==="IFRAME"&&!i?.contains(o.document.activeElement)&&a(e)},0)},{passive:!0})].filter(Boolean),x=()=>E.forEach(e=>e());return p?{stop:x,cancel:()=>{c=!1},trigger:e=>{c=!0,h(e),c=!1}}:x}function D(t,a={}){const{threshold:r=50,onSwipe:o,onSwipeEnd:u,onSwipeStart:s,passive:d=!0}=a,p=k({x:0,y:0}),c=k({x:0,y:0}),f=w(()=>p.x-c.x),v=w(()=>p.y-c.y),{max:b,abs:h}=Math,y=w(()=>b(h(f.value),h(v.value))>=r),E=L(!1),x=w(()=>y.value?h(f.value)>h(v.value)?f.value>0?"left":"right":v.value>0?"up":"down":"none"),e=l=>[l.touches[0].clientX,l.touches[0].clientY],n=(l,g)=>{p.x=l,p.y=g},i=(l,g)=>{c.x=l,c.y=g},m={passive:d,capture:!d},A=l=>{E.value&&u?.(l,x.value),E.value=!1},j=[T(t,"touchstart",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);n(g,M),i(g,M),s?.(l)},m),T(t,"touchmove",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);i(g,M),m.capture&&!m.passive&&Math.abs(f.value)>Math.abs(v.value)&&l.preventDefault(),!E.value&&y.value&&(E.value=!0),E.value&&o?.(l)},m),T(t,["touchend","touchcancel"],A,m)];return{isSwiping:E,direction:x,coordsStart:p,coordsEnd:c,lengthX:f,lengthY:v,stop:()=>j.forEach(l=>l())}}export{D as a,B as o,P as u};
|
||||
import{H as I,q as w,P as S,J as k,Q as L,u as R}from"./index-DM7YJCOo.js";const W=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const X=Object.prototype.toString,Y=t=>X.call(t)==="[object Object]",$=()=>{};function C(t){return Array.isArray(t)?t:[t]}function q(t,a,r){return I(t,a,{...r,immediate:!0})}const O=W?window:void 0;function P(t){var a;const r=S(t);return(a=r?.$el)!==null&&a!==void 0?a:r}function T(...t){const a=(o,u,s,d)=>(o.addEventListener(u,s,d),()=>o.removeEventListener(u,s,d)),r=w(()=>{const o=C(S(t[0])).filter(u=>u!=null);return o.every(u=>typeof u!="string")?o:void 0});return q(()=>{var o,u;return[(o=(u=r.value)===null||u===void 0?void 0:u.map(s=>P(s)))!==null&&o!==void 0?o:[O].filter(s=>s!=null),C(S(r.value?t[1]:t[0])),C(R(r.value?t[2]:t[1])),S(r.value?t[3]:t[2])]},([o,u,s,d],p,c)=>{if(!o?.length||!u?.length||!s?.length)return;const f=Y(d)?{...d}:d,v=o.flatMap(b=>u.flatMap(h=>s.map(y=>a(b,h,y,f))));c(()=>{v.forEach(b=>b())})},{flush:"post"})}function B(t,a,r={}){const{window:o=O,ignore:u=[],capture:s=!0,detectIframe:d=!1,controls:p=!1}=r;if(!o)return p?{stop:$,cancel:$,trigger:$}:$;let c=!0;const f=e=>S(u).some(n=>{if(typeof n=="string")return Array.from(o.document.querySelectorAll(n)).some(i=>i===e.target||e.composedPath().includes(i));{const i=P(n);return i&&(e.target===i||e.composedPath().includes(i))}});function v(e){const n=S(e);return n&&n.$.subTree.shapeFlag===16}function b(e,n){const i=S(e),m=i.$.subTree&&i.$.subTree.children;return m==null||!Array.isArray(m)?!1:m.some(A=>A.el===n.target||n.composedPath().includes(A.el))}const h=e=>{const n=P(t);if(e.target!=null&&!(!(n instanceof Element)&&v(t)&&b(t,e))&&!(!n||n===e.target||e.composedPath().includes(n))){if("detail"in e&&e.detail===0&&(c=!f(e)),!c){c=!0;return}a(e)}};let y=!1;const E=[T(o,"click",e=>{y||(y=!0,setTimeout(()=>{y=!1},0),h(e))},{passive:!0,capture:s}),T(o,"pointerdown",e=>{const n=P(t);c=!f(e)&&!!(n&&!e.composedPath().includes(n))},{passive:!0}),d&&T(o,"blur",e=>{setTimeout(()=>{var n;const i=P(t);((n=o.document.activeElement)===null||n===void 0?void 0:n.tagName)==="IFRAME"&&!i?.contains(o.document.activeElement)&&a(e)},0)},{passive:!0})].filter(Boolean),x=()=>E.forEach(e=>e());return p?{stop:x,cancel:()=>{c=!1},trigger:e=>{c=!0,h(e),c=!1}}:x}function D(t,a={}){const{threshold:r=50,onSwipe:o,onSwipeEnd:u,onSwipeStart:s,passive:d=!0}=a,p=k({x:0,y:0}),c=k({x:0,y:0}),f=w(()=>p.x-c.x),v=w(()=>p.y-c.y),{max:b,abs:h}=Math,y=w(()=>b(h(f.value),h(v.value))>=r),E=L(!1),x=w(()=>y.value?h(f.value)>h(v.value)?f.value>0?"left":"right":v.value>0?"up":"down":"none"),e=l=>[l.touches[0].clientX,l.touches[0].clientY],n=(l,g)=>{p.x=l,p.y=g},i=(l,g)=>{c.x=l,c.y=g},m={passive:d,capture:!d},A=l=>{E.value&&u?.(l,x.value),E.value=!1},j=[T(t,"touchstart",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);n(g,M),i(g,M),s?.(l)},m),T(t,"touchmove",l=>{if(l.touches.length!==1)return;const[g,M]=e(l);i(g,M),m.capture&&!m.passive&&Math.abs(f.value)>Math.abs(v.value)&&l.preventDefault(),!E.value&&y.value&&(E.value=!0),E.value&&o?.(l)},m),T(t,["touchend","touchcancel"],A,m)];return{isSwiping:E,direction:x,coordsStart:p,coordsEnd:c,lengthX:f,lengthY:v,stop:()=>j.forEach(l=>l())}}export{D as a,B as o,P as u};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as e,G as t,c as o,t as a,f as c}from"./index-DXzxfcZW.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return c(),o("span",null,a(this.getLocaleText),1)}const m=e(s,[["render",n]]);export{m as L};
|
||||
import{_ as e,G as t,c as o,t as a,f as c}from"./index-DM7YJCOo.js";const s={name:"localeText",props:{t:""},computed:{getLocaleText(){return t(this.t)}}};function n(r,p,l,_,i,x){return c(),o("span",null,a(this.getLocaleText),1)}const m=e(s,[["render",n]]);export{m as L};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{L as l}from"./localeText-Dmcj5qqx.js";import{d as c}from"./dayjs.min-C-brjxlJ.js";import{_ as h,c as o,a as e,b as a,w as u,e as p,h as g,t as i,k as f,n as _,f as n}from"./index-DXzxfcZW.js";const x={name:"message",methods:{dayjs:c,hide(){this.ct(),this.message.show=!1},show(){this.timeout=setTimeout(()=>{this.message.show=!1},5e3)},ct(){clearTimeout(this.timeout)}},components:{LocaleText:l},props:{message:Object},mounted(){this.show()},data(){return{dismiss:!1,timeout:null}}},v=["id"],b={key:0,class:"d-flex"},w={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},y={class:"ms-auto"},k={key:1},T={class:"card-body d-flex align-items-center gap-3"};function M(C,s,L,j,t,m){const d=g("LocaleText");return n(),o("div",{onMouseenter:s[1]||(s[1]=r=>{t.dismiss=!0,this.ct()}),onMouseleave:s[2]||(s[2]=r=>{t.dismiss=!1,this.show()}),class:"card shadow rounded-3 position-relative message ms-auto",id:this.message.id},[e("div",{class:_([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[a(f,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(n(),o("div",k,[e("small",{onClick:s[0]||(s[0]=r=>m.hide()),class:"d-block mx-auto w-100 text-center",style:{cursor:"pointer"}},[s[3]||(s[3]=e("i",{class:"bi bi-x-lg me-2"},null,-1)),a(d,{t:"Dismiss"})])])):(n(),o("div",b,[e("small",w,[a(d,{t:"FROM "}),p(" "+i(this.message.from),1)]),e("small",y,i(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,i(this.message.content),1)])],40,v)}const z=h(x,[["render",M],["__scopeId","data-v-94c76b54"]]);export{z as M};
|
||||
import{L as l}from"./localeText-BJvnc1lF.js";import{d as c}from"./dayjs.min-DZl6XMNW.js";import{_ as h,c as o,a as e,b as a,w as u,e as p,h as g,t as i,k as f,n as _,f as n}from"./index-DM7YJCOo.js";const x={name:"message",methods:{dayjs:c,hide(){this.ct(),this.message.show=!1},show(){this.timeout=setTimeout(()=>{this.message.show=!1},5e3)},ct(){clearTimeout(this.timeout)}},components:{LocaleText:l},props:{message:Object},mounted(){this.show()},data(){return{dismiss:!1,timeout:null}}},v=["id"],b={key:0,class:"d-flex"},w={class:"fw-bold d-block",style:{"text-transform":"uppercase"}},y={class:"ms-auto"},k={key:1},T={class:"card-body d-flex align-items-center gap-3"};function M(C,s,L,j,t,m){const d=g("LocaleText");return n(),o("div",{onMouseenter:s[1]||(s[1]=r=>{t.dismiss=!0,this.ct()}),onMouseleave:s[2]||(s[2]=r=>{t.dismiss=!1,this.show()}),class:"card shadow rounded-3 position-relative message ms-auto",id:this.message.id},[e("div",{class:_([{"text-bg-danger":this.message.type==="danger","text-bg-success":this.message.type==="success","text-bg-warning":this.message.type==="warning"},"card-header pos"])},[a(f,{name:"zoom",mode:"out-in"},{default:u(()=>[t.dismiss?(n(),o("div",k,[e("small",{onClick:s[0]||(s[0]=r=>m.hide()),class:"d-block mx-auto w-100 text-center",style:{cursor:"pointer"}},[s[3]||(s[3]=e("i",{class:"bi bi-x-lg me-2"},null,-1)),a(d,{t:"Dismiss"})])])):(n(),o("div",b,[e("small",w,[a(d,{t:"FROM "}),p(" "+i(this.message.from),1)]),e("small",y,i(m.dayjs().format("hh:mm A")),1)]))]),_:1})],2),e("div",T,[e("div",null,i(this.message.content),1)])],40,v)}const z=h(x,[["render",M],["__scopeId","data-v-94c76b54"]]);export{z as M};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{S as C,e as y,c as w,m as _,a as L,f as S,l as v,i as M,b as k,d as x,g as A,h as F,j as R,M as D,V as P,T as b,k as l,O as E,n as O,F as h,P as f,o as T,p as c,C as V,q as u,r as X}from"./Vector-CuSZivra.js";import{_ as Y,D as G,c as $,d as j,f as q}from"./index-DXzxfcZW.js";class r extends C{constructor(t,e){super(),this.flatMidpoint_=null,this.flatMidpointRevision_=-1,this.maxDelta_=-1,this.maxDeltaRevision_=-1,e!==void 0&&!Array.isArray(t[0])?this.setFlatCoordinates(e,t):this.setCoordinates(t,e)}appendCoordinate(t){y(this.flatCoordinates,t),this.changed()}clone(){const t=new r(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t}closestPointXY(t,e,o,n){return n<w(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(_(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),L(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,this.maxDelta_,!1,t,e,o,n))}forEachSegment(t){return S(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)}getCoordinateAtM(t,e){return this.layout!="XYM"&&this.layout!="XYZM"?null:(e=e!==void 0?e:!1,v(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e))}getCoordinates(){return M(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getCoordinateAt(t,e){return k(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,this.stride)}getLength(){return x(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getFlatMidpoint(){return this.flatMidpointRevision_!=this.getRevision()&&(this.flatMidpoint_=this.getCoordinateAt(.5,this.flatMidpoint_??void 0),this.flatMidpointRevision_=this.getRevision()),this.flatMidpoint_}getSimplifiedGeometryInternal(t){const e=[];return e.length=A(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,0),new r(e,"XY")}getType(){return"LineString"}intersectsExtent(t){return F(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,this.getExtent())}setCoordinates(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=R(this.flatCoordinates,0,t,this.stride),this.changed()}}const B={name:"osmap",props:{type:"",d:Object||Array},data(){return{osmAvailable:!0}},setup(){return{store:G()}},methods:{getLastLonLat(){if(this.type==="traceroute"){const i=this.d.findLast(t=>t.geo&&t.geo.lat&&t.geo.lon);return i?[i.geo.lon,i.geo.lat]:[0,0]}return[this.d.geo.lon,this.d.geo.lat]}},async mounted(){await fetch("https://tile.openstreetmap.org/",{signal:AbortSignal.timeout(1500)}).then(i=>{const t=new D({target:"map",layers:[new b({source:new E})],view:new P({center:l(this.getLastLonLat()),zoom:this.type==="traceroute"?3:10})}),e=[],o=new O;if(this.type==="traceroute")this.d.forEach(s=>{if(s.geo&&s.geo.lat&&s.geo.lon){const a=l([s.geo.lon,s.geo.lat]);e.push(a);const g=this.getLastLonLat(),m=new h({geometry:new f(a),last:s.geo.lon===g[0]&&s.geo.lat===g[1]});o.addFeature(m)}});else{const s=l([this.d.geo.lon,this.d.geo.lat]);e.push(s);const a=new h({geometry:new f(s)});o.addFeature(a)}const n=new r(e),d=new h({geometry:n});o.addFeature(d);const p=new T({source:o,style:function(s){if(s.getGeometry().getType()==="Point")return new c({image:new V({radius:10,fill:new X({color:s.get("last")?"#dc3545":"#0d6efd"}),stroke:new u({color:"white",width:5})})});if(s.getGeometry().getType()==="LineString")return new c({stroke:new u({color:"#0d6efd",width:2})})}});t.addLayer(p)}).catch(i=>{this.osmAvailable=!1})}},z={key:0,id:"map",class:"w-100 rounded-3"};function I(i,t,e,o,n,d){return this.osmAvailable?(q(),$("div",z)):j("",!0)}const H=Y(B,[["render",I]]);export{H as O};
|
||||
import{S as C,e as y,c as w,m as _,a as L,f as S,l as v,i as M,b as k,d as x,g as A,h as F,j as R,M as D,V as P,T as b,k as l,O as E,n as O,F as h,P as f,o as T,p as c,C as V,q as u,r as X}from"./Vector-CuSZivra.js";import{_ as Y,D as G,c as $,d as j,f as q}from"./index-DM7YJCOo.js";class r extends C{constructor(t,e){super(),this.flatMidpoint_=null,this.flatMidpointRevision_=-1,this.maxDelta_=-1,this.maxDeltaRevision_=-1,e!==void 0&&!Array.isArray(t[0])?this.setFlatCoordinates(e,t):this.setCoordinates(t,e)}appendCoordinate(t){y(this.flatCoordinates,t),this.changed()}clone(){const t=new r(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t}closestPointXY(t,e,o,n){return n<w(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(_(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),L(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,this.maxDelta_,!1,t,e,o,n))}forEachSegment(t){return S(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)}getCoordinateAtM(t,e){return this.layout!="XYM"&&this.layout!="XYZM"?null:(e=e!==void 0?e:!1,v(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e))}getCoordinates(){return M(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getCoordinateAt(t,e){return k(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,this.stride)}getLength(){return x(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)}getFlatMidpoint(){return this.flatMidpointRevision_!=this.getRevision()&&(this.flatMidpoint_=this.getCoordinateAt(.5,this.flatMidpoint_??void 0),this.flatMidpointRevision_=this.getRevision()),this.flatMidpoint_}getSimplifiedGeometryInternal(t){const e=[];return e.length=A(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,0),new r(e,"XY")}getType(){return"LineString"}intersectsExtent(t){return F(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,this.getExtent())}setCoordinates(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=R(this.flatCoordinates,0,t,this.stride),this.changed()}}const B={name:"osmap",props:{type:"",d:Object||Array},data(){return{osmAvailable:!0}},setup(){return{store:G()}},methods:{getLastLonLat(){if(this.type==="traceroute"){const i=this.d.findLast(t=>t.geo&&t.geo.lat&&t.geo.lon);return i?[i.geo.lon,i.geo.lat]:[0,0]}return[this.d.geo.lon,this.d.geo.lat]}},async mounted(){await fetch("https://tile.openstreetmap.org/",{signal:AbortSignal.timeout(1500)}).then(i=>{const t=new D({target:"map",layers:[new b({source:new E})],view:new P({center:l(this.getLastLonLat()),zoom:this.type==="traceroute"?3:10})}),e=[],o=new O;if(this.type==="traceroute")this.d.forEach(s=>{if(s.geo&&s.geo.lat&&s.geo.lon){const a=l([s.geo.lon,s.geo.lat]);e.push(a);const g=this.getLastLonLat(),m=new h({geometry:new f(a),last:s.geo.lon===g[0]&&s.geo.lat===g[1]});o.addFeature(m)}});else{const s=l([this.d.geo.lon,this.d.geo.lat]);e.push(s);const a=new h({geometry:new f(s)});o.addFeature(a)}const n=new r(e),d=new h({geometry:n});o.addFeature(d);const p=new T({source:o,style:function(s){if(s.getGeometry().getType()==="Point")return new c({image:new V({radius:10,fill:new X({color:s.get("last")?"#dc3545":"#0d6efd"}),stroke:new u({color:"white",width:5})})});if(s.getGeometry().getType()==="LineString")return new c({stroke:new u({color:"#0d6efd",width:2})})}});t.addLayer(p)}).catch(i=>{this.osmAvailable=!1})}},z={key:0,id:"map",class:"w-100 rounded-3"};function I(i,t,e,o,n,d){return this.osmAvailable?(q(),$("div",z)):j("",!0)}const H=Y(B,[["render",I]]);export{H as O};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as v,D as g,r as o,o as h,L as x,g as y,c as i,f as n,a as s,b as c,d as w,n as C,w as k,k as F}from"./index-DXzxfcZW.js";import{L as T}from"./localeText-Dmcj5qqx.js";import"./browser-DFwZaPoQ.js";import"./galois-field-I2lBzzs-.js";const M={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},S={class:"container d-flex h-100 w-100"},D={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},L={class:"card rounded-3 shadow w-100"},P={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},B={class:"mb-0"},G={class:"card-body p-4 d-flex flex-column gap-3"},N={style:{height:"300px"},class:"d-flex"},V=["value"],j={key:0,class:"spinner-border m-auto",role:"status"},I={class:"d-flex"},W=["disabled"],$={key:0,class:"d-block"},q={key:1,class:"d-block",id:"check"},z={__name:"peerConfigurationFile",props:{selectedPeer:Object},emits:["close"],setup(u,{emit:p}){const m=p,f=u,r=g(),t=o(!1),l=o(""),a=o(!0);o({error:!1,message:void 0}),h(()=>{const d=x();y("/api/downloadPeer/"+d.params.id,{id:f.selectedPeer.id},e=>{e.status?(l.value=e.data.file,a.value=!1):this.dashboardStore.newMessage("Server",e.message,"danger")})});const b=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(l.value).then(()=>{t.value=!0,setTimeout(()=>{t.value=!1},3e3)}).catch(()=>{r.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(t.value=!0,setTimeout(()=>{t.value=!1},3e3)):r.newMessage("WGDashboard","Failed to copy","danger"))};return(d,e)=>(n(),i("div",M,[s("div",S,[s("div",D,[s("div",L,[s("div",P,[s("h4",B,[c(T,{t:"Peer Configuration File"})]),s("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=_=>m("close"))})]),s("div",G,[s("div",N,[s("textarea",{style:{height:"300px"},class:C(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,V),a.value?(n(),i("div",j,[...e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)])])):w("",!0)]),s("div",I,[s("button",{onClick:e[1]||(e[1]=_=>b()),disabled:t.value||a.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[c(F,{name:"slide-up",mode:"out-in"},{default:k(()=>[t.value?(n(),i("span",q,[...e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)])])):(n(),i("span",$,[...e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])]))]),_:1})],8,W)])])])])])]))}},H=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{H as default};
|
||||
import{_ as v,D as g,r as o,o as h,L as x,g as y,c as i,f as n,a as s,b as c,d as w,n as C,w as k,k as F}from"./index-DM7YJCOo.js";import{L as T}from"./localeText-BJvnc1lF.js";import"./browser-CUYUHo3j.js";import"./galois-field-I2lBzzs-.js";const M={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},S={class:"container d-flex h-100 w-100"},D={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},L={class:"card rounded-3 shadow w-100"},P={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},B={class:"mb-0"},G={class:"card-body p-4 d-flex flex-column gap-3"},N={style:{height:"300px"},class:"d-flex"},V=["value"],j={key:0,class:"spinner-border m-auto",role:"status"},I={class:"d-flex"},W=["disabled"],$={key:0,class:"d-block"},q={key:1,class:"d-block",id:"check"},z={__name:"peerConfigurationFile",props:{selectedPeer:Object},emits:["close"],setup(u,{emit:p}){const m=p,f=u,r=g(),t=o(!1),l=o(""),a=o(!0);o({error:!1,message:void 0}),h(()=>{const d=x();y("/api/downloadPeer/"+d.params.id,{id:f.selectedPeer.id},e=>{e.status?(l.value=e.data.file,a.value=!1):this.dashboardStore.newMessage("Server",e.message,"danger")})});const b=async()=>{navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(l.value).then(()=>{t.value=!0,setTimeout(()=>{t.value=!1},3e3)}).catch(()=>{r.newMessage("WGDashboard","Failed to copy","danger")}):(document.querySelector("#peerConfigurationFile").select(),document.execCommand("copy")?(t.value=!0,setTimeout(()=>{t.value=!1},3e3)):r.newMessage("WGDashboard","Failed to copy","danger"))};return(d,e)=>(n(),i("div",M,[s("div",S,[s("div",D,[s("div",L,[s("div",P,[s("h4",B,[c(T,{t:"Peer Configuration File"})]),s("button",{type:"button",class:"btn-close ms-auto",onClick:e[0]||(e[0]=_=>m("close"))})]),s("div",G,[s("div",N,[s("textarea",{style:{height:"300px"},class:C(["form-control w-100 rounded-3 animate__fadeIn animate__faster animate__animated",{"d-none":a.value}]),id:"peerConfigurationFile",value:l.value},null,10,V),a.value?(n(),i("div",j,[...e[2]||(e[2]=[s("span",{class:"visually-hidden"},"Loading...",-1)])])):w("",!0)]),s("div",I,[s("button",{onClick:e[1]||(e[1]=_=>b()),disabled:t.value||a.value,class:"ms-auto btn bg-primary-subtle border-primary-subtle text-primary-emphasis rounded-3 position-relative"},[c(F,{name:"slide-up",mode:"out-in"},{default:k(()=>[t.value?(n(),i("span",q,[...e[4]||(e[4]=[s("i",{class:"bi bi-check-circle-fill"},null,-1)])])):(n(),i("span",$,[...e[3]||(e[3]=[s("i",{class:"bi bi-clipboard-fill"},null,-1)])]))]),_:1})],8,W)])])])])])]))}},H=v(z,[["__scopeId","data-v-b0ea2d46"]]);export{H as default};
|
||||
@@ -1 +0,0 @@
|
||||
import{L as o}from"./localeText-Dmcj5qqx.js";import{P as t}from"./peersDefaultSettingsInput-KXSGcg6g.js";import{B as s,c as l,a,b as e,f as n}from"./index-DXzxfcZW.js";const r={class:"d-flex gap-3 flex-column"},i={class:"card rounded-3"},d={class:"card-header"},c={class:"my-2"},_={class:"card-body"},D=s({__name:"peerDefaultSettings",setup(p){return(g,m)=>(n(),l("div",r,[a("div",i,[a("div",d,[a("h6",c,[e(o,{t:"Peer Default Settings"})])]),a("div",_,[a("div",null,[e(t,{targetData:"peer_global_dns",title:"DNS"}),e(t,{targetData:"peer_endpoint_allowed_ip",title:"Endpoint Allowed IPs"}),e(t,{targetData:"peer_mtu",title:"MTU"}),e(t,{targetData:"peer_keep_alive",title:"Persistent Keepalive"}),e(t,{targetData:"remote_endpoint",title:"Peer Remote Endpoint",warning:!0,warningText:"This will be changed globally, and will be apply to all peer's QR code and configuration file."})])])])]))}});export{D as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{L as r}from"./localeText-BJvnc1lF.js";import{P as t}from"./peersDefaultSettingsInput-n69y01QP.js";import{B as l,c as o,a,b as e,f as s}from"./index-DM7YJCOo.js";const n={class:"d-flex gap-3 flex-column"},i={class:"card rounded-3"},d={class:"card-header"},_={class:"my-2"},c={class:"card-body"},D=l({__name:"peerDefaultSettings",setup(p){return(f,g)=>(s(),o("div",n,[a("div",i,[a("div",d,[a("h6",_,[e(r,{t:"Peer Default Settings"})])]),a("div",c,[a("div",null,[e(t,{targetData:"peer_global_dns",title:"DNS"}),e(t,{targetData:"peer_endpoint_allowed_ip",title:"Endpoint Allowed IPs"}),e(t,{targetData:"peer_mtu",title:"MTU"}),e(t,{targetData:"peer_keep_alive",title:"Persistent Keepalive"}),e(t,{targetData:"peer_preshared_key_default",title:"Pre-Shared Key Default"}),e(t,{targetData:"remote_endpoint",title:"Peer Remote Endpoint",warning:!0,warningText:"This will be changed globally, and will be apply to all peer's QR code and configuration file."})])])])]))}});export{D as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{a as p,S as b}from"./schedulePeerJob-DOBEE-kC.js";import{_ as h,h as i,c as a,f as s,a as e,b as r,w as u,d as m,F as _,i as f,j as v,T as J,A as x,W as g}from"./index-DXzxfcZW.js";import{L as w}from"./localeText-Dmcj5qqx.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";import"./dayjs.min-C-brjxlJ.js";const P={name:"peerJobs",setup(){return{store:g()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:b,ScheduleDropdown:p},data(){return{}},methods:{deleteJob(d){this.selectedPeer.jobs=this.selectedPeer.jobs.filter(t=>t.JobID!==d.JobID)},addJob(){this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({JobID:x().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},j={class:"mb-0 fw-normal"},k={class:"card-body px-4 pb-4 pt-2 position-relative"},T={class:"d-flex align-items-center mb-3"},N={class:"card shadow-sm",key:"none",style:{height:"153px"}},I={class:"card-body text-muted text-center d-flex"},L={class:"m-auto"};function O(d,t,B,F,V,A){const n=i("LocaleText"),l=i("SchedulePeerJob");return s(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",j,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=o=>this.$emit("close"))})]),e("div",k,[e("div",T,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow",onClick:t[1]||(t[1]=o=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(J,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:u(()=>[(s(!0),a(_,null,f(this.selectedPeer.jobs,(o,E)=>(s(),v(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(o),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:o.JobID,pjob:o},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(s(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):m("",!0)]),_:1})])])])])])}const H=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{H as default};
|
||||
import{a as p,S as b}from"./schedulePeerJob-jjF9HAtj.js";import{_ as h,h as i,c as a,f as s,a as e,b as r,w as u,d as m,F as _,i as f,j as v,T as J,A as x,W as g}from"./index-DM7YJCOo.js";import{L as w}from"./localeText-BJvnc1lF.js";import"./vue-datepicker-9N8DgATH.js";import"./index-i3npkoSo.js";import"./dayjs.min-DZl6XMNW.js";const P={name:"peerJobs",setup(){return{store:g()}},props:{selectedPeer:Object},components:{LocaleText:w,SchedulePeerJob:b,ScheduleDropdown:p},data(){return{}},methods:{deleteJob(d){this.selectedPeer.jobs=this.selectedPeer.jobs.filter(t=>t.JobID!==d.JobID)},addJob(){this.selectedPeer.jobs.unshift(JSON.parse(JSON.stringify({JobID:x().toString(),Configuration:this.selectedPeer.configuration.Name,Peer:this.selectedPeer.id,Field:this.store.PeerScheduleJobs.dropdowns.Field[0].value,Operator:this.store.PeerScheduleJobs.dropdowns.Operator[0].value,Value:"",CreationDate:"",ExpireDate:"",Action:this.store.PeerScheduleJobs.dropdowns.Action[0].value})))}}},S={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},y={class:"container d-flex h-100 w-100"},$={class:"m-auto modal-dialog-centered dashboardModal"},C={class:"card rounded-3 shadow",style:{width:"700px"}},D={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},j={class:"mb-0 fw-normal"},k={class:"card-body px-4 pb-4 pt-2 position-relative"},T={class:"d-flex align-items-center mb-3"},N={class:"card shadow-sm",key:"none",style:{height:"153px"}},I={class:"card-body text-muted text-center d-flex"},L={class:"m-auto"};function O(d,t,B,F,V,A){const n=i("LocaleText"),l=i("SchedulePeerJob");return s(),a("div",S,[e("div",y,[e("div",$,[e("div",C,[e("div",D,[e("h4",j,[r(n,{t:"Schedule Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=o=>this.$emit("close"))})]),e("div",k,[e("div",T,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow",onClick:t[1]||(t[1]=o=>this.addJob())},[t[3]||(t[3]=e("i",{class:"bi bi-plus-lg me-2"},null,-1)),r(n,{t:"Job"})])]),r(J,{name:"schedulePeerJobTransition",tag:"div",class:"position-relative"},{default:u(()=>[(s(!0),a(_,null,f(this.selectedPeer.jobs,(o,E)=>(s(),v(l,{onRefresh:t[2]||(t[2]=c=>this.$emit("refresh")),onDelete:c=>this.deleteJob(o),dropdowns:this.store.PeerScheduleJobs.dropdowns,key:o.JobID,pjob:o},null,8,["onDelete","dropdowns","pjob"]))),128)),this.selectedPeer.jobs.length===0?(s(),a("div",N,[e("div",I,[e("h6",L,[r(n,{t:"This peer does not have any job yet."})])])])):m("",!0)]),_:1})])])])])])}const H=h(P,[["render",O],["__scopeId","data-v-5bbdd42b"]]);export{H as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{S as _}from"./schedulePeerJob-DOBEE-kC.js";import{_ as g,h as c,c as r,f as t,a as e,b as l,F as p,i as b,d as f,t as m,j as v,W as y}from"./index-DXzxfcZW.js";import{L as x}from"./localeText-Dmcj5qqx.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";import"./dayjs.min-C-brjxlJ.js";const J={name:"peerJobsAllModal",setup(){return{store:y()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},w={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},$={class:"container d-flex h-100 w-100"},k={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},j={class:"card-body px-4 pb-4 pt-2"},C={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},P={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",w,[e("div",$,[e("div",k,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",j,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",C,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",P,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),v(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const X=g(J,[["render",W]]);export{X as default};
|
||||
import{S as _}from"./schedulePeerJob-jjF9HAtj.js";import{_ as g,h as c,c as r,f as t,a as e,b as l,F as p,i as b,d as f,t as m,j as v,W as y}from"./index-DM7YJCOo.js";import{L as x}from"./localeText-BJvnc1lF.js";import"./vue-datepicker-9N8DgATH.js";import"./index-i3npkoSo.js";import"./dayjs.min-DZl6XMNW.js";const J={name:"peerJobsAllModal",setup(){return{store:y()}},components:{LocaleText:x,SchedulePeerJob:_},props:{configurationPeers:Array[Object]},computed:{getAllJobs(){return this.configurationPeers.filter(a=>a.jobs.length>0)}}},w={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll"},$={class:"container d-flex h-100 w-100"},k={class:"m-auto modal-dialog-centered dashboardModal"},A={class:"card rounded-3 shadow",style:{width:"900px"}},L={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-2"},S={class:"mb-0 fw-normal"},j={class:"card-body px-4 pb-4 pt-2"},C={key:0,class:"accordion",id:"peerJobsLogsModalAccordion"},P={class:"accordion-header"},M=["data-bs-target"],B={key:0},N={class:"text-muted"},D=["id"],T={class:"accordion-body"},V={key:1,class:"card shadow-sm",style:{height:"153px"}},F={class:"card-body text-muted text-center d-flex"},O={class:"m-auto"};function W(a,o,E,I,R,q){const n=c("LocaleText"),u=c("SchedulePeerJob");return t(),r("div",w,[e("div",$,[e("div",k,[e("div",A,[e("div",L,[e("h4",S,[l(n,{t:"All Active Jobs"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:o[0]||(o[0]=s=>this.$emit("close"))})]),e("div",j,[e("button",{class:"btn bg-primary-subtle border-1 border-primary-subtle text-primary-emphasis rounded-3 shadow mb-2",onClick:o[1]||(o[1]=s=>this.$emit("allLogs"))},[o[4]||(o[4]=e("i",{class:"bi bi-clock me-2"},null,-1)),l(n,{t:"Logs"})]),this.getAllJobs.length>0?(t(),r("div",C,[(t(!0),r(p,null,b(this.getAllJobs,(s,d)=>(t(),r("div",{class:"accordion-item",key:s.id},[e("h2",P,[e("button",{class:"accordion-button collapsed",type:"button","data-bs-toggle":"collapse","data-bs-target":"#collapse_"+d},[e("small",null,[e("strong",null,[s.name?(t(),r("span",B,m(s.name)+" • ",1)):f("",!0),e("samp",N,m(s.id),1)])])],8,M)]),e("div",{id:"collapse_"+d,class:"accordion-collapse collapse","data-bs-parent":"#peerJobsLogsModalAccordion"},[e("div",T,[(t(!0),r(p,null,b(s.jobs,i=>(t(),v(u,{onDelete:o[2]||(o[2]=h=>this.$emit("refresh")),onRefresh:o[3]||(o[3]=h=>this.$emit("refresh")),dropdowns:this.store.PeerScheduleJobs.dropdowns,viewOnly:!0,key:i.JobID,pjob:i},null,8,["dropdowns","pjob"]))),128))])],8,D)]))),128))])):(t(),r("div",V,[e("div",F,[e("span",O,[l(n,{t:"No active job at the moment."})])])]))])])])])])}const X=g(J,[["render",W]]);export{X as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{Q as l}from"./browser-DFwZaPoQ.js";import{L as _}from"./localeText-Dmcj5qqx.js";import{_ as h,h as f,c,f as s,a as e,b as p,d as i,j as m,n as u,g,D as v}from"./index-DXzxfcZW.js";import"./galois-field-I2lBzzs-.js";const w={name:"peerQRCode",components:{LocaleText:_},props:{selectedPeer:Object},setup(){return{dashboardStore:v()}},data(){return{loading:!0}},mounted(){g("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},o=>{if(this.loading=!1,o.status){let t="";if(this.selectedPeer.configuration.Protocol==="awg"){let a={containers:[{awg:{isThirdPartyConfig:!0,last_config:o.data.file,port:this.selectedPeer.configuration.ListenPort,transport_proto:"udp"},container:"amnezia-awg"}],defaultContainer:"amnezia-awg",description:this.selectedPeer.name,hostName:this.dashboardStore.Configuration.Peers.remote_endpoint};l.toCanvas(document.querySelector("#awg_vpn_qrcode"),btoa(JSON.stringify(a)),d=>{d&&console.error(d)})}t=o.data.file,l.toCanvas(document.querySelector("#qrcode"),t,a=>{a&&console.error(a)})}else this.dashboardStore.newMessage("Server",o.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},x={class:"container d-flex h-100 w-100"},P={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},C={class:"card rounded-3 shadow"},y={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},S={class:"mb-0"},k={class:"card-body p-4"},q={class:"d-flex gap-2 flex-column"},L={class:"d-flex flex-column gap-2 align-items-center"},N={key:0,class:"d-flex flex-column gap-2 align-items-center"},Q={key:1,class:"spinner-border m-auto",role:"status"};function z(o,t,a,d,r,A){const n=f("LocaleText");return s(),c("div",b,[e("div",x,[e("div",P,[e("div",C,[e("div",y,[e("h4",S,[p(n,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=R=>this.$emit("close"))})]),e("div",k,[e("div",q,[e("div",L,[e("canvas",{id:"qrcode",style:{width:"200px !important",height:"200px !important"},class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),this.selectedPeer.configuration.Protocol==="wg"?(s(),m(n,{key:0,t:"Scan with WireGuard App",class:"text-muted"})):i("",!0),this.selectedPeer.configuration.Protocol==="awg"?(s(),m(n,{key:1,t:"Scan with AmneziaWG App",class:"text-muted"})):i("",!0)]),this.selectedPeer.configuration.Protocol==="awg"?(s(),c("div",N,[e("canvas",{id:"awg_vpn_qrcode",class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),p(n,{t:"Scan with AmneziaVPN App",class:"text-muted"})])):i("",!0),r.loading?(s(),c("div",Q,[...t[1]||(t[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)])])):i("",!0)])])])])])])}const $=h(w,[["render",z],["__scopeId","data-v-02f2240d"]]);export{$ as default};
|
||||
import{Q as l}from"./browser-CUYUHo3j.js";import{L as _}from"./localeText-BJvnc1lF.js";import{_ as h,h as f,c,f as s,a as e,b as p,d as i,j as m,n as u,g,D as v}from"./index-DM7YJCOo.js";import"./galois-field-I2lBzzs-.js";const w={name:"peerQRCode",components:{LocaleText:_},props:{selectedPeer:Object},setup(){return{dashboardStore:v()}},data(){return{loading:!0}},mounted(){g("/api/downloadPeer/"+this.$route.params.id,{id:this.selectedPeer.id},o=>{if(this.loading=!1,o.status){let t="";if(this.selectedPeer.configuration.Protocol==="awg"){let a={containers:[{awg:{isThirdPartyConfig:!0,last_config:o.data.file,port:this.selectedPeer.configuration.ListenPort,transport_proto:"udp"},container:"amnezia-awg"}],defaultContainer:"amnezia-awg",description:this.selectedPeer.name,hostName:this.dashboardStore.Configuration.Peers.remote_endpoint};l.toCanvas(document.querySelector("#awg_vpn_qrcode"),btoa(JSON.stringify(a)),d=>{d&&console.error(d)})}t=o.data.file,l.toCanvas(document.querySelector("#qrcode"),t,a=>{a&&console.error(a)})}else this.dashboardStore.newMessage("Server",o.message,"danger")})}},b={class:"peerSettingContainer w-100 h-100 position-absolute top-0 start-0"},x={class:"container d-flex h-100 w-100"},P={class:"m-auto modal-dialog-centered dashboardModal justify-content-center"},C={class:"card rounded-3 shadow"},y={class:"card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0"},S={class:"mb-0"},k={class:"card-body p-4"},q={class:"d-flex gap-2 flex-column"},L={class:"d-flex flex-column gap-2 align-items-center"},N={key:0,class:"d-flex flex-column gap-2 align-items-center"},Q={key:1,class:"spinner-border m-auto",role:"status"};function z(o,t,a,d,r,A){const n=f("LocaleText");return s(),c("div",b,[e("div",x,[e("div",P,[e("div",C,[e("div",y,[e("h4",S,[p(n,{t:"QR Code"})]),e("button",{type:"button",class:"btn-close ms-auto",onClick:t[0]||(t[0]=R=>this.$emit("close"))})]),e("div",k,[e("div",q,[e("div",L,[e("canvas",{id:"qrcode",style:{width:"200px !important",height:"200px !important"},class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),this.selectedPeer.configuration.Protocol==="wg"?(s(),m(n,{key:0,t:"Scan with WireGuard App",class:"text-muted"})):i("",!0),this.selectedPeer.configuration.Protocol==="awg"?(s(),m(n,{key:1,t:"Scan with AmneziaWG App",class:"text-muted"})):i("",!0)]),this.selectedPeer.configuration.Protocol==="awg"?(s(),c("div",N,[e("canvas",{id:"awg_vpn_qrcode",class:u(["rounded-3 shadow animate__animated animate__fadeIn animate__faster qrcode",{"d-none":r.loading}])},null,2),p(n,{t:"Scan with AmneziaVPN App",class:"text-muted"})])):i("",!0),r.loading?(s(),c("div",Q,[...t[1]||(t[1]=[e("span",{class:"visually-hidden"},"Loading...",-1)])])):i("",!0)])])])])])])}const $=h(w,[["render",z],["__scopeId","data-v-02f2240d"]]);export{$ as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as p,q as m,G as f,W as h,r as u,a0 as _,L as v,K as g,o as x,a1 as S,c as y,d as b,f as B,a as s,m as w,y as T}from"./index-DXzxfcZW.js";const q={key:0,class:"fixed-bottom w-100 bottom-0 z-2 p-3",style:{"z-index":"1"}},C={class:"d-flex flex-column searchPeersContainer ms-auto p-2 rounded-5",style:{width:"300px"}},P={class:"rounded-5 border border-white p-2 d-flex align-items-center gap-1 w-100"},R=["placeholder"],k={__name:"peerSearchBar",props:["ConfigurationInfo"],emits:["close"],setup(V,{emit:z}){const l=m(()=>f("Search Peers..."));let r;const t=h(),e=u(t.searchString),d=()=>{r?(clearTimeout(r),r=setTimeout(()=>{t.searchString=e.value},300)):r=setTimeout(()=>{t.searchString=e.value},300)};_("searchBar");const a=v(),i=g();a.query.peer&&(e.value=a.query.peer,i.replace({query:null}));const n=u(!0);return x(()=>{document.querySelector("#searchPeers").focus()}),S(()=>{n.value=!1}),(G,o)=>n.value?(B(),y("div",q,[s("div",C,[s("div",P,[w(s("input",{ref:"searchBar",class:"flex-grow-1 form-control form-control-sm rounded-5 bg-transparent border-0 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:o[0]||(o[0]=c=>d()),"onUpdate:modelValue":o[1]||(o[1]=c=>e.value=c)},null,40,R),[[T,e.value]])])])])):b("",!0)}},K=p(k,[["__scopeId","data-v-576347d8"]]);export{K as default};
|
||||
import{_ as p,q as m,G as f,W as h,r as u,a0 as _,L as v,K as g,o as x,a1 as S,c as y,d as b,f as B,a as s,m as w,y as T}from"./index-DM7YJCOo.js";const q={key:0,class:"fixed-bottom w-100 bottom-0 z-2 p-3",style:{"z-index":"1"}},C={class:"d-flex flex-column searchPeersContainer ms-auto p-2 rounded-5",style:{width:"300px"}},P={class:"rounded-5 border border-white p-2 d-flex align-items-center gap-1 w-100"},R=["placeholder"],k={__name:"peerSearchBar",props:["ConfigurationInfo"],emits:["close"],setup(V,{emit:z}){const l=m(()=>f("Search Peers..."));let r;const t=h(),e=u(t.searchString),d=()=>{r?(clearTimeout(r),r=setTimeout(()=>{t.searchString=e.value},300)):r=setTimeout(()=>{t.searchString=e.value},300)};_("searchBar");const a=v(),i=g();a.query.peer&&(e.value=a.query.peer,i.replace({query:null}));const n=u(!0);return x(()=>{document.querySelector("#searchPeers").focus()}),S(()=>{n.value=!1}),(G,o)=>n.value?(B(),y("div",q,[s("div",C,[s("div",P,[w(s("input",{ref:"searchBar",class:"flex-grow-1 form-control form-control-sm rounded-5 bg-transparent border-0 border-secondary-subtle",placeholder:l.value,id:"searchPeers",onKeyup:o[0]||(o[0]=c=>d()),"onUpdate:modelValue":o[1]||(o[1]=c=>e.value=c)},null,40,R),[[T,e.value]])])])])):b("",!0)}},K=p(k,[["__scopeId","data-v-576347d8"]]);export{K as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{_ as h,c as o,a as e,m as c,d as m,b as d,h as f,y as g,n as v,t as p,z as b,D as w,A as x,f as r}from"./index-DXzxfcZW.js";import{L as _}from"./localeText-Dmcj5qqx.js";const k={components:{LocaleText:_},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const s=w(),t=`input_${x()}`;return{store:s,uuid:t}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Peers[this.targetData]},methods:{async useValidation(){this.changed&&await b("/api/updateDashboardConfigurationItem",{section:"Peers",key:this.targetData,value:this.value},s=>{s.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Peers[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=s.message),this.changed=!1,this.updating=!1})}}},V={class:"form-group mb-2"},D=["for"],y=["id","disabled"],T={class:"invalid-feedback"},C={key:0,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1"};function F(s,t,a,I,n,u){const l=f("LocaleText");return r(),o("div",V,[e("label",{for:this.uuid,class:"text-muted mb-1"},[e("strong",null,[e("small",null,[d(l,{t:this.title},null,8,["t"])])])],8,D),c(e("input",{type:"text",class:v(["form-control",{"is-invalid":n.showInvalidFeedback,"is-valid":n.isValid}]),id:this.uuid,"onUpdate:modelValue":t[0]||(t[0]=i=>this.value=i),onKeydown:t[1]||(t[1]=i=>this.changed=!0),onBlur:t[2]||(t[2]=i=>u.useValidation()),disabled:this.updating},null,42,y),[[g,this.value]]),e("div",T,p(this.invalidFeedback),1),a.warning?(r(),o("div",C,[e("small",null,[t[3]||(t[3]=e("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),d(l,{t:a.warningText},null,8,["t"])])])):m("",!0)])}const B=h(k,[["render",F]]);export{B as P};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as c,c as a,a as t,m as u,d as m,b as h,h as f,v as g,y as v,n as p,t as b,z as k,D as w,A as x,f as n}from"./index-DM7YJCOo.js";import{L as _}from"./localeText-BJvnc1lF.js";const V={components:{LocaleText:_},props:{targetData:String,title:String,warning:!1,warningText:""},setup(){const i=w(),e=`input_${x()}`;return{store:i,uuid:e}},data(){return{value:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.value=this.store.Configuration.Peers[this.targetData]},computed:{isBoolean(){return typeof this.value=="boolean"}},methods:{async useValidation(){this.changed&&await k("/api/updateDashboardConfigurationItem",{section:"Peers",key:this.targetData,value:this.value},i=>{i.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Peers[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=i.message),this.changed=!1,this.updating=!1})}}},y={class:"form-group mb-2"},D=["for"],C={key:0,class:"form-check form-switch"},T=["id","disabled"],F=["id","disabled"],B={class:"invalid-feedback"},I={key:2,class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1"};function P(i,e,l,S,d,o){const r=f("LocaleText");return n(),a("div",y,[t("label",{for:this.uuid,class:"text-muted mb-1"},[t("strong",null,[t("small",null,[h(r,{t:this.title},null,8,["t"])])])],8,D),o.isBoolean?(n(),a("div",C,[u(t("input",{class:"form-check-input",type:"checkbox",role:"switch","onUpdate:modelValue":e[0]||(e[0]=s=>this.value=s),id:this.uuid,onChange:e[1]||(e[1]=s=>{this.changed=!0,o.useValidation()}),disabled:this.updating},null,40,T),[[g,this.value]])])):u((n(),a("input",{key:1,type:"text",class:p(["form-control",{"is-invalid":d.showInvalidFeedback,"is-valid":d.isValid}]),id:this.uuid,"onUpdate:modelValue":e[2]||(e[2]=s=>this.value=s),onKeydown:e[3]||(e[3]=s=>this.changed=!0),onBlur:e[4]||(e[4]=s=>o.useValidation()),disabled:this.updating},null,42,F)),[[v,this.value]]),t("div",B,b(this.invalidFeedback),1),l.warning?(n(),a("div",I,[t("small",null,[e[5]||(e[5]=t("i",{class:"bi bi-exclamation-triangle-fill me-2"},null,-1)),h(r,{t:l.warningText},null,8,["t"])])])):m("",!0)])}const z=c(V,[["render",P]]);export{z as P};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{L as n}from"./localeText-Dmcj5qqx.js";import{c as a,d as r,e as s,j as i,f as e}from"./index-DXzxfcZW.js";const d={class:"position-relative"},c={key:0,class:"badge wireguardBg rounded-3 shadow z-1"},l={key:1,class:"badge amneziawgBg rounded-3 shadow"},p={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(o){return(m,t)=>(e(),a("div",d,[o.protocol==="wg"?(e(),a("span",c,[t[0]||(t[0]=s(" WireGuard ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):o.protocol==="awg"?(e(),a("span",l,[t[1]||(t[1]=s(" AmneziaWG ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):r("",!0)]))}};export{p as _};
|
||||
import{L as n}from"./localeText-BJvnc1lF.js";import{c as a,d as r,e as s,j as i,f as e}from"./index-DM7YJCOo.js";const d={class:"position-relative"},c={key:0,class:"badge wireguardBg rounded-3 shadow z-1"},l={key:1,class:"badge amneziawgBg rounded-3 shadow"},p={__name:"protocolBadge",props:{protocol:String,mini:!1},setup(o){return(m,t)=>(e(),a("div",d,[o.protocol==="wg"?(e(),a("span",c,[t[0]||(t[0]=s(" WireGuard ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):o.protocol==="awg"?(e(),a("span",l,[t[1]||(t[1]=s(" AmneziaWG ",-1)),o.mini?r("",!0):(e(),i(n,{key:0,t:"Configuration"}))])):r("",!0)]))}};export{p as _};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.btn.disabled[data-v-abe2acbc]{opacity:1;background-color:#0d6efd17;border-color:transparent}[data-v-b94dda6b]{font-size:.875rem}input[data-v-b94dda6b]{padding:.1rem .4rem}input[data-v-b94dda6b]:disabled{border-color:transparent;background-color:#0d6efd17;color:#0d6efd}.dp__main[data-v-b94dda6b]{width:auto;flex-grow:1;--dp-input-padding: 2.5px 30px 2.5px 12px;--dp-border-radius: .5rem}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
.btn.disabled[data-v-abe2acbc]{opacity:1;background-color:#0d6efd17;border-color:transparent}[data-v-73513cfe]{font-size:.875rem}input[data-v-73513cfe]{padding:.1rem .4rem}input[data-v-73513cfe]:disabled{border-color:transparent;background-color:#0d6efd17;color:#0d6efd}.dp__main[data-v-73513cfe]{width:auto;flex-grow:1;--dp-input-padding: 2.5px 30px 2.5px 12px;--dp-border-radius: .5rem}
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as c,z as D,D as m,A as x,c as i,a as t,t as S,m as l,y as u,e as p,f as o,b as n,F as $,i as w,h as r,w as I}from"./index-DXzxfcZW.js";import{P}from"./peersDefaultSettingsInput-KXSGcg6g.js";import{A as k,a as A,D as y,b as C,c as V,d as F,e as T,_ as L}from"./dashboardEmailSettings-BNCV3lPl.js";import{D as R,a as W}from"./dashboardSettingsWireguardConfigurationAutostart-DWZoKQw6.js";import{L as U}from"./localeText-Dmcj5qqx.js";import"./dayjs.min-C-brjxlJ.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";const B={name:"dashboardSettingsInputIPAddressAndPort",props:{},setup(){const e=m(),s=`input_${x()}`;return{store:e,uuid:s}},data(){return{app_ip:"",app_port:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.app_ip=this.store.Configuration.Server.app_ip,this.app_port=this.store.Configuration.Server.app_port},methods:{async useValidation(){this.changed&&await D("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},e=>{e.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=e.message)})}}},G={class:"invalid-feedback d-block mt-0"},N={class:"row"},E={class:"form-group mb-2 col-sm"},M=["for"],j=["id"],z={class:"form-group col-sm"},K=["for"],q=["id"];function H(e,s,h,_,b,f){return o(),i("div",null,[t("div",G,S(this.invalidFeedback),1),t("div",N,[t("div",E,[t("label",{for:"app_ip_"+this.uuid,class:"text-muted mb-1"},[...s[2]||(s[2]=[t("strong",null,[t("small",null,"Dashboard IP Address")],-1)])],8,M),l(t("input",{type:"text",class:"form-control mb-2",id:"app_ip_"+this.uuid,"onUpdate:modelValue":s[0]||(s[0]=a=>this.app_ip=a)},null,8,j),[[u,this.app_ip]]),s[3]||(s[3]=t("div",{class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block"},[t("small",null,[t("i",{class:"bi bi-exclamation-triangle-fill me-2"}),t("code",null,"0.0.0.0"),p(" means it can be access by anyone with your server IP Address.")])],-1))]),t("div",z,[t("label",{for:"app_port_"+this.uuid,class:"text-muted mb-1"},[...s[4]||(s[4]=[t("strong",null,[t("small",null,"Dashboard Port")],-1)])],8,K),l(t("input",{type:"text",class:"form-control mb-2",id:"app_port_"+this.uuid,"onUpdate:modelValue":s[1]||(s[1]=a=>this.app_port=a)},null,8,q),[[u,this.app_port]])])]),s[5]||(s[5]=t("button",{class:"btn btn-success btn-sm fw-bold rounded-3"},[t("i",{class:"bi bi-floppy-fill me-2"}),p("Update Dashboard Settings & Restart ")],-1))])}const J=c(B,[["render",H]]),O={name:"settings",components:{DashboardEmailSettings:L,DashboardSettingsWireguardConfigurationAutostart:W,DashboardIPPortInput:T,DashboardLanguage:F,LocaleText:U,AccountSettingsMFA:V,DashboardAPIKeys:C,DashboardSettingsInputIPAddressAndPort:J,DashboardTheme:y,DashboardSettingsInputWireguardConfigurationPath:R,AccountSettingsInputPassword:A,AccountSettingsInputUsername:k,PeersDefaultSettingsInput:P},setup(){return{dashboardConfigurationStore:m()}},data(){return{activeTab:"WGDashboard",tabs:[{id:"",title:"WGDashboard Settings"},{id:"peers_settings",title:"Peers Settings"},{id:"wireguard_settings",title:"WireGuard Configuration Settings"}]}}},Q={class:"mt-md-5 mt-3 text-body mb-3"},X={class:"container-md d-flex flex-column gap-3"},Y={class:"border-bottom pb-3"},Z={class:"nav nav-pills nav-justified align-items-center gap-2"},tt={class:"nav-item"},st={class:"my-2"};function et(e,s,h,_,b,f){const a=r("LocaleText"),g=r("RouterLink"),v=r("RouterView");return o(),i("div",Q,[t("div",X,[t("div",Y,[t("ul",Z,[(o(!0),i($,null,w(this.tabs,d=>(o(),i("li",tt,[n(g,{to:{name:d.title},class:"nav-link rounded-3","exact-active-class":"active",role:"button"},{default:I(()=>[t("h6",st,[n(a,{t:d.title},null,8,["t"])])]),_:2},1032,["to"])]))),256))])]),n(v)])])}const pt=c(O,[["render",et]]);export{pt as default};
|
||||
import{_ as c,z as D,D as m,A as x,c as i,a as t,t as S,m as l,y as u,e as p,f as o,b as n,F as $,i as w,h as r,w as I}from"./index-DM7YJCOo.js";import{P}from"./peersDefaultSettingsInput-n69y01QP.js";import{A as k,a as A,D as y,b as C,c as V,d as F,e as T,_ as L}from"./dashboardEmailSettings-DBnS2OTV.js";import{D as R,a as W}from"./dashboardSettingsWireguardConfigurationAutostart-CLeShfcZ.js";import{L as U}from"./localeText-BJvnc1lF.js";import"./dayjs.min-DZl6XMNW.js";import"./vue-datepicker-9N8DgATH.js";import"./index-i3npkoSo.js";const B={name:"dashboardSettingsInputIPAddressAndPort",props:{},setup(){const e=m(),s=`input_${x()}`;return{store:e,uuid:s}},data(){return{app_ip:"",app_port:"",invalidFeedback:"",showInvalidFeedback:!1,isValid:!1,timeout:void 0,changed:!1,updating:!1}},mounted(){this.app_ip=this.store.Configuration.Server.app_ip,this.app_port=this.store.Configuration.Server.app_port},methods:{async useValidation(){this.changed&&await D("/api/updateDashboardConfigurationItem",{section:"Server",key:this.targetData,value:this.value},e=>{e.status?(this.isValid=!0,this.showInvalidFeedback=!1,this.store.Configuration.Account[this.targetData]=this.value,clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.isValid=!1,5e3)):(this.isValid=!1,this.showInvalidFeedback=!0,this.invalidFeedback=e.message)})}}},G={class:"invalid-feedback d-block mt-0"},N={class:"row"},E={class:"form-group mb-2 col-sm"},M=["for"],j=["id"],z={class:"form-group col-sm"},K=["for"],q=["id"];function H(e,s,h,_,b,f){return o(),i("div",null,[t("div",G,S(this.invalidFeedback),1),t("div",N,[t("div",E,[t("label",{for:"app_ip_"+this.uuid,class:"text-muted mb-1"},[...s[2]||(s[2]=[t("strong",null,[t("small",null,"Dashboard IP Address")],-1)])],8,M),l(t("input",{type:"text",class:"form-control mb-2",id:"app_ip_"+this.uuid,"onUpdate:modelValue":s[0]||(s[0]=a=>this.app_ip=a)},null,8,j),[[u,this.app_ip]]),s[3]||(s[3]=t("div",{class:"px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block"},[t("small",null,[t("i",{class:"bi bi-exclamation-triangle-fill me-2"}),t("code",null,"0.0.0.0"),p(" means it can be access by anyone with your server IP Address.")])],-1))]),t("div",z,[t("label",{for:"app_port_"+this.uuid,class:"text-muted mb-1"},[...s[4]||(s[4]=[t("strong",null,[t("small",null,"Dashboard Port")],-1)])],8,K),l(t("input",{type:"text",class:"form-control mb-2",id:"app_port_"+this.uuid,"onUpdate:modelValue":s[1]||(s[1]=a=>this.app_port=a)},null,8,q),[[u,this.app_port]])])]),s[5]||(s[5]=t("button",{class:"btn btn-success btn-sm fw-bold rounded-3"},[t("i",{class:"bi bi-floppy-fill me-2"}),p("Update Dashboard Settings & Restart ")],-1))])}const J=c(B,[["render",H]]),O={name:"settings",components:{DashboardEmailSettings:L,DashboardSettingsWireguardConfigurationAutostart:W,DashboardIPPortInput:T,DashboardLanguage:F,LocaleText:U,AccountSettingsMFA:V,DashboardAPIKeys:C,DashboardSettingsInputIPAddressAndPort:J,DashboardTheme:y,DashboardSettingsInputWireguardConfigurationPath:R,AccountSettingsInputPassword:A,AccountSettingsInputUsername:k,PeersDefaultSettingsInput:P},setup(){return{dashboardConfigurationStore:m()}},data(){return{activeTab:"WGDashboard",tabs:[{id:"",title:"WGDashboard Settings"},{id:"peers_settings",title:"Peers Settings"},{id:"wireguard_settings",title:"WireGuard Configuration Settings"}]}}},Q={class:"mt-md-5 mt-3 text-body mb-3"},X={class:"container-md d-flex flex-column gap-3"},Y={class:"border-bottom pb-3"},Z={class:"nav nav-pills nav-justified align-items-center gap-2"},tt={class:"nav-item"},st={class:"my-2"};function et(e,s,h,_,b,f){const a=r("LocaleText"),g=r("RouterLink"),v=r("RouterView");return o(),i("div",Q,[t("div",X,[t("div",Y,[t("ul",Z,[(o(!0),i($,null,w(this.tabs,d=>(o(),i("li",tt,[n(g,{to:{name:d.title},class:"nav-link rounded-3","exact-active-class":"active",role:"button"},{default:I(()=>[t("h6",st,[n(a,{t:d.title},null,8,["t"])])]),_:2},1032,["to"])]))),256))])]),n(v)])])}const pt=c(O,[["render",et]]);export{pt as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as u,c as r,a as e,b as o,h as m,e as p,d as c,t as h,m as l,y as d,z as f,D as w,f as i}from"./index-DXzxfcZW.js";import{L as g}from"./localeText-Dmcj5qqx.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:w()}},data(){return{setup:{username:"",newPassword:"",repeatNewPassword:"",enable_totp:!0},loading:!1,errorMessage:"",done:!1}},computed:{goodToSubmit(){return this.setup.username&&this.setup.newPassword.length>=8&&this.setup.repeatNewPassword.length>=8&&this.setup.newPassword===this.setup.repeatNewPassword}},methods:{submit(){this.loading=!0,f("/api/Welcome_Finish",this.setup,n=>{n.status?(this.done=!0,this.$router.push("/2FASetup")):(document.querySelectorAll("#createAccount input").forEach(s=>s.classList.add("is-invalid")),this.errorMessage=n.message,document.querySelector(".login-container-fluid").scrollTo({top:0,left:0,behavior:"smooth"})),this.loading=!1})}}},_=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},v={class:"dashboardLogo display-4"},y={class:"mb-5"},P={key:0,class:"alert alert-danger"},N={class:"d-flex flex-column gap-3"},k={id:"createAccount",class:"d-flex flex-column gap-2"},S={class:"form-group text-body"},T={for:"username",class:"mb-1 text-muted"},C={class:"form-group text-body"},L={for:"password",class:"mb-1 text-muted"},V={class:"form-group text-body"},$={for:"confirmPassword",class:"mb-1 text-muted"},q=["disabled"],A={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=m("LocaleText");return i(),r("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[e("div",x,[e("span",v,[o(t,{t:"Nice to meet you!"})]),e("p",y,[o(t,{t:"Please fill in the following fields to finish setup"}),s[4]||(s[4]=p(" 😊",-1))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):c("",!0),e("div",N,[e("form",k,[e("div",S,[e("label",T,[e("small",null,[o(t,{t:"Enter an username you like"})])]),l(e("input",{type:"text",autocomplete:"username","onUpdate:modelValue":s[0]||(s[0]=a=>this.setup.username=a),class:"form-control",id:"username",name:"username",required:""},null,512),[[d,this.setup.username]])]),e("div",C,[e("label",L,[e("small",null,[o(t,{t:"Enter a password"}),e("code",null,[o(t,{t:"(At least 8 characters and make sure is strong enough!)"})])])]),l(e("input",{type:"password",autocomplete:"new-password","onUpdate:modelValue":s[1]||(s[1]=a=>this.setup.newPassword=a),class:"form-control",id:"password",name:"password",required:""},null,512),[[d,this.setup.newPassword]])]),e("div",V,[e("label",$,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",A,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,q)])])])],8,_)}const W=u(b,[["render",B]]);export{W as default};
|
||||
import{_ as u,c as r,a as e,b as o,h as m,e as p,d as c,t as h,m as l,y as d,z as f,D as w,f as i}from"./index-DM7YJCOo.js";import{L as g}from"./localeText-BJvnc1lF.js";const b={name:"setup",components:{LocaleText:g},setup(){return{store:w()}},data(){return{setup:{username:"",newPassword:"",repeatNewPassword:"",enable_totp:!0},loading:!1,errorMessage:"",done:!1}},computed:{goodToSubmit(){return this.setup.username&&this.setup.newPassword.length>=8&&this.setup.repeatNewPassword.length>=8&&this.setup.newPassword===this.setup.repeatNewPassword}},methods:{submit(){this.loading=!0,f("/api/Welcome_Finish",this.setup,n=>{n.status?(this.done=!0,this.$router.push("/2FASetup")):(document.querySelectorAll("#createAccount input").forEach(s=>s.classList.add("is-invalid")),this.errorMessage=n.message,document.querySelector(".login-container-fluid").scrollTo({top:0,left:0,behavior:"smooth"})),this.loading=!1})}}},_=["data-bs-theme"],x={class:"m-auto text-body",style:{width:"500px"}},v={class:"dashboardLogo display-4"},y={class:"mb-5"},P={key:0,class:"alert alert-danger"},N={class:"d-flex flex-column gap-3"},k={id:"createAccount",class:"d-flex flex-column gap-2"},S={class:"form-group text-body"},T={for:"username",class:"mb-1 text-muted"},C={class:"form-group text-body"},L={for:"password",class:"mb-1 text-muted"},V={class:"form-group text-body"},$={for:"confirmPassword",class:"mb-1 text-muted"},q=["disabled"],A={key:0,class:"d-flex align-items-center w-100"},M={key:1,class:"d-flex align-items-center w-100"};function B(n,s,D,E,U,F){const t=m("LocaleText");return i(),r("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[e("div",x,[e("span",v,[o(t,{t:"Nice to meet you!"})]),e("p",y,[o(t,{t:"Please fill in the following fields to finish setup"}),s[4]||(s[4]=p(" 😊",-1))]),e("div",null,[e("h3",null,[o(t,{t:"Create an account"})]),this.errorMessage?(i(),r("div",P,h(this.errorMessage),1)):c("",!0),e("div",N,[e("form",k,[e("div",S,[e("label",T,[e("small",null,[o(t,{t:"Enter an username you like"})])]),l(e("input",{type:"text",autocomplete:"username","onUpdate:modelValue":s[0]||(s[0]=a=>this.setup.username=a),class:"form-control",id:"username",name:"username",required:""},null,512),[[d,this.setup.username]])]),e("div",C,[e("label",L,[e("small",null,[o(t,{t:"Enter a password"}),e("code",null,[o(t,{t:"(At least 8 characters and make sure is strong enough!)"})])])]),l(e("input",{type:"password",autocomplete:"new-password","onUpdate:modelValue":s[1]||(s[1]=a=>this.setup.newPassword=a),class:"form-control",id:"password",name:"password",required:""},null,512),[[d,this.setup.newPassword]])]),e("div",V,[e("label",$,[e("small",null,[o(t,{t:"Confirm password"})])]),l(e("input",{type:"password",autocomplete:"confirm-new-password","onUpdate:modelValue":s[2]||(s[2]=a=>this.setup.repeatNewPassword=a),class:"form-control",id:"confirmPassword",name:"confirmPassword",required:""},null,512),[[d,this.setup.repeatNewPassword]])])]),e("button",{class:"btn btn-dark btn-lg mb-5 d-flex btn-brand shadow align-items-center",ref:"signInBtn",disabled:!this.goodToSubmit||this.loading||this.done,onClick:s[3]||(s[3]=a=>this.submit())},[!this.loading&&!this.done?(i(),r("span",A,[o(t,{t:"Next"}),s[5]||(s[5]=e("i",{class:"bi bi-chevron-right ms-auto"},null,-1))])):(i(),r("span",M,[o(t,{t:"Saving..."}),s[6]||(s[6]=e("span",{class:"spinner-border ms-auto spinner-border-sm",role:"status"},[e("span",{class:"visually-hidden"},"Loading...")],-1))]))],8,q)])])])],8,_)}const W=u(b,[["render",B]]);export{W as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_,c as m,a as t,b as r,h as p,r as c,D as h,g as u,L as b,f}from"./index-DXzxfcZW.js";import{Q as v}from"./browser-DFwZaPoQ.js";import{L as y}from"./localeText-Dmcj5qqx.js";import"./galois-field-I2lBzzs-.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=b(),e=c(!1),s=h(),n=c(""),i=c(void 0),l=c(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(i.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(i.value=d.data,l.value=new Blob([i.value.file],{type:"text/plain"})):i.value=void 0,e.value=!0}),{store:s,theme:n,peerConfiguration:i,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),s=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=s,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},x=["data-bs-theme"],w={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},L={class:"m-auto"},I={key:1,class:"d-flex align-items-center flex-column gap-3"},B={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},k={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},R={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},D=["download","href"];function q(o,e,s,n,i,l){const a=p("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",w,[this.peerConfiguration?(f(),m("div",I,[t("div",B,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),r(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",k,null,512),t("p",R,[r(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),r(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},[...e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)])],8,D)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",L,[r(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,x)}const O=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{O as default};
|
||||
import{_,c as m,a as t,b as r,h as p,r as c,D as h,g as u,L as b,f}from"./index-DM7YJCOo.js";import{Q as v}from"./browser-CUYUHo3j.js";import{L as y}from"./localeText-BJvnc1lF.js";import"./galois-field-I2lBzzs-.js";const g={name:"share",components:{LocaleText:y},async setup(){const o=b(),e=c(!1),s=h(),n=c(""),i=c(void 0),l=c(new Blob);await u("/api/getDashboardTheme",{},d=>{n.value=d.data});const a=o.query.ShareID;return a===void 0||a.length===0?(i.value=void 0,e.value=!0):await u("/api/sharePeer/get",{ShareID:a},d=>{d.status?(i.value=d.data,l.value=new Blob([i.value.file],{type:"text/plain"})):i.value=void 0,e.value=!0}),{store:s,theme:n,peerConfiguration:i,blob:l}},mounted(){this.peerConfiguration&&v.toCanvas(document.querySelector("#qrcode"),this.peerConfiguration.file,o=>{o&&console.error(o)})},methods:{download(){const o=new Blob([this.peerConfiguration.file],{type:"text/plain"}),e=URL.createObjectURL(o),s=`${this.peerConfiguration.fileName}.conf`,n=document.createElement("a");n.href=e,n.download=s,n.click()}},computed:{getBlob(){return URL.createObjectURL(this.blob)}}},x=["data-bs-theme"],w={class:"m-auto text-body",style:{width:"500px"}},C={key:0,class:"text-center position-relative",style:{}},U={class:"position-absolute w-100 h-100 top-0 start-0 d-flex animate__animated animate__fadeInUp",style:{"animation-delay":"0.1s"}},L={class:"m-auto"},I={key:1,class:"d-flex align-items-center flex-column gap-3"},B={class:"h1 dashboardLogo text-center animate__animated animate__fadeInUp"},k={id:"qrcode",class:"rounded-3 shadow animate__animated animate__fadeInUp mb-3",ref:"qrcode"},R={class:"text-muted animate__animated animate__fadeInUp mb-1",style:{"animation-delay":"0.2s"}},D=["download","href"];function q(o,e,s,n,i,l){const a=p("LocaleText");return f(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.theme},[t("div",w,[this.peerConfiguration?(f(),m("div",I,[t("div",B,[e[1]||(e[1]=t("h6",null,"WGDashboard",-1)),r(a,{t:"Scan QR Code with the WireGuard App to add peer"})]),t("canvas",k,null,512),t("p",R,[r(a,{t:"or click the button below to download the "}),e[2]||(e[2]=t("samp",null,".conf",-1)),r(a,{t:" file"})]),t("a",{download:this.peerConfiguration.fileName+".conf",href:l.getBlob,class:"btn btn-lg bg-primary-subtle text-primary-emphasis border-1 border-primary-subtle animate__animated animate__fadeInUp shadow-sm",style:{"animation-delay":"0.25s"}},[...e[3]||(e[3]=[t("i",{class:"bi bi-download"},null,-1)])],8,D)])):(f(),m("div",C,[e[0]||(e[0]=t("div",{class:"animate__animated animate__fadeInUp"},[t("h1",{style:{"font-size":"20rem",filter:"blur(1rem)","animation-duration":"7s"},class:"animate__animated animate__flash animate__infinite"},[t("i",{class:"bi bi-file-binary"})])],-1)),t("div",U,[t("h3",L,[r(a,{t:"Oh no... This link is either expired or invalid."})])])]))])],8,x)}const O=_(g,[["render",q],["__scopeId","data-v-1b44aacd"]]);export{O as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
.card-header[data-v-87b9c3d8]{transition:all .2s ease-in-out}.dot.inactive[data-v-87b9c3d8]{background-color:#dc3545;box-shadow:0 0 0 .2rem #dc354545}.spin[data-v-87b9c3d8]{animation:spin-87b9c3d8 1s infinite cubic-bezier(.82,.58,.17,.9)}@keyframes spin-87b9c3d8{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media screen and (max-width: 768px){.remoteServerContainer[data-v-87b9c3d8]{flex-direction:column}.remoteServerContainer .button-group button[data-v-87b9c3d8]{width:100%}}@media screen and (max-width: 768px){.login-box[data-v-9e84e18b]{width:100%!important}.login-box div[data-v-9e84e18b]{width:auto!important}}
|
||||
.card-header[data-v-87b9c3d8]{transition:all .2s ease-in-out}.dot.inactive[data-v-87b9c3d8]{background-color:#dc3545;box-shadow:0 0 0 .2rem #dc354545}.spin[data-v-87b9c3d8]{animation:spin-87b9c3d8 1s infinite cubic-bezier(.82,.58,.17,.9)}@keyframes spin-87b9c3d8{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media screen and (max-width: 768px){.remoteServerContainer[data-v-87b9c3d8]{flex-direction:column}.remoteServerContainer .button-group button[data-v-87b9c3d8]{width:100%}}@media screen and (max-width: 768px){.login-box[data-v-9f90d4ac]{width:100%!important}.login-box div[data-v-9f90d4ac]{width:auto!important}}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as p,r as b,q as x,c as t,f as r,b as n,w as f,d as v,n as g,s as l,a as c,e as C,t as d,k as w,p as y}from"./index-DXzxfcZW.js";import{L as _}from"./localeText-Dmcj5qqx.js";const k={class:"text-muted me-2"},N={class:"fw-bold"},q={__name:"cpuCore",props:{core_number:Number,percentage:Number,align:Boolean,square:Boolean},setup(e){y(i=>({a680627c:s.value}));const u=e,o=b(!1),s=x(()=>u.square?"40px":"25px");return(i,a)=>(r(),t("div",{class:"flex-grow-1 square rounded-3 border position-relative p-2",onMouseenter:a[0]||(a[0]=m=>o.value=!0),onMouseleave:a[1]||(a[1]=m=>o.value=!1),style:l({"background-color":`rgb(13 110 253 / ${e.percentage*10}%)`})},[n(w,{name:"zoomReversed"},{default:f(()=>[o.value?(r(),t("div",{key:0,style:l([{"white-space":"nowrap"},{top:s.value}]),class:g(["floatingLabel z-3 border position-absolute d-block p-1 px-2 bg-body text-body rounded-3 border shadow d-flex",[e.align?"end-0":"start-0"]])},[c("small",k,[n(_,{t:"Core"}),C(" #"+d(e.core_number+1),1)]),c("small",N,d(e.percentage)+"% ",1)],6)):v("",!0)]),_:1})],36))}},h=p(q,[["__scopeId","data-v-d4cea788"]]);export{h as C};
|
||||
import{_ as p,r as b,q as x,c as t,f as r,b as n,w as f,d as v,n as g,s as l,a as c,e as C,t as d,k as w,p as y}from"./index-DM7YJCOo.js";import{L as _}from"./localeText-BJvnc1lF.js";const k={class:"text-muted me-2"},N={class:"fw-bold"},q={__name:"cpuCore",props:{core_number:Number,percentage:Number,align:Boolean,square:Boolean},setup(e){y(i=>({a680627c:s.value}));const u=e,o=b(!1),s=x(()=>u.square?"40px":"25px");return(i,a)=>(r(),t("div",{class:"flex-grow-1 square rounded-3 border position-relative p-2",onMouseenter:a[0]||(a[0]=m=>o.value=!0),onMouseleave:a[1]||(a[1]=m=>o.value=!1),style:l({"background-color":`rgb(13 110 253 / ${e.percentage*10}%)`})},[n(w,{name:"zoomReversed"},{default:f(()=>[o.value?(r(),t("div",{key:0,style:l([{"white-space":"nowrap"},{top:s.value}]),class:g(["floatingLabel z-3 border position-absolute d-block p-1 px-2 bg-body text-body rounded-3 border shadow d-flex",[e.align?"end-0":"start-0"]])},[c("small",k,[n(_,{t:"Core"}),C(" #"+d(e.core_number+1),1)]),c("small",N,d(e.percentage)+"% ",1)],6)):v("",!0)]),_:1})],36))}},h=p(q,[["__scopeId","data-v-d4cea788"]]);export{h as C};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as h,c as m,a as t,b as i,h as d,t as p,m as f,y as _,j as r,w as c,z as b,D as v,g,f as n}from"./index-DXzxfcZW.js";import{Q as x}from"./browser-DFwZaPoQ.js";import{L as y}from"./localeText-Dmcj5qqx.js";import"./galois-field-I2lBzzs-.js";const T={name:"totp",components:{LocaleText:y},async setup(){const s=v();let e="";return await g("/api/Welcome_GetTotpLink",{},(a=>{a.status&&(e=a.data)})),{l:e,store:s}},mounted(){this.l&&x.toCanvas(document.getElementById("qrcode"),this.l,function(s){})},data(){return{totp:"",totpInvalidMessage:"",verified:!1}},methods:{validateTotp(){}},watch:{totp(s){const e=document.querySelector("#totp");e.classList.remove("is-invalid","is-valid"),s.length===6&&(console.log(s),/[0-9]{6}/.test(s)?b("/api/Welcome_VerifyTotpLink",{totp:s},a=>{a.status?(this.verified=!0,e.classList.add("is-valid"),this.$emit("verified")):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP does not match.")}):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP can only contain numbers"))}}},k=["data-bs-theme"],L={class:"m-auto text-body",style:{width:"500px"}},w={class:"d-flex flex-column"},C={class:"dashboardLogo display-4"},M={class:"mb-2"},P={class:"text-muted"},I={class:"p-3 bg-body-secondary rounded-3 border mb-3"},O={class:"text-muted mb-0"},B=["href"],$={style:{"line-break":"anywhere"}},D={for:"totp",class:"mb-2"},R={class:"text-muted"},S={class:"form-group mb-2"},q=["disabled"],A={class:"invalid-feedback"},E={class:"valid-feedback"},F={class:"d-flex gap-3 mt-5 flex-column"};function Q(s,e,a,G,N,W){const o=d("LocaleText"),l=d("RouterLink");return n(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[t("div",L,[t("div",w,[t("div",null,[t("h1",C,[i(o,{t:"Multi-Factor Authentication (MFA)"})]),t("p",M,[t("small",P,[i(o,{t:"1. Please scan the following QR Code to generate TOTP with your choice of authenticator"})])]),e[1]||(e[1]=t("canvas",{id:"qrcode",class:"rounded-3 mb-2"},null,-1)),t("div",I,[t("p",O,[t("small",null,[i(o,{t:"Or you can click the link below:"})])]),t("a",{href:this.l},[t("code",$,p(this.l),1)],8,B)]),t("label",D,[t("small",R,[i(o,{t:"2. Enter the TOTP generated by your authenticator to verify"})])]),t("div",S,[f(t("input",{class:"form-control text-center totp",id:"totp",maxlength:"6",type:"text",inputmode:"numeric",autocomplete:"one-time-code","onUpdate:modelValue":e[0]||(e[0]=u=>this.totp=u),disabled:this.verified},null,8,q),[[_,this.totp]]),t("div",A,[i(o,{t:this.totpInvalidMessage},null,8,["t"])]),t("div",E,[i(o,{t:"TOTP verified!"})])])]),e[4]||(e[4]=t("hr",null,null,-1)),t("div",F,[this.verified?(n(),r(l,{key:1,to:"/",class:"btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3"},{default:c(()=>[i(o,{t:"Complete"}),e[3]||(e[3]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1})):(n(),r(l,{key:0,to:"/",class:"btn bg-secondary-subtle text-secondary-emphasis rounded-3 flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex"},{default:c(()=>[i(o,{t:"I don't need MFA"}),e[2]||(e[2]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1}))])])])],8,k)}const H=h(T,[["render",Q]]);export{H as default};
|
||||
import{_ as h,c as m,a as t,b as i,h as d,t as p,m as f,y as _,j as r,w as c,z as b,D as v,g,f as n}from"./index-DM7YJCOo.js";import{Q as x}from"./browser-CUYUHo3j.js";import{L as y}from"./localeText-BJvnc1lF.js";import"./galois-field-I2lBzzs-.js";const T={name:"totp",components:{LocaleText:y},async setup(){const s=v();let e="";return await g("/api/Welcome_GetTotpLink",{},(a=>{a.status&&(e=a.data)})),{l:e,store:s}},mounted(){this.l&&x.toCanvas(document.getElementById("qrcode"),this.l,function(s){})},data(){return{totp:"",totpInvalidMessage:"",verified:!1}},methods:{validateTotp(){}},watch:{totp(s){const e=document.querySelector("#totp");e.classList.remove("is-invalid","is-valid"),s.length===6&&(console.log(s),/[0-9]{6}/.test(s)?b("/api/Welcome_VerifyTotpLink",{totp:s},a=>{a.status?(this.verified=!0,e.classList.add("is-valid"),this.$emit("verified")):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP does not match.")}):(e.classList.add("is-invalid"),this.totpInvalidMessage="TOTP can only contain numbers"))}}},k=["data-bs-theme"],L={class:"m-auto text-body",style:{width:"500px"}},w={class:"d-flex flex-column"},C={class:"dashboardLogo display-4"},M={class:"mb-2"},P={class:"text-muted"},I={class:"p-3 bg-body-secondary rounded-3 border mb-3"},O={class:"text-muted mb-0"},B=["href"],$={style:{"line-break":"anywhere"}},D={for:"totp",class:"mb-2"},R={class:"text-muted"},S={class:"form-group mb-2"},q=["disabled"],A={class:"invalid-feedback"},E={class:"valid-feedback"},F={class:"d-flex gap-3 mt-5 flex-column"};function Q(s,e,a,G,N,W){const o=d("LocaleText"),l=d("RouterLink");return n(),m("div",{class:"container-fluid login-container-fluid d-flex main pt-5 overflow-scroll","data-bs-theme":this.store.Configuration.Server.dashboard_theme},[t("div",L,[t("div",w,[t("div",null,[t("h1",C,[i(o,{t:"Multi-Factor Authentication (MFA)"})]),t("p",M,[t("small",P,[i(o,{t:"1. Please scan the following QR Code to generate TOTP with your choice of authenticator"})])]),e[1]||(e[1]=t("canvas",{id:"qrcode",class:"rounded-3 mb-2"},null,-1)),t("div",I,[t("p",O,[t("small",null,[i(o,{t:"Or you can click the link below:"})])]),t("a",{href:this.l},[t("code",$,p(this.l),1)],8,B)]),t("label",D,[t("small",R,[i(o,{t:"2. Enter the TOTP generated by your authenticator to verify"})])]),t("div",S,[f(t("input",{class:"form-control text-center totp",id:"totp",maxlength:"6",type:"text",inputmode:"numeric",autocomplete:"one-time-code","onUpdate:modelValue":e[0]||(e[0]=u=>this.totp=u),disabled:this.verified},null,8,q),[[_,this.totp]]),t("div",A,[i(o,{t:this.totpInvalidMessage},null,8,["t"])]),t("div",E,[i(o,{t:"TOTP verified!"})])])]),e[4]||(e[4]=t("hr",null,null,-1)),t("div",F,[this.verified?(n(),r(l,{key:1,to:"/",class:"btn btn-dark btn-lg d-flex btn-brand shadow align-items-center flex-grow-1 rounded-3"},{default:c(()=>[i(o,{t:"Complete"}),e[3]||(e[3]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1})):(n(),r(l,{key:0,to:"/",class:"btn bg-secondary-subtle text-secondary-emphasis rounded-3 flex-grow-1 btn-lg border-1 border-secondary-subtle shadow d-flex"},{default:c(()=>[i(o,{t:"I don't need MFA"}),e[2]||(e[2]=t("i",{class:"bi bi-chevron-right ms-auto"},null,-1))]),_:1}))])])])],8,k)}const H=h(T,[["render",Q]]);export{H as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as h,c as o,a as t,b as n,h as r,m as g,y as b,I as y,w as c,k as u,g as f,W as x,f as l,e as v,F as m,i as _,s as k,n as T,t as i}from"./index-DXzxfcZW.js";import{O as A}from"./osmap-VxPm4_Yh.js";import{L as w}from"./localeText-Dmcj5qqx.js";import"./Vector-CuSZivra.js";const R={name:"traceroute",components:{LocaleText:w,OSMap:A},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:x()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,f("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},M={class:"mt-md-5 mt-3 text-body"},S={class:"container-md"},$={class:"mb-3 text-body"},L={class:"d-flex gap-2 mb-3 flex-column"},C={class:"flex-grow-1"},P={class:"mb-1 text-muted",for:"ipAddress"},I=["disabled"],O=["disabled"],V={key:0,class:"d-block"},B={key:1,class:"d-block"},N={class:"position-relative"},z={key:"pingPlaceholder"},D={key:1},E={key:"table",class:"w-100 mt-2"},F={class:"table table-sm rounded-3 w-100"},G={scope:"col"},H={scope:"col"},K={scope:"col"},W={scope:"col"},U={scope:"col"},j={scope:"col"},q={key:0},J={key:1};function Q(d,s,X,Y,Z,tt){const a=r("LocaleText"),p=r("OSMap");return l(),o("div",M,[t("div",S,[t("h3",$,[n(a,{t:"Traceroute"})]),t("div",L,[t("div",C,[t("label",P,[t("small",null,[n(a,{t:"Enter IP Address / Hostname"})])]),g(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control rounded-3","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=y(e=>this.execute(),["enter"])),type:"text"},null,40,I),[[b,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 position-relative flex-grow-1",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(u,{name:"slide"},{default:c(()=>[this.tracing?(l(),o("span",B,[...s[4]||(s[4]=[t("span",{class:"spinner-border spinner-border-sm","aria-hidden":"true"},null,-1),t("span",{class:"visually-hidden",role:"status"},"Loading...",-1)])])):(l(),o("span",V,[...s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),v("Trace! ",-1)])]))]),_:1})],8,O)]),t("div",N,[n(u,{name:"ping"},{default:c(()=>[this.tracerouteResult?(l(),o("div",D,[n(p,{d:this.tracerouteResult,type:"traceroute"},null,8,["d"]),t("div",E,[t("table",F,[t("thead",null,[t("tr",null,[t("th",G,[n(a,{t:"Hop"})]),t("th",H,[n(a,{t:"IP Address"})]),t("th",K,[n(a,{t:"Average RTT (ms)"})]),t("th",W,[n(a,{t:"Min RTT (ms)"})]),t("th",U,[n(a,{t:"Max RTT (ms)"})]),t("th",j,[n(a,{t:"Geolocation"})])])]),t("tbody",null,[(l(!0),o(m,null,_(this.tracerouteResult,(e,et)=>(l(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,[t("samp",null,i(e.ip),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.avg_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.min_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.max_rtt),1)])]),t("td",null,[e.geo&&e.geo.city&&e.geo.country?(l(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):(l(),o("span",J," - "))])]))),256))])])])])):(l(),o("div",z,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(l(),o(m,null,_(5,e=>t("div",{class:T(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:k({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const at=h(R,[["render",Q],["__scopeId","data-v-125b538b"]]);export{at as default};
|
||||
import{_ as h,c as o,a as t,b as n,h as r,m as g,y as b,I as y,w as c,k as u,g as f,W as x,f as l,e as v,F as m,i as _,s as k,n as T,t as i}from"./index-DM7YJCOo.js";import{O as A}from"./osmap-BMy-ioUU.js";import{L as w}from"./localeText-BJvnc1lF.js";import"./Vector-CuSZivra.js";const R={name:"traceroute",components:{LocaleText:w,OSMap:A},data(){return{tracing:!1,ipAddress:void 0,tracerouteResult:void 0}},setup(){return{store:x()}},methods:{execute(){this.ipAddress&&(this.tracing=!0,this.tracerouteResult=void 0,f("/api/traceroute/execute",{ipAddress:this.ipAddress},d=>{d.status?this.tracerouteResult=d.data:this.store.newMessage("Server",d.message,"danger"),this.tracing=!1}))}}},M={class:"mt-md-5 mt-3 text-body"},S={class:"container-md"},$={class:"mb-3 text-body"},L={class:"d-flex gap-2 mb-3 flex-column"},C={class:"flex-grow-1"},P={class:"mb-1 text-muted",for:"ipAddress"},I=["disabled"],O=["disabled"],V={key:0,class:"d-block"},B={key:1,class:"d-block"},N={class:"position-relative"},z={key:"pingPlaceholder"},D={key:1},E={key:"table",class:"w-100 mt-2"},F={class:"table table-sm rounded-3 w-100"},G={scope:"col"},H={scope:"col"},K={scope:"col"},W={scope:"col"},U={scope:"col"},j={scope:"col"},q={key:0},J={key:1};function Q(d,s,X,Y,Z,tt){const a=r("LocaleText"),p=r("OSMap");return l(),o("div",M,[t("div",S,[t("h3",$,[n(a,{t:"Traceroute"})]),t("div",L,[t("div",C,[t("label",P,[t("small",null,[n(a,{t:"Enter IP Address / Hostname"})])]),g(t("input",{disabled:this.tracing,id:"ipAddress",class:"form-control rounded-3","onUpdate:modelValue":s[0]||(s[0]=e=>this.ipAddress=e),onKeyup:s[1]||(s[1]=y(e=>this.execute(),["enter"])),type:"text"},null,40,I),[[b,this.ipAddress]])]),t("button",{class:"btn btn-primary rounded-3 position-relative flex-grow-1",disabled:this.tracing||!this.ipAddress,onClick:s[2]||(s[2]=e=>this.execute())},[n(u,{name:"slide"},{default:c(()=>[this.tracing?(l(),o("span",B,[...s[4]||(s[4]=[t("span",{class:"spinner-border spinner-border-sm","aria-hidden":"true"},null,-1),t("span",{class:"visually-hidden",role:"status"},"Loading...",-1)])])):(l(),o("span",V,[...s[3]||(s[3]=[t("i",{class:"bi bi-person-walking me-2"},null,-1),v("Trace! ",-1)])]))]),_:1})],8,O)]),t("div",N,[n(u,{name:"ping"},{default:c(()=>[this.tracerouteResult?(l(),o("div",D,[n(p,{d:this.tracerouteResult,type:"traceroute"},null,8,["d"]),t("div",E,[t("table",F,[t("thead",null,[t("tr",null,[t("th",G,[n(a,{t:"Hop"})]),t("th",H,[n(a,{t:"IP Address"})]),t("th",K,[n(a,{t:"Average RTT (ms)"})]),t("th",W,[n(a,{t:"Min RTT (ms)"})]),t("th",U,[n(a,{t:"Max RTT (ms)"})]),t("th",j,[n(a,{t:"Geolocation"})])])]),t("tbody",null,[(l(!0),o(m,null,_(this.tracerouteResult,(e,et)=>(l(),o("tr",null,[t("td",null,[t("small",null,i(e.hop),1)]),t("td",null,[t("small",null,[t("samp",null,i(e.ip),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.avg_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.min_rtt),1)])]),t("td",null,[t("small",null,[t("samp",null,i(e.max_rtt),1)])]),t("td",null,[e.geo&&e.geo.city&&e.geo.country?(l(),o("span",q,[t("small",null,i(e.geo.city)+", "+i(e.geo.country),1)])):(l(),o("span",J," - "))])]))),256))])])])])):(l(),o("div",z,[s[5]||(s[5]=t("div",{class:"pingPlaceholder bg-body-secondary rounded-3 mb-3",style:{height:"300px !important"}},null,-1)),(l(),o(m,null,_(5,e=>t("div",{class:T(["pingPlaceholder bg-body-secondary rounded-3 mb-3",{"animate__animated animate__flash animate__slower animate__infinite":this.tracing}]),style:k({"animation-delay":`${e*.05}s`})},null,6)),64))]))]),_:1})])])])}const at=h(R,[["render",Q],["__scopeId","data-v-125b538b"]]);export{at as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{B as n,D as r,c as i,a as s,b as t,j as l,d as c,u,f as e}from"./index-DXzxfcZW.js";import{L as a}from"./localeText-Dmcj5qqx.js";import{D as _,d as m,e as h,A as p,a as b,b as v,_ as g,c as f}from"./dashboardEmailSettings-BNCV3lPl.js";import"./dayjs.min-C-brjxlJ.js";import"./vue-datepicker-vren6E8j.js";import"./index-CRsyV-e7.js";const A={class:"d-flex gap-3 flex-column"},D={class:"card rounded-3"},y={class:"card-header"},S={class:"my-2"},x={class:"card-body"},I={class:"row g-2"},P={class:"col-sm"},B={class:"col-sm"},C={class:"card rounded-3"},k={class:"card-header"},w={class:"my-2"},L={class:"card-body"},F={class:"card rounded-3"},M={class:"card-header"},N={class:"my-2"},V={class:"card-body d-flex flex-column gap-3"},G=n({__name:"wgdashboardSettings",setup(T){const d=r();return(U,o)=>(e(),i("div",A,[s("div",D,[s("div",y,[s("h6",S,[o[0]||(o[0]=s("i",{class:"bi bi-magic me-2"},null,-1)),t(a,{t:"Appearance"})])]),s("div",x,[s("div",I,[s("div",P,[t(_)]),s("div",B,[t(m)])])])]),s("div",C,[s("div",k,[s("h6",w,[o[1]||(o[1]=s("i",{class:"bi bi-ethernet me-2"},null,-1)),t(a,{t:"Dashboard IP Address & Listen Port"})])]),s("div",L,[t(h)])]),s("div",F,[s("div",M,[s("h6",N,[o[2]||(o[2]=s("i",{class:"bi bi-people-fill me-2"},null,-1)),t(a,{t:"Account Settings"})])]),s("div",V,[s("div",null,[t(p,{targetData:"username",title:"Username"})]),o[3]||(o[3]=s("hr",null,null,-1)),s("div",null,[t(b,{targetData:"password"})]),o[4]||(o[4]=s("hr",null,null,-1)),s("div",null,[s("h6",null,[t(a,{t:"Multi-Factor Authentication (MFA)"})]),u(d).getActiveCrossServer()?c("",!0):(e(),l(f,{key:0}))])])]),t(v),t(g)]))}});export{G as default};
|
||||
import{B as n,D as r,c as i,a as s,b as t,j as l,d as c,u,f as e}from"./index-DM7YJCOo.js";import{L as a}from"./localeText-BJvnc1lF.js";import{D as _,d as m,e as h,A as p,a as b,b as v,_ as g,c as f}from"./dashboardEmailSettings-DBnS2OTV.js";import"./dayjs.min-DZl6XMNW.js";import"./vue-datepicker-9N8DgATH.js";import"./index-i3npkoSo.js";const A={class:"d-flex gap-3 flex-column"},D={class:"card rounded-3"},y={class:"card-header"},S={class:"my-2"},x={class:"card-body"},I={class:"row g-2"},P={class:"col-sm"},B={class:"col-sm"},C={class:"card rounded-3"},k={class:"card-header"},w={class:"my-2"},L={class:"card-body"},F={class:"card rounded-3"},M={class:"card-header"},N={class:"my-2"},V={class:"card-body d-flex flex-column gap-3"},G=n({__name:"wgdashboardSettings",setup(T){const d=r();return(U,o)=>(e(),i("div",A,[s("div",D,[s("div",y,[s("h6",S,[o[0]||(o[0]=s("i",{class:"bi bi-magic me-2"},null,-1)),t(a,{t:"Appearance"})])]),s("div",x,[s("div",I,[s("div",P,[t(_)]),s("div",B,[t(m)])])])]),s("div",C,[s("div",k,[s("h6",w,[o[1]||(o[1]=s("i",{class:"bi bi-ethernet me-2"},null,-1)),t(a,{t:"Dashboard IP Address & Listen Port"})])]),s("div",L,[t(h)])]),s("div",F,[s("div",M,[s("h6",N,[o[2]||(o[2]=s("i",{class:"bi bi-people-fill me-2"},null,-1)),t(a,{t:"Account Settings"})])]),s("div",V,[s("div",null,[t(p,{targetData:"username",title:"Username"})]),o[3]||(o[3]=s("hr",null,null,-1)),s("div",null,[t(b,{targetData:"password"})]),o[4]||(o[4]=s("hr",null,null,-1)),s("div",null,[s("h6",null,[t(a,{t:"Multi-Factor Authentication (MFA)"})]),u(d).getActiveCrossServer()?c("",!0):(e(),l(f,{key:0}))])])]),t(v),t(g)]))}});export{G as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+28
-2
@@ -11,6 +11,26 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WGDashboard</title>
|
||||
<base href="./">
|
||||
<style>
|
||||
#preloader{
|
||||
width: 100vw; height: 100vh; display: flex
|
||||
}
|
||||
#preloader_placeholder{
|
||||
width: 50px; height: 50px; background-color: #000; margin: auto;
|
||||
animation: 3s ease-in-out fadeInPreloader infinite;
|
||||
}
|
||||
@keyframes fadeInPreloader {
|
||||
0%{
|
||||
opacity: 0;
|
||||
}
|
||||
50%{
|
||||
opacity: 1;
|
||||
}
|
||||
100%{
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const isViteDevMode = document.querySelector('script[src*="@vite/client"]') !== null;
|
||||
const base = document.querySelector('base');
|
||||
@@ -18,10 +38,16 @@
|
||||
base.href = '/';
|
||||
}
|
||||
</script>
|
||||
<script type="module" crossorigin src="./assets/index-DXzxfcZW.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-DM7YJCOo.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-DOyBHXAH.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
<div id="preloader">
|
||||
<div id="preloader_placeholder">
|
||||
<img style="width: 100%" src="./img/Logo-2-128x128.png" alt="WGDashboard Admin" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
canvas[data-v-ec841c31]{width:250px!important;height:250px!important}.qrcodeContainer[data-v-83f277d2]{background-color:#00000050;backdrop-filter:blur(8px) brightness(.7);z-index:9999}.button-group a[data-v-5e50834a]:hover{background-color:#ffffff20}.dot[data-v-5e50834a]{width:10px;height:10px;border-radius:50px;display:inline-block;margin-left:auto!important;background-color:#6c757d}.dot.active[data-v-5e50834a]{background-color:#28a745!important;box-shadow:0 0 0 .2rem #28a74545}.nav-link[data-v-9bb8c5cf]{padding:1rem}@media screen and (max-width: 576px){.nav-links a span[data-v-9bb8c5cf]{display:none}}.card[data-v-9bb8c5cf],.card[data-v-c81aa653]{background-color:#00000040;backdrop-filter:blur(8px)}
|
||||
File diff suppressed because one or more lines are too long
+2
-2
@@ -36,8 +36,8 @@
|
||||
base.href = '/';
|
||||
}
|
||||
</script>
|
||||
<script type="module" crossorigin src="./assets/index-oNzmMgcK.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BGKUQnbP.css">
|
||||
<script type="module" crossorigin src="./assets/index-B0IcYqqq.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-DZ4pmfoO.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
|
||||
Reference in New Issue
Block a user