mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-10-04 08:16:17 +00:00
Compare commits
14 Commits
docker-ent
...
v4.3.1-dev
Author | SHA1 | Date | |
---|---|---|---|
|
1faabd37af | ||
|
c18ec5c83c | ||
|
d8c89056cb | ||
|
8b541229d8 | ||
|
b7e65f7caf | ||
|
2eda18f18d | ||
|
d06709aeab | ||
|
3de22ed2d6 | ||
|
a9036590a9 | ||
|
8f8843d449 | ||
|
6a21702768 | ||
|
56552d0a83 | ||
|
bd17b9080a | ||
|
bf28983229 |
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -8,24 +8,24 @@ updates:
|
|||||||
- package-ecosystem: "pip"
|
- package-ecosystem: "pip"
|
||||||
directory: "/src"
|
directory: "/src"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
|
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/src/static/app"
|
directory: "/src/static/app"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
|
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/.github"
|
directory: "/.github"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
|
|
||||||
- package-ecosystem: "docker"
|
- package-ecosystem: "docker"
|
||||||
directory: "/docker"
|
directory: "/docker"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
|
|
||||||
- package-ecosystem: "docker-compose"
|
- package-ecosystem: "docker-compose"
|
||||||
directory: "/docker"
|
directory: "/docker"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "daily"
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@ __pycache__
|
|||||||
src/test.py
|
src/test.py
|
||||||
*.db
|
*.db
|
||||||
src/wg-dashboard.ini
|
src/wg-dashboard.ini
|
||||||
|
src/ssl-tls.ini
|
||||||
src/static/pic.xd
|
src/static/pic.xd
|
||||||
*.conf
|
*.conf
|
||||||
private_key.txt
|
private_key.txt
|
||||||
|
@@ -104,6 +104,7 @@ ARG wg_port="51820"
|
|||||||
ENV TZ="Europe/Amsterdam" \
|
ENV TZ="Europe/Amsterdam" \
|
||||||
global_dns="9.9.9.9" \
|
global_dns="9.9.9.9" \
|
||||||
wgd_port="10086" \
|
wgd_port="10086" \
|
||||||
|
log_level="INFO" \
|
||||||
public_ip="" \
|
public_ip="" \
|
||||||
WGDASH=/opt/wgdashboard
|
WGDASH=/opt/wgdashboard
|
||||||
|
|
||||||
@@ -129,6 +130,15 @@ SaveConfig = true\n\
|
|||||||
DNS = ${global_dns}" > /configs/wg0.conf.template \
|
DNS = ${global_dns}" > /configs/wg0.conf.template \
|
||||||
&& chmod 600 /configs/wg0.conf.template
|
&& chmod 600 /configs/wg0.conf.template
|
||||||
|
|
||||||
|
# Replacement of paths with relative ones for namespace handling when using a reverse proxy
|
||||||
|
RUN set -ex && \
|
||||||
|
find ${WGDASH}/src/static/dist -type f \( -name "*.html" -o -name "*.js" \) \
|
||||||
|
-exec sed -i 's|/static/dist|./static/dist|g' {} + && \
|
||||||
|
find ${WGDASH}/src/static/dist -type f -name "*.css" \
|
||||||
|
-exec sed -i 's|/static/dist/WGDashboardClient/assets/|./|g' {} + && \
|
||||||
|
find ${WGDASH}/src/static/dist -type f -name "*.css" \
|
||||||
|
-exec sed -i 's|/static/dist/WGDashboardAdmin/assets/|./|g' {} +
|
||||||
|
|
||||||
# Set a healthcheck to determine the container its health
|
# Set a healthcheck to determine the container its health
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1
|
CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1
|
||||||
|
@@ -102,6 +102,7 @@ Updating the WGDashboard container should be through 'The Docker Way' - by pulli
|
|||||||
| `global_dns` | IPv4 and IPv6 addresses | `9.9.9.9` | `8.8.8.8`, `1.1.1.1` | Default DNS for WireGuard clients. |
|
| `global_dns` | IPv4 and IPv6 addresses | `9.9.9.9` | `8.8.8.8`, `1.1.1.1` | Default DNS for WireGuard clients. |
|
||||||
| `public_ip` | Public IP address | Retrieved automatically | `253.162.134.73` | Used to generate accurate client configs. Needed if container is NAT’d. |
|
| `public_ip` | Public IP address | Retrieved automatically | `253.162.134.73` | Used to generate accurate client configs. Needed if container is NAT’d. |
|
||||||
| `wgd_port` | Any port that is allowed for the process | `10086` | `443` | This port is used to set the WGDashboard web port. |
|
| `wgd_port` | Any port that is allowed for the process | `10086` | `443` | This port is used to set the WGDashboard web port. |
|
||||||
|
| `log_level` | `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL` | `INFO` | `WARNING` | Sets the severity of the logs being displayed. |
|
||||||
| `username` | Any non‐empty string | `-` | `admin` | Username for the WGDashboard web interface account. |
|
| `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). |
|
| `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. |
|
| `enable_totp` | `true`, `false` | `true` | `false` | Enable TOTP‐based two‐factor authentication for the account. |
|
||||||
|
@@ -12,7 +12,8 @@ services:
|
|||||||
# Environment variables can be used to configure certain values at startup. Without having to configure it from the dashboard.
|
# Environment variables can be used to configure certain values at startup. Without having to configure it from the dashboard.
|
||||||
# By default its all disabled, but uncomment the following lines to apply these. (uncommenting is removing the # character)
|
# By default its all disabled, but uncomment the following lines to apply these. (uncommenting is removing the # character)
|
||||||
# Refer to the documentation on https://wgdashboard.dev/ for more info on what everything means.
|
# Refer to the documentation on https://wgdashboard.dev/ for more info on what everything means.
|
||||||
#environment:
|
environment:
|
||||||
|
- log_level=WARNING
|
||||||
#- tz= # <--- Set container timezone, default: Europe/Amsterdam.
|
#- tz= # <--- Set container timezone, default: Europe/Amsterdam.
|
||||||
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
|
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
|
||||||
#- wgd_port= # <--- Set the port WGDashboard will use for its web-server.
|
#- wgd_port= # <--- Set the port WGDashboard will use for its web-server.
|
||||||
|
@@ -83,8 +83,6 @@ ensure_installation() {
|
|||||||
mkdir -p /data/db
|
mkdir -p /data/db
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir "${WGDASH}/src/log"
|
|
||||||
|
|
||||||
if [ ! -d "${WGDASH}/src/db" ]; then
|
if [ ! -d "${WGDASH}/src/db" ]; then
|
||||||
ln -s /data/db "${WGDASH}/src/db"
|
ln -s /data/db "${WGDASH}/src/db"
|
||||||
fi
|
fi
|
||||||
@@ -102,7 +100,8 @@ ensure_installation() {
|
|||||||
. "${WGDASH}/src/venv/bin/activate"
|
. "${WGDASH}/src/venv/bin/activate"
|
||||||
|
|
||||||
# Use the bash interpreter to install WGDashboard according to the wgd.sh script.
|
# Use the bash interpreter to install WGDashboard according to the wgd.sh script.
|
||||||
# /bin/bash ./wgd.sh install
|
/bin/bash ./wgd.sh install
|
||||||
|
|
||||||
echo "Looks like the installation succeeded. Moving on."
|
echo "Looks like the installation succeeded. Moving on."
|
||||||
|
|
||||||
# Setup WireGuard if needed
|
# Setup WireGuard if needed
|
||||||
@@ -116,7 +115,7 @@ ensure_installation() {
|
|||||||
|
|
||||||
echo "Done setting template."
|
echo "Done setting template."
|
||||||
else
|
else
|
||||||
echo "Existing wg0 configuration file found, using that."
|
echo "Existing Wireguard configuration file found in /etc/wireguard."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +137,8 @@ set_envvars() {
|
|||||||
|
|
||||||
set_ini Peers remote_endpoint "${public_ip}"
|
set_ini Peers remote_endpoint "${public_ip}"
|
||||||
set_ini Server app_port "${wgd_port}"
|
set_ini Server app_port "${wgd_port}"
|
||||||
|
set_ini Server log_level "${log_level}"
|
||||||
|
|
||||||
# Account settings - process all parameters
|
# Account settings - process all parameters
|
||||||
[[ -n "$username" ]] && echo "Configuring user account:"
|
[[ -n "$username" ]] && echo "Configuring user account:"
|
||||||
# Basic account variables
|
# Basic account variables
|
||||||
@@ -222,4 +222,4 @@ start_and_monitor() {
|
|||||||
# Main execution flow
|
# Main execution flow
|
||||||
ensure_installation
|
ensure_installation
|
||||||
set_envvars
|
set_envvars
|
||||||
start_and_monitor
|
start_and_monitor
|
||||||
|
@@ -72,7 +72,6 @@ def ResponseObject(status=True, message=None, data=None, status_code = 200) -> F
|
|||||||
'''
|
'''
|
||||||
Flask App
|
Flask App
|
||||||
'''
|
'''
|
||||||
app = Flask("WGDashboard", template_folder=os.path.abspath("./static/dist/WGDashboardAdmin"))
|
|
||||||
|
|
||||||
def peerInformationBackgroundThread():
|
def peerInformationBackgroundThread():
|
||||||
global WireguardConfigurations
|
global WireguardConfigurations
|
||||||
@@ -120,7 +119,8 @@ def peerJobScheduleBackgroundThread():
|
|||||||
def gunicornConfig():
|
def gunicornConfig():
|
||||||
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
|
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
|
||||||
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
|
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
|
||||||
return app_ip, app_port
|
|
||||||
|
return app_ip, app_port, log_level
|
||||||
|
|
||||||
def ProtocolsEnabled() -> list[str]:
|
def ProtocolsEnabled() -> list[str]:
|
||||||
from shutil import which
|
from shutil import which
|
||||||
@@ -172,16 +172,7 @@ def startThreads():
|
|||||||
scheduleJobThread = threading.Thread(target=peerJobScheduleBackgroundThread, daemon=True)
|
scheduleJobThread = threading.Thread(target=peerJobScheduleBackgroundThread, daemon=True)
|
||||||
scheduleJobThread.start()
|
scheduleJobThread.start()
|
||||||
|
|
||||||
dictConfig({
|
app = Flask("WGDashboard", template_folder=os.path.abspath("./static/dist/WGDashboardAdmin"))
|
||||||
'version': 1,
|
|
||||||
'formatters': {'default': {
|
|
||||||
'format': '[%(asctime)s] [%(levelname)s] in [%(module)s] %(message)s',
|
|
||||||
}},
|
|
||||||
'root': {
|
|
||||||
'level': 'INFO'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
WireguardConfigurations: dict[str, WireguardConfiguration] = {}
|
WireguardConfigurations: dict[str, WireguardConfiguration] = {}
|
||||||
CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
|
CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
|
||||||
@@ -189,6 +180,7 @@ CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
|
|||||||
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928
|
||||||
app.secret_key = secrets.token_urlsafe(32)
|
app.secret_key = secrets.token_urlsafe(32)
|
||||||
app.json = CustomJsonEncoder(app)
|
app.json = CustomJsonEncoder(app)
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
SystemStatus = SystemStatus()
|
SystemStatus = SystemStatus()
|
||||||
DashboardConfig = DashboardConfig()
|
DashboardConfig = DashboardConfig()
|
||||||
@@ -199,19 +191,44 @@ with app.app_context():
|
|||||||
DashboardPlugins: DashboardPlugins = DashboardPlugins(app, WireguardConfigurations)
|
DashboardPlugins: DashboardPlugins = DashboardPlugins(app, WireguardConfigurations)
|
||||||
DashboardWebHooks: DashboardWebHooks = DashboardWebHooks(DashboardConfig)
|
DashboardWebHooks: DashboardWebHooks = DashboardWebHooks(DashboardConfig)
|
||||||
NewConfigurationTemplates: NewConfigurationTemplates = NewConfigurationTemplates()
|
NewConfigurationTemplates: NewConfigurationTemplates = NewConfigurationTemplates()
|
||||||
|
|
||||||
InitWireguardConfigurationsList(startup=True)
|
InitWireguardConfigurationsList(startup=True)
|
||||||
|
|
||||||
DashboardClients: DashboardClients = DashboardClients(WireguardConfigurations)
|
DashboardClients: DashboardClients = DashboardClients(WireguardConfigurations)
|
||||||
app.register_blueprint(createClientBlueprint(WireguardConfigurations, DashboardConfig, DashboardClients))
|
app.register_blueprint(
|
||||||
|
createClientBlueprint(WireguardConfigurations, DashboardConfig, DashboardClients)
|
||||||
|
)
|
||||||
|
|
||||||
_, APP_PREFIX = DashboardConfig.GetConfig("Server", "app_prefix")
|
_, APP_PREFIX = DashboardConfig.GetConfig("Server", "app_prefix")
|
||||||
|
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
|
||||||
|
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
|
||||||
|
_, WG_CONF_PATH = DashboardConfig.GetConfig("Server", "wg_conf_path")
|
||||||
|
_, log_level = DashboardConfig.GetConfig("Server", "log_level")
|
||||||
|
|
||||||
cors = CORS(app, resources={rf"{APP_PREFIX}/api/*": {
|
cors = CORS(app, resources={rf"{APP_PREFIX}/api/*": {
|
||||||
"origins": "*",
|
"origins": "*",
|
||||||
"methods": "DELETE, POST, GET, OPTIONS",
|
"methods": "DELETE, POST, GET, OPTIONS",
|
||||||
"allow_headers": ["Content-Type", "wg-dashboard-apikey"]
|
"allow_headers": ["Content-Type", "wg-dashboard-apikey"]
|
||||||
}})
|
}})
|
||||||
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
|
|
||||||
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
|
app.logger.setLevel(getattr(logging, log_level.upper(), logging.INFO))
|
||||||
_, WG_CONF_PATH = DashboardConfig.GetConfig("Server", "wg_conf_path")
|
|
||||||
|
dictConfig({
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'formatters': {
|
||||||
|
'default': {
|
||||||
|
'format': '[%(asctime)s] [%(levelname)s] in [%(module)s] %(message)s',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'wsgi': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
||||||
|
'formatter': 'default',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
'''
|
'''
|
||||||
API Routes
|
API Routes
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import dashboard
|
import dashboard
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger, Dash
|
global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger, Dash
|
||||||
app_host, app_port = dashboard.gunicornConfig()
|
app_host, app_port, log_level = dashboard.gunicornConfig()
|
||||||
date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
|
date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
|
||||||
|
|
||||||
def post_worker_init(worker):
|
def post_worker_init(worker):
|
||||||
@@ -16,7 +16,7 @@ daemon = True
|
|||||||
pidfile = './gunicorn.pid'
|
pidfile = './gunicorn.pid'
|
||||||
wsgi_app = "dashboard:app"
|
wsgi_app = "dashboard:app"
|
||||||
accesslog = f"./log/access_{date}.log"
|
accesslog = f"./log/access_{date}.log"
|
||||||
loglevel = "info"
|
loglevel = f"{log_level}"
|
||||||
capture_output = True
|
capture_output = True
|
||||||
errorlog = f"./log/error_{date}.log"
|
errorlog = f"./log/error_{date}.log"
|
||||||
pythonpath = "., ./modules"
|
pythonpath = "., ./modules"
|
||||||
|
@@ -174,7 +174,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
|
|||||||
|
|
||||||
def getPeers(self):
|
def getPeers(self):
|
||||||
self.Peers.clear()
|
self.Peers.clear()
|
||||||
current_app.logger.info(f"Refreshing {self.Name} peer list")
|
current_app.logger.debug(f"Refreshing {self.Name} peer list")
|
||||||
|
|
||||||
if self.configurationFileChanged():
|
if self.configurationFileChanged():
|
||||||
with open(self.configPath, 'r') as configFile:
|
with open(self.configPath, 'r') as configFile:
|
||||||
@@ -183,7 +183,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
|
|||||||
content = configFile.read().split('\n')
|
content = configFile.read().split('\n')
|
||||||
try:
|
try:
|
||||||
if "[Peer]" not in content:
|
if "[Peer]" not in content:
|
||||||
current_app.logger.info(f"{self.Name} config has no [Peer] section")
|
current_app.logger.debug(f"{self.Name} config has no [Peer] section")
|
||||||
return
|
return
|
||||||
|
|
||||||
peerStarts = content.index("[Peer]")
|
peerStarts = content.index("[Peer]")
|
||||||
|
@@ -1,25 +1,47 @@
|
|||||||
|
# ConnectionString.py
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
from sqlalchemy_utils import database_exists, create_database
|
from sqlalchemy_utils import database_exists, create_database
|
||||||
from flask import current_app
|
|
||||||
|
|
||||||
def ConnectionString(database) -> str:
|
default_db = "wgdashboard"
|
||||||
|
default_log_db = "wgdashboard_log"
|
||||||
|
default_job_db = "wgdashboard_job"
|
||||||
|
sqlite_path = "db"
|
||||||
|
if os.path.exists(sqlite_path):
|
||||||
|
os.makedirs(sqlite_path, exist_ok=True)
|
||||||
|
|
||||||
|
def ConnectionString(database_name: str) -> str:
|
||||||
|
"""
|
||||||
|
Returns a SQLAlchemy-compatible connection string for the chosen database.
|
||||||
|
Creates the database if it doesn't exist.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Read and parse the INI file once at startup
|
||||||
parser = configparser.ConfigParser(strict=False)
|
parser = configparser.ConfigParser(strict=False)
|
||||||
parser.read_file(open('wg-dashboard.ini', "r+"))
|
parser.read("wg-dashboard.ini")
|
||||||
sqlitePath = os.path.join("db")
|
|
||||||
if not os.path.isdir(sqlitePath):
|
db_type = parser.get("Database", "type")
|
||||||
os.mkdir(sqlitePath)
|
db_prefix = parser.get("Database", "prefix")
|
||||||
if parser.get("Database", "type") == "postgresql":
|
database_name = f"{db_prefix}{database_name}"
|
||||||
cn = f'postgresql+psycopg://{parser.get("Database", "username")}:{parser.get("Database", "password")}@{parser.get("Database", "host")}/{database}'
|
|
||||||
elif parser.get("Database", "type") == "mysql":
|
if db_type == "postgresql":
|
||||||
cn = f'mysql+pymysql://{parser.get("Database", "username")}:{parser.get("Database", "password")}@{parser.get("Database", "host")}/{database}'
|
username = parser.get("Database", "username")
|
||||||
|
password = parser.get("Database", "password")
|
||||||
|
host = parser.get("Database", "host")
|
||||||
|
cn = f"postgresql+psycopg://{username}:{password}@{host}/{database_name}"
|
||||||
|
elif db_type == "mysql":
|
||||||
|
username = parser.get("Database", "username")
|
||||||
|
password = parser.get("Database", "password")
|
||||||
|
host = parser.get("Database", "host")
|
||||||
|
cn = f"mysql+pymysql://{username}:{password}@{host}/{database_name}"
|
||||||
else:
|
else:
|
||||||
cn = f'sqlite:///{os.path.join(sqlitePath, f"{database}.db")}'
|
cn = f'sqlite:///{os.path.join(sqlite_path, f"{database_name}.db")}'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not database_exists(cn):
|
if not database_exists(cn):
|
||||||
create_database(cn)
|
create_database(cn)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error("Database error. Terminating...", e)
|
current_app.logger.critical("Database error. Terminating...", e)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
return cn
|
return cn
|
@@ -8,7 +8,7 @@ import pyotp
|
|||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from .DashboardClientsPeerAssignment import DashboardClientsPeerAssignment
|
from .DashboardClientsPeerAssignment import DashboardClientsPeerAssignment
|
||||||
from .DashboardClientsTOTP import DashboardClientsTOTP
|
from .DashboardClientsTOTP import DashboardClientsTOTP
|
||||||
from .DashboardOIDC import DashboardOIDC
|
from .DashboardOIDC import DashboardOIDC
|
||||||
@@ -20,7 +20,7 @@ from flask import session
|
|||||||
class DashboardClients:
|
class DashboardClients:
|
||||||
def __init__(self, wireguardConfigurations):
|
def __init__(self, wireguardConfigurations):
|
||||||
self.logger = DashboardLogger()
|
self.logger = DashboardLogger()
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.OIDC = DashboardOIDC("Client")
|
self.OIDC = DashboardOIDC("Client")
|
||||||
|
|
||||||
@@ -32,10 +32,10 @@ class DashboardClients:
|
|||||||
db.Column('TotpKey', db.String(500)),
|
db.Column('TotpKey', db.String(500)),
|
||||||
db.Column('TotpKeyVerified', db.Integer),
|
db.Column('TotpKeyVerified', db.Integer),
|
||||||
db.Column('CreatedDate',
|
db.Column('CreatedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP),
|
||||||
server_default=db.func.now()),
|
server_default=db.func.now()),
|
||||||
db.Column('DeletedDate',
|
db.Column('DeletedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP)),
|
||||||
extend_existing=True,
|
extend_existing=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,10 +46,10 @@ class DashboardClients:
|
|||||||
db.Column('ProviderIssuer', db.String(500), nullable=False, index=True),
|
db.Column('ProviderIssuer', db.String(500), nullable=False, index=True),
|
||||||
db.Column('ProviderSubject', db.String(500), nullable=False, index=True),
|
db.Column('ProviderSubject', db.String(500), nullable=False, index=True),
|
||||||
db.Column('CreatedDate',
|
db.Column('CreatedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP),
|
||||||
server_default=db.func.now()),
|
server_default=db.func.now()),
|
||||||
db.Column('DeletedDate',
|
db.Column('DeletedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP)),
|
||||||
extend_existing=True,
|
extend_existing=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,10 +65,10 @@ class DashboardClients:
|
|||||||
db.Column('ResetToken', db.String(255), nullable=False, primary_key=True),
|
db.Column('ResetToken', db.String(255), nullable=False, primary_key=True),
|
||||||
db.Column('ClientID', db.String(255), nullable=False),
|
db.Column('ClientID', db.String(255), nullable=False),
|
||||||
db.Column('CreatedDate',
|
db.Column('CreatedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP),
|
||||||
server_default=db.func.now()),
|
server_default=db.func.now()),
|
||||||
db.Column('ExpiryDate',
|
db.Column('ExpiryDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP)),
|
||||||
extend_existing=True
|
extend_existing=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from .DashboardLogger import DashboardLogger
|
from .DashboardLogger import DashboardLogger
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from .WireguardConfiguration import WireguardConfiguration
|
from .WireguardConfiguration import WireguardConfiguration
|
||||||
@@ -31,7 +31,7 @@ class Assignment:
|
|||||||
class DashboardClientsPeerAssignment:
|
class DashboardClientsPeerAssignment:
|
||||||
def __init__(self, wireguardConfigurations: dict[str, WireguardConfiguration]):
|
def __init__(self, wireguardConfigurations: dict[str, WireguardConfiguration]):
|
||||||
self.logger = DashboardLogger()
|
self.logger = DashboardLogger()
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.wireguardConfigurations = wireguardConfigurations
|
self.wireguardConfigurations = wireguardConfigurations
|
||||||
self.dashboardClientsPeerAssignmentTable = db.Table(
|
self.dashboardClientsPeerAssignmentTable = db.Table(
|
||||||
@@ -41,10 +41,10 @@ class DashboardClientsPeerAssignment:
|
|||||||
db.Column('ConfigurationName', db.String(255)),
|
db.Column('ConfigurationName', db.String(255)),
|
||||||
db.Column('PeerID', db.String(500)),
|
db.Column('PeerID', db.String(500)),
|
||||||
db.Column('AssignedDate',
|
db.Column('AssignedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP),
|
||||||
server_default=db.func.now()),
|
server_default=db.func.now()),
|
||||||
db.Column('UnassignedDate',
|
db.Column('UnassignedDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP)),
|
||||||
extend_existing=True
|
extend_existing=True
|
||||||
)
|
)
|
||||||
self.metadata.create_all(self.engine)
|
self.metadata.create_all(self.engine)
|
||||||
|
@@ -3,19 +3,19 @@ import hashlib
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
|
|
||||||
|
|
||||||
class DashboardClientsTOTP:
|
class DashboardClientsTOTP:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.dashboardClientsTOTPTable = db.Table(
|
self.dashboardClientsTOTPTable = db.Table(
|
||||||
'DashboardClientsTOTPTokens', self.metadata,
|
'DashboardClientsTOTPTokens', self.metadata,
|
||||||
db.Column("Token", db.String(500), primary_key=True, index=True),
|
db.Column("Token", db.String(500), primary_key=True, index=True),
|
||||||
db.Column("ClientID", db.String(500), index=True),
|
db.Column("ClientID", db.String(500), index=True),
|
||||||
db.Column(
|
db.Column(
|
||||||
"ExpireTime", (db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)
|
"ExpireTime", (db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.metadata.create_all(self.engine)
|
self.metadata.create_all(self.engine)
|
||||||
|
@@ -7,7 +7,7 @@ import sqlalchemy as db
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from .Utilities import (
|
from .Utilities import (
|
||||||
GetRemoteEndpoint, ValidateDNSAddress
|
GetRemoteEndpoint, ValidateDNSAddress
|
||||||
)
|
)
|
||||||
@@ -47,7 +47,8 @@ class DashboardConfig:
|
|||||||
"dashboard_sort": "status",
|
"dashboard_sort": "status",
|
||||||
"dashboard_theme": "dark",
|
"dashboard_theme": "dark",
|
||||||
"dashboard_api_key": "false",
|
"dashboard_api_key": "false",
|
||||||
"dashboard_language": "en-US"
|
"dashboard_language": "en-US",
|
||||||
|
"log_level": "INFO"
|
||||||
},
|
},
|
||||||
"Peers": {
|
"Peers": {
|
||||||
"peer_global_DNS": "1.1.1.1",
|
"peer_global_DNS": "1.1.1.1",
|
||||||
@@ -65,7 +66,8 @@ class DashboardConfig:
|
|||||||
"host": "",
|
"host": "",
|
||||||
"port": "",
|
"port": "",
|
||||||
"username": "",
|
"username": "",
|
||||||
"password": ""
|
"password": "",
|
||||||
|
"prefix": ""
|
||||||
},
|
},
|
||||||
"Email":{
|
"Email":{
|
||||||
"server": "",
|
"server": "",
|
||||||
@@ -95,28 +97,14 @@ class DashboardConfig:
|
|||||||
if not exist:
|
if not exist:
|
||||||
self.SetConfig(section, key, value, True)
|
self.SetConfig(section, key, value, True)
|
||||||
|
|
||||||
self.engine = db.create_engine(ConnectionString('wgdashboard'))
|
self.SetConfig("Server", "version", DashboardConfig.DashboardVersion)
|
||||||
|
self.SaveConfig()
|
||||||
|
|
||||||
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.dbMetadata = db.MetaData()
|
self.dbMetadata = db.MetaData()
|
||||||
self.__createAPIKeyTable()
|
self.__createAPIKeyTable()
|
||||||
self.DashboardAPIKeys = self.__getAPIKeys()
|
self.DashboardAPIKeys = self.__getAPIKeys()
|
||||||
self.APIAccessed = False
|
self.APIAccessed = False
|
||||||
self.SetConfig("Server", "version", DashboardConfig.DashboardVersion)
|
|
||||||
|
|
||||||
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":
|
|
||||||
cn = f'mysql+mysqldb://{self.GetConfig("Database", "username")[1]}:{self.GetConfig("Database", "password")[1]}@{self.GetConfig("Database", "host")[1]}/{database}'
|
|
||||||
else:
|
|
||||||
cn = f'sqlite:///{os.path.join(sqlitePath, f"{database}.db")}'
|
|
||||||
if not database_exists(cn):
|
|
||||||
create_database(cn)
|
|
||||||
return cn
|
|
||||||
|
|
||||||
def __createAPIKeyTable(self):
|
def __createAPIKeyTable(self):
|
||||||
self.apiKeyTable = db.Table('DashboardAPIKeys', self.dbMetadata,
|
self.apiKeyTable = db.Table('DashboardAPIKeys', self.dbMetadata,
|
||||||
|
@@ -4,18 +4,18 @@ Dashboard Logger Class
|
|||||||
import uuid
|
import uuid
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db, default_log_db
|
||||||
|
|
||||||
|
|
||||||
class DashboardLogger:
|
class DashboardLogger:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard_log"))
|
self.engine = db.create_engine(ConnectionString(default_log_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.dashboardLoggerTable = db.Table('DashboardLog', self.metadata,
|
self.dashboardLoggerTable = db.Table('DashboardLog', self.metadata,
|
||||||
|
|
||||||
db.Column('LogID', db.String(255), nullable=False, primary_key=True),
|
db.Column('LogID', db.String(255), nullable=False, primary_key=True),
|
||||||
db.Column('LogDate',
|
db.Column('LogDate',
|
||||||
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
(db.DATETIME if 'sqlite:///' in ConnectionString(default_db) else db.TIMESTAMP),
|
||||||
server_default=db.func.now()),
|
server_default=db.func.now()),
|
||||||
db.Column('URL', db.String(255)),
|
db.Column('URL', db.String(255)),
|
||||||
db.Column('IP', db.String(255)),
|
db.Column('IP', db.String(255)),
|
||||||
|
@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
|
|||||||
import requests
|
import requests
|
||||||
from pydantic import BaseModel, field_serializer
|
from pydantic import BaseModel, field_serializer
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
WebHookActions = ['peer_created', 'peer_deleted', 'peer_updated']
|
WebHookActions = ['peer_created', 'peer_deleted', 'peer_updated']
|
||||||
@@ -40,7 +40,7 @@ class WebHookSessionLogs(BaseModel):
|
|||||||
|
|
||||||
class DashboardWebHooks:
|
class DashboardWebHooks:
|
||||||
def __init__(self, DashboardConfig):
|
def __init__(self, DashboardConfig):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.webHooksTable = db.Table(
|
self.webHooksTable = db.Table(
|
||||||
'DashboardWebHooks', self.metadata,
|
'DashboardWebHooks', self.metadata,
|
||||||
@@ -201,7 +201,7 @@ class DashboardWebHooks:
|
|||||||
|
|
||||||
class WebHookSession:
|
class WebHookSession:
|
||||||
def __init__(self, webHook: WebHook, data: dict[str, str]):
|
def __init__(self, webHook: WebHook, data: dict[str, str]):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.webHookSessionsTable = db.Table('DashboardWebHookSessions', self.metadata, autoload_with=self.engine)
|
self.webHookSessionsTable = db.Table('DashboardWebHookSessions', self.metadata, autoload_with=self.engine)
|
||||||
self.webHook = webHook
|
self.webHook = webHook
|
||||||
|
@@ -2,7 +2,7 @@ import uuid
|
|||||||
|
|
||||||
from pydantic import BaseModel, field_serializer
|
from pydantic import BaseModel, field_serializer
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
|
|
||||||
|
|
||||||
class NewConfigurationTemplate(BaseModel):
|
class NewConfigurationTemplate(BaseModel):
|
||||||
@@ -14,7 +14,7 @@ class NewConfigurationTemplate(BaseModel):
|
|||||||
|
|
||||||
class NewConfigurationTemplates:
|
class NewConfigurationTemplates:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.templatesTable = db.Table(
|
self.templatesTable = db.Table(
|
||||||
'NewConfigurationTemplates', self.metadata,
|
'NewConfigurationTemplates', self.metadata,
|
||||||
|
@@ -4,12 +4,12 @@ Peer Job Logger
|
|||||||
import uuid
|
import uuid
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_log_db
|
||||||
from .Log import Log
|
from .Log import Log
|
||||||
|
|
||||||
class PeerJobLogger:
|
class PeerJobLogger:
|
||||||
def __init__(self, AllPeerJobs, DashboardConfig):
|
def __init__(self, AllPeerJobs, DashboardConfig):
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard_log"))
|
self.engine = db.create_engine(ConnectionString(default_log_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.jobLogTable = db.Table('JobLog', self.metadata,
|
self.jobLogTable = db.Table('JobLog', self.metadata,
|
||||||
db.Column('LogID', db.String(255), nullable=False, primary_key=True),
|
db.Column('LogID', db.String(255), nullable=False, primary_key=True),
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Peer Jobs
|
Peer Jobs
|
||||||
"""
|
"""
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_job_db
|
||||||
from .PeerJob import PeerJob
|
from .PeerJob import PeerJob
|
||||||
from .PeerJobLogger import PeerJobLogger
|
from .PeerJobLogger import PeerJobLogger
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
@@ -11,7 +11,7 @@ from flask import current_app
|
|||||||
class PeerJobs:
|
class PeerJobs:
|
||||||
def __init__(self, DashboardConfig, WireguardConfigurations):
|
def __init__(self, DashboardConfig, WireguardConfigurations):
|
||||||
self.Jobs: list[PeerJob] = []
|
self.Jobs: list[PeerJob] = []
|
||||||
self.engine = db.create_engine(ConnectionString('wgdashboard_job'))
|
self.engine = db.create_engine(ConnectionString(default_job_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.peerJobTable = db.Table('PeerJobs', self.metadata,
|
self.peerJobTable = db.Table('PeerJobs', self.metadata,
|
||||||
db.Column('JobID', db.String(255), nullable=False, primary_key=True),
|
db.Column('JobID', db.String(255), nullable=False, primary_key=True),
|
||||||
@@ -141,7 +141,7 @@ class PeerJobs:
|
|||||||
|
|
||||||
|
|
||||||
def runJob(self):
|
def runJob(self):
|
||||||
current_app.logger.info("Running scheduled jobs")
|
current_app.logger.debug("Running scheduled jobs")
|
||||||
needToDelete = []
|
needToDelete = []
|
||||||
self.__getJobs()
|
self.__getJobs()
|
||||||
for job in self.Jobs:
|
for job in self.Jobs:
|
||||||
@@ -184,7 +184,7 @@ class PeerJobs:
|
|||||||
f"Somehow can't find this peer {job.Peer} from {c.Name} failed {job.Action}ed."
|
f"Somehow can't find this peer {job.Peer} from {c.Name} failed {job.Action}ed."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
current_app.logger.warning(f"Somehow can't find this peer {job.Peer} from {job.Configuration} failed {job.Action}ed.")
|
current_app.logger.warning(f"Somehow can't find this peer {job.Peer} from {c.Name} failed {job.Action}ed.")
|
||||||
self.JobLogger.log(job.JobID, False,
|
self.JobLogger.log(job.JobID, False,
|
||||||
f"Somehow can't find this peer {job.Peer} from {job.Configuration} failed {job.Action}ed."
|
f"Somehow can't find this peer {job.Peer} from {job.Configuration} failed {job.Action}ed."
|
||||||
)
|
)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from .PeerShareLink import PeerShareLink
|
from .PeerShareLink import PeerShareLink
|
||||||
import sqlalchemy as db
|
import sqlalchemy as db
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -10,7 +10,7 @@ Peer Share Links
|
|||||||
class PeerShareLinks:
|
class PeerShareLinks:
|
||||||
def __init__(self, DashboardConfig, WireguardConfigurations):
|
def __init__(self, DashboardConfig, WireguardConfigurations):
|
||||||
self.Links: list[PeerShareLink] = []
|
self.Links: list[PeerShareLink] = []
|
||||||
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
self.engine = db.create_engine(ConnectionString(default_db))
|
||||||
self.metadata = db.MetaData()
|
self.metadata = db.MetaData()
|
||||||
self.peerShareLinksTable = db.Table(
|
self.peerShareLinksTable = db.Table(
|
||||||
'PeerShareLinks', self.metadata,
|
'PeerShareLinks', self.metadata,
|
||||||
|
@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
|||||||
from itertools import islice
|
from itertools import islice
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
from .ConnectionString import ConnectionString
|
from .ConnectionString import ConnectionString, default_db
|
||||||
from .DashboardConfig import DashboardConfig
|
from .DashboardConfig import DashboardConfig
|
||||||
from .Peer import Peer
|
from .Peer import Peer
|
||||||
from .PeerJobs import PeerJobs
|
from .PeerJobs import PeerJobs
|
||||||
@@ -64,7 +64,7 @@ class WireguardConfiguration:
|
|||||||
self.AllPeerShareLinks = AllPeerShareLinks
|
self.AllPeerShareLinks = AllPeerShareLinks
|
||||||
self.DashboardWebHooks = DashboardWebHooks
|
self.DashboardWebHooks = DashboardWebHooks
|
||||||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf')
|
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf')
|
||||||
self.engine: sqlalchemy.Engine = sqlalchemy.create_engine(ConnectionString("wgdashboard"))
|
self.engine: sqlalchemy.Engine = sqlalchemy.create_engine(ConnectionString(default_db))
|
||||||
self.metadata: sqlalchemy.MetaData = sqlalchemy.MetaData()
|
self.metadata: sqlalchemy.MetaData = sqlalchemy.MetaData()
|
||||||
self.dbType = self.DashboardConfig.GetConfig("Database", "type")[1]
|
self.dbType = self.DashboardConfig.GetConfig("Database", "type")[1]
|
||||||
|
|
||||||
@@ -396,7 +396,7 @@ class WireguardConfiguration:
|
|||||||
|
|
||||||
def getPeers(self):
|
def getPeers(self):
|
||||||
tmpList = []
|
tmpList = []
|
||||||
current_app.logger.info(f"Refreshing {self.Name} peer list")
|
current_app.logger.debug(f"Refreshing {self.Name} peer list")
|
||||||
|
|
||||||
if self.configurationFileChanged():
|
if self.configurationFileChanged():
|
||||||
with open(self.configPath, 'r') as configFile:
|
with open(self.configPath, 'r') as configFile:
|
||||||
@@ -405,7 +405,7 @@ class WireguardConfiguration:
|
|||||||
content = configFile.read().split('\n')
|
content = configFile.read().split('\n')
|
||||||
try:
|
try:
|
||||||
if "[Peer]" not in content:
|
if "[Peer]" not in content:
|
||||||
current_app.logger.info(f"{self.Name} config has no [Peer] section")
|
current_app.logger.debug(f"{self.Name} config has no [Peer] section")
|
||||||
return
|
return
|
||||||
|
|
||||||
peerStarts = content.index("[Peer]")
|
peerStarts = content.index("[Peer]")
|
||||||
|
213
src/static/app/package-lock.json
generated
213
src/static/app/package-lock.json
generated
@@ -9,7 +9,7 @@
|
|||||||
"version": "4.3.0.1",
|
"version": "4.3.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-server": "2.4.23",
|
"@volar/language-server": "2.4.23",
|
||||||
"@vue/language-server": "3.0.8",
|
"@vue/language-server": "3.0.7",
|
||||||
"@vuepic/vue-datepicker": "^11.0.2",
|
"@vuepic/vue-datepicker": "^11.0.2",
|
||||||
"@vueuse/core": "^13.5.0",
|
"@vueuse/core": "^13.5.0",
|
||||||
"@vueuse/shared": "^13.5.0",
|
"@vueuse/shared": "^13.5.0",
|
||||||
@@ -30,19 +30,19 @@
|
|||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qrcodejs": "^1.0.0",
|
"qrcodejs": "^1.0.0",
|
||||||
"simple-code-editor": "^2.0.9",
|
"simple-code-editor": "^2.0.9",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^13.0.0",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.17",
|
||||||
"vue-chartjs": "^5.3.0",
|
"vue-chartjs": "^5.3.0",
|
||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.0",
|
||||||
"vite": "^7.1.7"
|
"vite": "^7.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
"version": "7.27.1",
|
"version": "7.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-identifier": {
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
"version": "7.27.1",
|
"version": "7.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.28.4",
|
"version": "7.28.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.4.tgz",
|
||||||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.28.4",
|
"version": "7.28.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
|
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.4.tgz",
|
||||||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1036,7 +1036,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.5.5",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -1685,53 +1685,53 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.21.tgz",
|
||||||
"integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==",
|
"integrity": "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.4",
|
"@babel/parser": "^7.28.3",
|
||||||
"@vue/shared": "3.5.22",
|
"@vue/shared": "3.5.21",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.21.tgz",
|
||||||
"integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==",
|
"integrity": "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.22",
|
"@vue/compiler-core": "3.5.21",
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.21.tgz",
|
||||||
"integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
|
"integrity": "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.28.4",
|
"@babel/parser": "^7.28.3",
|
||||||
"@vue/compiler-core": "3.5.22",
|
"@vue/compiler-core": "3.5.21",
|
||||||
"@vue/compiler-dom": "3.5.22",
|
"@vue/compiler-dom": "3.5.21",
|
||||||
"@vue/compiler-ssr": "3.5.22",
|
"@vue/compiler-ssr": "3.5.21",
|
||||||
"@vue/shared": "3.5.22",
|
"@vue/shared": "3.5.21",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.19",
|
"magic-string": "^0.30.18",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.21.tgz",
|
||||||
"integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==",
|
"integrity": "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.22",
|
"@vue/compiler-dom": "3.5.21",
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-vue2": {
|
"node_modules/@vue/compiler-vue2": {
|
||||||
@@ -1778,9 +1778,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/language-core": {
|
"node_modules/@vue/language-core": {
|
||||||
"version": "3.0.8",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.0.7.tgz",
|
||||||
"integrity": "sha512-eYs6PF7bxoPYvek9qxceo1BCwFbJZYqJll+WaYC8o8ec60exqj+n+QRGGiJHSeUfYp0hDxARbMdxMq/fbPgU5g==",
|
"integrity": "sha512-0sqqyqJ0Gn33JH3TdIsZLCZZ8Gr4kwlg8iYOnOrDDkJKSjFurlQY/bEFQx5zs7SX2C/bjMkmPYq/NiyY1fTOkw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-core": "2.4.23",
|
"@volar/language-core": "2.4.23",
|
||||||
@@ -1802,15 +1802,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/language-server": {
|
"node_modules/@vue/language-server": {
|
||||||
"version": "3.0.8",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/language-server/-/language-server-3.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/language-server/-/language-server-3.0.7.tgz",
|
||||||
"integrity": "sha512-FHCLPCO9h3I0kyU9OJBDFUMmeIMM5aDJowIk10HFszxhHD6PZciftO8yE37ED0TFw/OYDBGRT4CJO42UsTM01Q==",
|
"integrity": "sha512-bEEAHJhBqWXAaYtqexRH8kggKm98L8/q69A1DvrIY8E2TwLMS1MKBVSMxerTmZ7Zsstl0ZHL6a/q9duMoBKpUQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-server": "2.4.23",
|
"@volar/language-server": "2.4.23",
|
||||||
"@vue/language-core": "3.0.8",
|
"@vue/language-core": "3.0.7",
|
||||||
"@vue/language-service": "3.0.8",
|
"@vue/language-service": "3.0.7",
|
||||||
"@vue/typescript-plugin": "3.0.8",
|
"@vue/typescript-plugin": "3.0.7",
|
||||||
"vscode-uri": "^3.0.8"
|
"vscode-uri": "^3.0.8"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1821,13 +1821,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/language-service": {
|
"node_modules/@vue/language-service": {
|
||||||
"version": "3.0.8",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/language-service/-/language-service-3.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/language-service/-/language-service-3.0.7.tgz",
|
||||||
"integrity": "sha512-oJpR3cuX/788sZmud4NhcFSTqTb+IjNzt6Ebr0630FlRFmUSYMt1f2mKtAtQD5kjk3d728QaVvbB2DD+BlkNLQ==",
|
"integrity": "sha512-v+XLXuWvk4QgHu0TTJjaIwVu/jrjDpX7ISFu+IrihDusVQ80dm68yrH02Rr4xqKhQos0mwpTbjyC56Ld1eI5Uw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-service": "2.4.23",
|
"@volar/language-service": "2.4.23",
|
||||||
"@vue/language-core": "3.0.8",
|
"@vue/language-core": "3.0.7",
|
||||||
"@vue/shared": "^3.5.0",
|
"@vue/shared": "^3.5.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"volar-service-css": "0.0.65",
|
"volar-service-css": "0.0.65",
|
||||||
@@ -1842,65 +1842,64 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.21.tgz",
|
||||||
"integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==",
|
"integrity": "sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.21.tgz",
|
||||||
"integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==",
|
"integrity": "sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.22",
|
"@vue/reactivity": "3.5.21",
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.21.tgz",
|
||||||
"integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==",
|
"integrity": "sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.22",
|
"@vue/reactivity": "3.5.21",
|
||||||
"@vue/runtime-core": "3.5.22",
|
"@vue/runtime-core": "3.5.21",
|
||||||
"@vue/shared": "3.5.22",
|
"@vue/shared": "3.5.21",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.21.tgz",
|
||||||
"integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==",
|
"integrity": "sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.22",
|
"@vue/compiler-ssr": "3.5.21",
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.5.22"
|
"vue": "3.5.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.21.tgz",
|
||||||
"integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==",
|
"integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/typescript-plugin": {
|
"node_modules/@vue/typescript-plugin": {
|
||||||
"version": "3.0.8",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/typescript-plugin/-/typescript-plugin-3.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/typescript-plugin/-/typescript-plugin-3.0.7.tgz",
|
||||||
"integrity": "sha512-d0sTpi1qi5n2b9T8FZrxDUvq5ttsYu9JnUwEsJ8VBHLSu3YJQjY2WfuZCF4ZZYWo/RtE9ZKvBx7s2HDnH3q1pA==",
|
"integrity": "sha512-WBvIkdrRTRPUhcxxqjkqY56rdUkcb+hWSM1lhCko2H9SXPZoDPUN7ZhtX5rrSZWFvduq3lUmahJFW4IT522tIg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/typescript": "2.4.23",
|
"@volar/typescript": "2.4.23",
|
||||||
"@vue/language-core": "3.0.8",
|
"@vue/language-core": "3.0.7",
|
||||||
"@vue/shared": "^3.5.0",
|
"@vue/shared": "^3.5.0",
|
||||||
"laplacenoma": "^0.0.3",
|
|
||||||
"path-browserify": "^1.0.1"
|
"path-browserify": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2579,15 +2578,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cidr-regex": {
|
"node_modules/cidr-regex": {
|
||||||
"version": "4.1.3",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/cidr-regex/-/cidr-regex-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-5.0.0.tgz",
|
||||||
"integrity": "sha512-86M1y3ZeQvpZkZejQCcS+IaSWjlDUC+ORP0peScQ4uEUFCZ8bEQVz7NlJHqysoUb6w3zCjx4Mq/8/2RHhMwHYw==",
|
"integrity": "sha512-9FT511D25oLAQYkfKLqWUMzoitgITToOqNThDAM8ujXaeXDulDPffJQflag918J8DN8mUPXRpS9J3U5GlIHGSQ==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ip-regex": "^5.0.0"
|
"ip-regex": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cidr-tools": {
|
"node_modules/cidr-tools": {
|
||||||
@@ -2870,7 +2869,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -3297,7 +3296,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/entities": {
|
"node_modules/entities": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3420,7 +3419,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/estree-walker": {
|
"node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -4046,7 +4045,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/ip-regex": {
|
"node_modules/ip-regex": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ip-regex/-/ip-regex-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz",
|
||||||
"integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==",
|
"integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4069,15 +4068,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-cidr": {
|
"node_modules/is-cidr": {
|
||||||
"version": "5.1.1",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/is-cidr/-/is-cidr-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-cidr/-/is-cidr-6.0.0.tgz",
|
||||||
"integrity": "sha512-AwzRMjtJNTPOgm7xuYZ71715z99t+4yRnSnSzgK5err5+heYi4zMuvmpUadaJ28+KCXCQo8CjUrKQZRWSPmqTQ==",
|
"integrity": "sha512-LM62mX6QmYvLL7c0AZ2rnqGUAHcgkNwre56e8rrAdRLjUmwqrOrqGj6E/iVSrL7xxZfGQUR0gBVx9pW5CLIbig==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cidr-regex": "^4.1.1"
|
"cidr-regex": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-expression": {
|
"node_modules/is-expression": {
|
||||||
@@ -4269,12 +4268,6 @@
|
|||||||
"json-buffer": "3.0.1"
|
"json-buffer": "3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/laplacenoma": {
|
|
||||||
"version": "0.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/laplacenoma/-/laplacenoma-0.0.3.tgz",
|
|
||||||
"integrity": "sha512-fsQMsMozEzGg/DhQG73nf8Nzx0XvU8RJFRViYuocM6pQSa33lucnHvJzsb4udQUzH5p5zdX63t9qRahKAhWtiQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/lazy-val": {
|
"node_modules/lazy-val": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz",
|
"resolved": "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||||
@@ -4344,7 +4337,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.19",
|
"version": "0.30.19",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
|
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz",
|
||||||
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
|
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8499,16 +8492,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "11.1.0",
|
"version": "13.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/sponsors/broofa",
|
"https://github.com/sponsors/broofa",
|
||||||
"https://github.com/sponsors/ctavan"
|
"https://github.com/sponsors/ctavan"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist/esm/bin/uuid"
|
"uuid": "dist-node/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/verror": {
|
"node_modules/verror": {
|
||||||
@@ -8527,9 +8520,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "7.1.7",
|
"version": "7.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.6.tgz",
|
||||||
"integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==",
|
"integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8830,16 +8823,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.21",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz",
|
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.21.tgz",
|
||||||
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
|
"integrity": "sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.22",
|
"@vue/compiler-dom": "3.5.21",
|
||||||
"@vue/compiler-sfc": "3.5.22",
|
"@vue/compiler-sfc": "3.5.21",
|
||||||
"@vue/runtime-dom": "3.5.22",
|
"@vue/runtime-dom": "3.5.21",
|
||||||
"@vue/server-renderer": "3.5.22",
|
"@vue/server-renderer": "3.5.21",
|
||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.21"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-server": "2.4.23",
|
"@volar/language-server": "2.4.23",
|
||||||
"@vue/language-server": "3.0.8",
|
"@vue/language-server": "3.0.7",
|
||||||
"@vuepic/vue-datepicker": "^11.0.2",
|
"@vuepic/vue-datepicker": "^11.0.2",
|
||||||
"@vueuse/core": "^13.5.0",
|
"@vueuse/core": "^13.5.0",
|
||||||
"@vueuse/shared": "^13.5.0",
|
"@vueuse/shared": "^13.5.0",
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"electron-builder": "^26.0.12",
|
"electron-builder": "^26.0.12",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"i": "^0.3.7",
|
"i": "^0.3.7",
|
||||||
"is-cidr": "^5.0.3",
|
"is-cidr": "^6.0.0",
|
||||||
"npm": "^11.6.0",
|
"npm": "^11.6.0",
|
||||||
"ol": "^10.2.1",
|
"ol": "^10.2.1",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
@@ -34,13 +34,13 @@
|
|||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"qrcodejs": "^1.0.0",
|
"qrcodejs": "^1.0.0",
|
||||||
"simple-code-editor": "^2.0.9",
|
"simple-code-editor": "^2.0.9",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^13.0.0",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.17",
|
||||||
"vue-chartjs": "^5.3.0",
|
"vue-chartjs": "^5.3.0",
|
||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.0",
|
||||||
"vite": "^7.1.7"
|
"vite": "^7.1.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -114,7 +114,7 @@ const data = computed(() => {
|
|||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress" role="progressbar" style="height: 6px">
|
<div class="progress" role="progressbar" style="height: 6px">
|
||||||
<div class="progress-bar bg-warning" :style="{width: `$ data?.Memory.SwapMemory.percent}%` }"></div>
|
<div class="progress-bar bg-warning" :style="{width: `${data?.Memory.SwapMemory.percent}%` }"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user