sidebar: detectar IP LAN local via WebRTC y mostrarla en el pie del menú

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-09 10:35:54 -05:00
co-authored by Claude Sonnet 4.6
parent 60d186253e
commit 8b3188b21b
+33 -2
View File
@@ -244,12 +244,43 @@ if (class_exists('ModuleRegistry', false)) {
<?= htmlspecialchars($_user_name, ENT_QUOTES, 'UTF-8') ?>
</div>
<div class="sidebar-user-role"><?= htmlspecialchars($_role_label, ENT_QUOTES, 'UTF-8') ?></div>
<div style="font-size:.68rem;color:#94a3b8;margin-top:3px;letter-spacing:.02em">
<i class="fas fa-network-wired me-1"></i><?= htmlspecialchars(trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? '')[0])) ?>
<div id="sb-local-ip" style="font-size:.68rem;color:#94a3b8;margin-top:3px;letter-spacing:.02em">
<i class="fas fa-network-wired me-1"></i><span id="sb-ip-val">detectando…</span>
</div>
</div>
</nav>
<script>
(function() {
function detectLocalIP() {
var RTC = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (!RTC) { document.getElementById('sb-ip-val').textContent = '(no disponible)'; return; }
var pc = new RTC({ iceServers: [] }), found = false;
pc.createDataChannel('');
pc.createOffer().then(function(o) { return pc.setLocalDescription(o); }).catch(function(){});
pc.onicecandidate = function(e) {
if (found || !e || !e.candidate) return;
var ips = e.candidate.candidate.match(/\b(\d{1,3}\.){3}\d{1,3}\b/g) || [];
ips.forEach(function(ip) {
if (found) return;
if (/^(192\.168\.|10\.|172\.(1[6-9]|2\d|3[01])\.)/.test(ip)) {
found = true;
document.getElementById('sb-ip-val').textContent = ip;
pc.close();
}
});
};
setTimeout(function() {
if (!found) document.getElementById('sb-ip-val').textContent = '(no detectada)';
}, 3000);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', detectLocalIP);
} else {
detectLocalIP();
}
})();
</script>
<style>
/* ── Header con logo ────────────────────────────────── */