fix: ECC cert support, ACME deploy hook path, NAT detection, and account config fallback

- Add find_cert_dir() to resolve both RSA and ECC (domain_ecc/) cert dirs
- Copy acme deploy hook to /deploy/ where acme.sh resolves it
- _parse_account_conf checks both legacy .account.conf and declarative config
- Skip public DNS check when all local IPs are private (NAT)
- Improve check message strings for validity and expiry status
- Support timezone-aware date formats in _days_until parsing
- Filter out "no" SAN domains in cert listing
- Bump frontend asset version cache keys
- Fix DOMContentLoaded race condition in app.js boot
- Fix spread operator in certs.js modal template
This commit is contained in:
2026-06-27 14:23:40 +00:00
parent 398831b6e2
commit 8feb56faf6
12 changed files with 250 additions and 105 deletions
+7 -2
View File
@@ -13,6 +13,7 @@ from typing import Any
from jinja2 import Environment, FileSystemLoader
from lib.acme import find_cert_dir
from lib.common import ensure_dirs, load_json, save_json
logger = logging.getLogger(__name__)
@@ -206,6 +207,8 @@ def generate_server_conf(domain_cfg: dict[str, Any]) -> str:
The complete nginx server-block configuration as a string.
"""
tmpl = ENV.get_template("nginx/server_block.conf")
acme_home_path = PROJECT_DIR / "data" / "acme"
acme_cert_dir = str(find_cert_dir(domain_cfg["domain"], acme_home_path))
return tmpl.render(
domain=domain_cfg["domain"],
backend=domain_cfg.get("backend", {}),
@@ -214,7 +217,7 @@ def generate_server_conf(domain_cfg: dict[str, Any]) -> str:
cert=domain_cfg.get("cert"),
auth=domain_cfg.get("auth"),
is_management=False,
acme_home=str(PROJECT_DIR / "data" / "acme"),
acme_cert_dir=acme_cert_dir,
certs_dir=str(PROJECT_DIR / "data" / "certs"),
acme_webroot=str(PROJECT_DIR / "data" / "acme" / "www"),
)
@@ -230,6 +233,8 @@ def _generate_management_conf(management: dict[str, Any]) -> str:
The complete nginx server-block configuration for the management UI.
"""
tmpl = ENV.get_template("nginx/server_block.conf")
acme_home_path = PROJECT_DIR / "data" / "acme"
acme_cert_dir = str(find_cert_dir(management.get("domain", ""), acme_home_path))
return tmpl.render(
domain=management.get("domain"),
backend=dict(
@@ -240,7 +245,7 @@ def _generate_management_conf(management: dict[str, Any]) -> str:
cert=None,
auth=management.get("auth"),
is_management=True,
acme_home=str(PROJECT_DIR / "data" / "acme"),
acme_cert_dir=acme_cert_dir,
certs_dir=str(PROJECT_DIR / "data" / "certs"),
acme_webroot=str(PROJECT_DIR / "data" / "acme" / "www"),
)