feat: add ACME account management with validation pipeline

- Register, view, and deactivate ACME accounts via API and UI
- 16-check validation framework for certificate issuance readiness
- DNS resolution, port, nginx, and firewall pre-flight checks
- External IP detection with NAT support and fallback providers
- Account card and settings modal in certificates page
- Guard certificate issuance behind account registration
- Update modal CSS to overlay-based approach
- 1000+ lines of tests for validation and account handlers
This commit is contained in:
2026-06-23 14:24:19 +00:00
parent 3a325504ec
commit 5025dfaf30
19 changed files with 2073 additions and 141 deletions
+3 -19
View File
@@ -19,7 +19,6 @@ _cli_path=""
_cli_mgmt_pass=""
_cli_mgmt_user=""
_cli_mgmt_domain=""
_cli_acme_email=""
_cli_force_venv=false
_cli_wan_iface=""
_cli_lan_ifaces=""
@@ -31,7 +30,6 @@ while [[ $# -gt 0 ]]; do
--mgmt-pass) _cli_mgmt_pass="$2"; shift 2 ;;
--mgmt-user) _cli_mgmt_user="$2"; shift 2 ;;
--mgmt-domain) _cli_mgmt_domain="$2"; shift 2 ;;
--acme-email) _cli_acme_email="$2"; shift 2 ;;
--force-venv) _cli_force_venv=true; shift ;;
--wan-iface) _cli_wan_iface="$2"; shift 2 ;;
--lan-ifaces) _cli_lan_ifaces="$2"; shift 2 ;;
@@ -46,8 +44,7 @@ while [[ $# -gt 0 ]]; do
" --mgmt-pass PASS WebUI basic auth password (required)" \
" --mgmt-user USER WebUI basic auth username (default: admin)" \
" --mgmt-domain DOMAIN Management domain (auto-detected)" \
" --acme-email EMAIL ACME contact email (optional, deprecated — use WebUI)" \
" --wan-iface IFACE WAN interface name (auto-detected)" \
" --wan-iface IFACE WAN interface name (auto-detected)" \
" --lan-ifaces IFC,... LAN interface names, comma-separated (auto-detected)" \
" -h, --help Show this help" \
"" \
@@ -74,9 +71,6 @@ REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
# Required settings (no defaults — must be provided)
MGMT_PASS="${_cli_mgmt_pass:-${MGMT_PASS:-}}"
# ACME_EMAIL is optional — will be configured from the WebUI
ACME_EMAIL="${_cli_acme_email:-${ACME_EMAIL:-}}"
# Optional settings with defaults
MGMT_USER="${_cli_mgmt_user:-${MGMT_USER:-admin}}"
@@ -364,20 +358,18 @@ else
MGMT_DOMAIN="$DOMAIN" \
MGMT_USER="$MGMT_USER" \
MGMT_PASS="$MGMT_PASS" \
ACME_EMAIL="$ACME_EMAIL" \
"${PROJECT_DIR}/.venv/bin/python3" -c "
import daemon.client as c
from daemon.iface import (
POST_ACME_SELF_SIGNED, POST_NGINX_MANAGEMENT, POST_NGINX_APPLY,
POST_FIREWALL_CONFIG, POST_FIREWALL_CONFIG_APPLY, POST_NETWORK_SYSCTL_SET,
POST_ACME_EMAIL, GET_NETWORK_INFER_DHCP_RANGES,
GET_NETWORK_INFER_DHCP_RANGES,
)
import sys
domain = '${DOMAIN}'
mgmt_user = '${MGMT_USER}'
mgmt_pass = '${MGMT_PASS}'
acme_email = '${ACME_EMAIL}'
wan_iface = '${WAN_IFACE}'
lan_ifaces = '${LAN_IFACES}'
@@ -444,14 +436,6 @@ try:
except Exception as e:
print(f' [network] Warning: {e}', file=sys.stderr)
# ACME email (optional)
if acme_email:
try:
c.post(POST_ACME_EMAIL, {'email': acme_email})
print(f' [acme] Email set to {acme_email}')
except Exception as e:
print(f' [acme] Warning: {e}', file=sys.stderr)
# Infer DHCP ranges (logged for user reference)
try:
ranges = c.get(GET_NETWORK_INFER_DHCP_RANGES)
@@ -494,7 +478,7 @@ else
fi
echo ""
echo " Next steps:"
echo " 1. Set ACME contact email at https://$DOMAIN/certs/settings"
echo " 1. Register your ACME account at https://$DOMAIN/certs"
echo " 2. Verify zone assignments at https://$DOMAIN/interfaces"
echo " 3. Configure DHCP ranges for your LAN"
echo " 4. Add proxy domains with ACME certificates"