From 185d2c889f3fa9daa6800620ea332685aad22579 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 7 Jul 2026 12:41:53 -0500 Subject: [PATCH] =?UTF-8?q?Fix=20AGENT=20button=20showing=20the=20wrong=20?= =?UTF-8?q?machine:=20same-subnet=20fallback=20matched=20whichever=20agent?= =?UTF-8?q?=20happened=20to=20be=20first=20in=20the=20list,=20not=20the=20?= =?UTF-8?q?actual=20browsing=20machine=20=E2=80=94=20happens=20whenever=20?= =?UTF-8?q?a=20LAN=20client=20hits=20the=20dashboard=20via=20hairpin=20NAT?= =?UTF-8?q?/external=20hostname=20and=20the=20server=20sees=20the=20same?= =?UTF-8?q?=20reflected=20IP=20for=20every=20visitor.=20Exact-match=20only?= =?UTF-8?q?=20now;=20falls=20through=20to=20not-detected=20instead=20of=20?= =?UTF-8?q?misreporting=20another=20real=20machine=20as=20yours.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public_html/assets/js/jarvis-app.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/public_html/assets/js/jarvis-app.js b/public_html/assets/js/jarvis-app.js index 1c075e5..cd1c45f 100644 --- a/public_html/assets/js/jarvis-app.js +++ b/public_html/assets/js/jarvis-app.js @@ -1631,11 +1631,18 @@ async function checkAgentStatus() { sta.textContent = online.length > 0 ? online.length + ' ONLINE' : 'NONE'; const cnt = document.getElementById('net-agent-count'); if (cnt) cnt.textContent = online.length + ' AGENT' + (online.length !== 1 ? 'S' : '') + ' ONLINE'; + // Fixed 2026-07-07: this used to fall back to "any agent on the same /24 + // subnet" when the exact IP didn't match, meant to handle NAT — but when + // a LAN client hits the dashboard via its external hostname (hairpin NAT, + // or through Cloudflare), the server sees the SAME single reflected/proxy + // IP for every visitor on the LAN, not each machine's real one. The exact + // match then always fails, and the subnet fallback just grabbed whichever + // agent happened to be first in the list — showing a *different real + // machine* as "yours", not a harmless guess. Exact match only now; if it + // fails, the button correctly falls through to "not detected" instead of + // reporting someone else's agent as this one. const myIp = data.my_ip || ''; - // Match by exact IP first, then by same /24 subnet (handles NAT behind same router) - const mySubnet = myIp.split('.').slice(0,3).join('.'); - _myAgent = online.find(a => a.ip_address === myIp) - || online.find(a => a.ip_address && a.ip_address.startsWith(mySubnet + '.')); + _myAgent = online.find(a => a.ip_address === myIp) || null; _agentOnline = !!_myAgent; if (btn) { const isTablet = detectOS() === 'tablet';