diff --git a/AppImage/ProxMenux-1.2.3.AppImage b/AppImage/ProxMenux-1.2.3.AppImage index c28d79a8..5aaacf21 100755 Binary files a/AppImage/ProxMenux-1.2.3.AppImage and b/AppImage/ProxMenux-1.2.3.AppImage differ diff --git a/AppImage/ProxMenux-Monitor.AppImage.sha256 b/AppImage/ProxMenux-Monitor.AppImage.sha256 index a5524aa8..ad1abc7d 100644 --- a/AppImage/ProxMenux-Monitor.AppImage.sha256 +++ b/AppImage/ProxMenux-Monitor.AppImage.sha256 @@ -1 +1 @@ -cd07523bc6d5127029d352fcd9488bb90b37c42809d5061cb22aa8a442f036bb ProxMenux-1.2.3.AppImage +7b5dd3ff6fe70a190caf00d1ce5198dfe1917af53d01ab4fd1a3908f3204c0ff ProxMenux-1.2.3.AppImage diff --git a/AppImage/scripts/flask_notification_routes.py b/AppImage/scripts/flask_notification_routes.py index cb445d4b..6f1227e9 100644 --- a/AppImage/scripts/flask_notification_routes.py +++ b/AppImage/scripts/flask_notification_routes.py @@ -227,6 +227,14 @@ def _is_own_host_ip(value: str) -> bool: CGNAT, WireGuard, LAN, IPv6 GUA…). Without this, PVE hits the layer 3 ``X-ProxMenux-Timestamp`` check — a header PVE cannot inject dynamically — and every notification target test returns ``401 missing_timestamp``. + + IMPORTANT: Flask bound to ``*:8008`` (dual-stack) reports IPv4 peers + in v4-mapped IPv6 form (``::ffff:192.168.0.55``). psutil reports the + same interface as plain IPv4 (``192.168.0.55``). Without unmapping, + literal comparison fails and the fix effectively does nothing in + production — reproduced end-to-end on 192.168.0.55: passing the raw + literal returned True, but ``::ffff:192.168.0.55`` returned False, + which is what Flask actually hands us at runtime. """ if _is_loopback_addr(value): return True @@ -234,7 +242,11 @@ def _is_own_host_ip(value: str) -> bool: import ipaddress import socket import psutil - client = ipaddress.ip_address(value).compressed + addr = ipaddress.ip_address(value) + mapped = getattr(addr, 'ipv4_mapped', None) + if mapped is not None: + addr = mapped + client = addr.compressed for _iface, addrs in psutil.net_if_addrs().items(): for a in addrs: if a.family in (socket.AF_INET, socket.AF_INET6):