mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
Fix agent detection: real client IP via CF header, tablet/iPad support, subnet fallback match
This commit is contained in:
@@ -213,7 +213,9 @@ switch ($agentAction) {
|
|||||||
foreach ($agents as &$a) {
|
foreach ($agents as &$a) {
|
||||||
$a['capabilities'] = json_decode($a['capabilities'] ?? '[]', true);
|
$a['capabilities'] = json_decode($a['capabilities'] ?? '[]', true);
|
||||||
}
|
}
|
||||||
agent_ok(['agents' => $agents, 'my_ip' => $_SERVER['REMOTE_ADDR'] ?? '']);
|
$realIp = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';
|
||||||
|
$realIp = trim(explode(',', $realIp)[0]);
|
||||||
|
agent_ok(['agents' => $agents, 'my_ip' => $realIp]);
|
||||||
|
|
||||||
// ── LATEST METRICS (for dashboard display) ───────────────────────────────
|
// ── LATEST METRICS (for dashboard display) ───────────────────────────────
|
||||||
case 'status':
|
case 'status':
|
||||||
|
|||||||
+42
-18
@@ -1741,12 +1741,16 @@ function speak(text) {
|
|||||||
|
|
||||||
// ── AGENT DETECTION & BROWSER INSTALL ─────────────────────────────────
|
// ── AGENT DETECTION & BROWSER INSTALL ─────────────────────────────────
|
||||||
let _agentOnline = false;
|
let _agentOnline = false;
|
||||||
|
let _myAgent = null;
|
||||||
|
|
||||||
function detectOS() {
|
function detectOS() {
|
||||||
const ua = navigator.userAgent;
|
const ua = navigator.userAgent;
|
||||||
const p = (navigator.platform || '').toLowerCase();
|
const p = (navigator.platform || '').toLowerCase();
|
||||||
if (p.includes('mac')) return 'mac';
|
// Tablets — check before desktop OS (iPads spoof MacIntel)
|
||||||
|
if (/iPad|Android/.test(ua) || (p.includes('mac') && navigator.maxTouchPoints > 1)) return 'tablet';
|
||||||
|
if (/iPhone/.test(ua)) return 'tablet';
|
||||||
if (p.includes('win') || ua.includes('Windows')) return 'windows';
|
if (p.includes('win') || ua.includes('Windows')) return 'windows';
|
||||||
|
if (p.includes('mac') || ua.includes('Macintosh')) return 'mac';
|
||||||
if (p.includes('linux') || ua.includes('Linux')) return 'linux';
|
if (p.includes('linux') || ua.includes('Linux')) return 'linux';
|
||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
@@ -1765,12 +1769,19 @@ async function checkAgentStatus() {
|
|||||||
const cnt = document.getElementById('net-agent-count');
|
const cnt = document.getElementById('net-agent-count');
|
||||||
if (cnt) cnt.textContent = online.length + ' AGENT' + (online.length !== 1 ? 'S' : '') + ' ONLINE';
|
if (cnt) cnt.textContent = online.length + ' AGENT' + (online.length !== 1 ? 'S' : '') + ' ONLINE';
|
||||||
const myIp = data.my_ip || '';
|
const myIp = data.my_ip || '';
|
||||||
const myAgent = online.find(a => a.ip_address === myIp);
|
// Match by exact IP first, then by same /24 subnet (handles NAT behind same router)
|
||||||
_agentOnline = !!myAgent;
|
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 + '.'));
|
||||||
|
_agentOnline = !!_myAgent;
|
||||||
if (btn) {
|
if (btn) {
|
||||||
if (_agentOnline) {
|
const isTablet = detectOS() === 'tablet';
|
||||||
|
if (isTablet) {
|
||||||
|
btn.title = 'JARVIS Agent — not available for tablets';
|
||||||
|
btn.style.opacity = '0.5';
|
||||||
|
} else if (_agentOnline) {
|
||||||
btn.classList.add('agent-online');
|
btn.classList.add('agent-online');
|
||||||
btn.title = 'Agent active: ' + myAgent.hostname;
|
btn.title = 'Agent active: ' + _myAgent.hostname;
|
||||||
} else {
|
} else {
|
||||||
btn.classList.remove('agent-online');
|
btn.classList.remove('agent-online');
|
||||||
btn.title = 'Click to install JARVIS Agent on this machine';
|
btn.title = 'Click to install JARVIS Agent on this machine';
|
||||||
@@ -1885,24 +1896,35 @@ function openAgentModal() {
|
|||||||
const baseUrl = 'https://jarvis.orbishosting.com/agent';
|
const baseUrl = 'https://jarvis.orbishosting.com/agent';
|
||||||
const jUrl = 'https://jarvis.orbishosting.com';
|
const jUrl = 'https://jarvis.orbishosting.com';
|
||||||
|
|
||||||
if (_agentOnline) {
|
if (os === 'tablet') {
|
||||||
|
title.textContent = '● JARVIS — TABLET / MOBILE';
|
||||||
|
content.innerHTML =
|
||||||
|
'<div style="color:var(--cyan);font-size:0.75rem;margin-bottom:12px">✓ You\'re viewing JARVIS on a tablet or mobile device.</div>' +
|
||||||
|
'<div style="color:var(--text-dim);font-size:0.65rem;line-height:1.6">The JARVIS Agent runs on desktop and server platforms (Windows, macOS, Linux).<br><br>' +
|
||||||
|
'Tablets and phones can browse the full JARVIS dashboard but do not need an agent installed — all data comes from your other monitored machines.</div>';
|
||||||
|
} else if (_agentOnline) {
|
||||||
title.textContent = '● AGENT CONNECTED';
|
title.textContent = '● AGENT CONNECTED';
|
||||||
content.innerHTML = '<div style="color:var(--green);font-size:0.75rem;margin-bottom:12px">✓ JARVIS Agent is running on this machine.</div>' +
|
content.innerHTML =
|
||||||
'<div style="color:var(--text-dim);font-size:0.65rem">Reporting: CPU · Memory · Disk · Services · Uptime</div>';
|
'<div style="color:var(--green);font-size:0.75rem;margin-bottom:12px">✓ JARVIS Agent is active on this machine.</div>' +
|
||||||
|
'<div style="color:var(--text-dim);font-size:0.65rem;line-height:1.8">' +
|
||||||
|
'<b style="color:var(--text)">Host:</b> ' + (_myAgent?.hostname||'—') + '<br>' +
|
||||||
|
'<b style="color:var(--text)">IP:</b> ' + (_myAgent?.ip_address||'—') + '<br>' +
|
||||||
|
'<b style="color:var(--text)">Type:</b> ' + (_myAgent?.agent_type||'—').toUpperCase() + '<br>' +
|
||||||
|
'<b style="color:var(--text)">Reporting:</b> CPU · Memory · Disk · Services · Uptime</div>';
|
||||||
} else {
|
} else {
|
||||||
const inst = {
|
const inst = {
|
||||||
|
windows: {
|
||||||
|
label:'Windows',
|
||||||
|
cmd:'# Run PowerShell as Administrator:\nSet-ExecutionPolicy Bypass -Scope Process -Force\nInvoke-WebRequest -Uri "'+baseUrl+'/install-windows.ps1" -OutFile "$env:TEMP\\install.ps1"\n& "$env:TEMP\\install.ps1" -JarvisUrl '+jUrl+' -Key '+regKey,
|
||||||
|
dl: baseUrl+'/install-windows.ps1',
|
||||||
|
note:'Run PowerShell as Administrator. Installs as a Windows Task Scheduler service.'
|
||||||
|
},
|
||||||
mac: {
|
mac: {
|
||||||
label:'macOS',
|
label:'macOS',
|
||||||
cmd:'bash <(curl -sSL '+baseUrl+'/install-mac.sh) \\\n --jarvis-url '+jUrl+' \\\n --key '+regKey,
|
cmd:'bash <(curl -sSL '+baseUrl+'/install-mac.sh) \\\n --jarvis-url '+jUrl+' \\\n --key '+regKey,
|
||||||
dl: baseUrl+'/install-mac.sh',
|
dl: baseUrl+'/install-mac.sh',
|
||||||
note:'Run in Terminal. Installs as a launchd background service.'
|
note:'Run in Terminal. Installs as a launchd background service.'
|
||||||
},
|
},
|
||||||
windows: {
|
|
||||||
label:'Windows',
|
|
||||||
cmd:'# Run PowerShell as Administrator:\nSet-ExecutionPolicy Bypass -Scope Process\nInvoke-WebRequest -Uri "'+baseUrl+'/install-windows.ps1" -OutFile install.ps1\n.\\install-windows.ps1 -JarvisUrl '+jUrl+' -Key '+regKey,
|
|
||||||
dl: baseUrl+'/install-windows.ps1',
|
|
||||||
note:'Run PowerShell as Administrator. Installs as Task Scheduler service.'
|
|
||||||
},
|
|
||||||
linux: {
|
linux: {
|
||||||
label:'Linux',
|
label:'Linux',
|
||||||
cmd:'curl -sSL '+baseUrl+'/install.sh | sudo bash -s -- \\\n --jarvis-url '+jUrl+' \\\n --key '+regKey,
|
cmd:'curl -sSL '+baseUrl+'/install.sh | sudo bash -s -- \\\n --jarvis-url '+jUrl+' \\\n --key '+regKey,
|
||||||
@@ -1911,18 +1933,20 @@ function openAgentModal() {
|
|||||||
},
|
},
|
||||||
unknown: {
|
unknown: {
|
||||||
label:'Your System',
|
label:'Your System',
|
||||||
cmd:'# Download from JARVIS server:\nhttps://jarvis.orbishosting.com/agent/',
|
cmd:'# Browse installers:\nhttps://jarvis.orbishosting.com/agent/',
|
||||||
dl: 'https://jarvis.orbishosting.com/agent/',
|
dl: 'https://jarvis.orbishosting.com/agent/',
|
||||||
note:'Select your platform from the GitHub repo.'
|
note:'Choose your platform installer from the JARVIS agent directory.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const i = inst[os] || inst.unknown;
|
const i = inst[os] || inst.unknown;
|
||||||
title.textContent = '● INSTALL AGENT · ' + i.label.toUpperCase();
|
const osBadge = {windows:'🪟 WINDOWS', mac:'🍎 MACOS', linux:'🐧 LINUX', unknown:'❓ UNKNOWN'}[os] || os.toUpperCase();
|
||||||
|
title.textContent = '● INSTALL AGENT · ' + (inst[os] ? inst[os].label.toUpperCase() : 'YOUR SYSTEM');
|
||||||
content.innerHTML =
|
content.innerHTML =
|
||||||
|
'<div style="color:var(--cyan);font-size:0.65rem;letter-spacing:1px;margin-bottom:8px">DETECTED: ' + osBadge + '</div>' +
|
||||||
'<div style="color:var(--text-dim);font-size:0.65rem;margin-bottom:12px">'+i.note+'</div>' +
|
'<div style="color:var(--text-dim);font-size:0.65rem;margin-bottom:12px">'+i.note+'</div>' +
|
||||||
'<pre id="agentCmdPre">'+i.cmd+'</pre>' +
|
'<pre id="agentCmdPre">'+i.cmd+'</pre>' +
|
||||||
'<a class="agent-dl-btn" href="'+i.dl+'" target="_blank">↓ DOWNLOAD INSTALLER</a>' +
|
'<a class="agent-dl-btn" href="'+i.dl+'" target="_blank">↓ DOWNLOAD INSTALLER</a>' +
|
||||||
'<div style="color:var(--text-dim);font-size:0.6rem;margin-top:16px;opacity:0.7">After install, this indicator turns green within 30 seconds.</div>';
|
'<div style="color:var(--text-dim);font-size:0.6rem;margin-top:16px;opacity:0.7">After install, the AGENT indicator turns green within 30 seconds.</div>';
|
||||||
}
|
}
|
||||||
modal.classList.add('open');
|
modal.classList.add('open');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user