espilon-source/tools/C3PO/hp_dashboard/static/hp/js/router.js
Eun0us 79c2a4d4bf c3po: full server rewrite with modular routes and honeypot dashboard
Replace monolithic CLI and web server with route-based Flask API.
New routes: api_commands, api_build, api_can, api_monitor, api_ota,
api_tunnel. Add honeypot security dashboard with real-time SSE,
MITRE ATT&CK mapping, kill chain analysis.

New TUI with commander/help modules. Add session management,
tunnel proxy core, CAN bus data store. Docker support.
2026-02-28 20:12:27 +01:00

75 lines
2.6 KiB
JavaScript

/* ESPILON Honeypot Dashboard — Router & Navigation */
import { S } from './state.js';
import { $id } from './utils.js';
// Tab render functions — set by app.js via setTabRenderers().
const _tabRenderers = {};
export function setTabRenderers(renderers) {
Object.assign(_tabRenderers, renderers);
}
export function switchTab(tab) {
S.tab = tab;
// Highlight active nav button
document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
const btn = $id('tab-' + tab);
if (btn) btn.classList.add('active');
// Toggle search bar visibility (only on events tab)
const sb = $id('search-bar');
if (sb) sb.style.display = tab === 'timeline' ? '' : 'none';
// Collapse filter panel when leaving events tab
const fp = $id('filter-panel');
if (fp) fp.classList.remove('active');
// Clear events badge when switching to events
if (tab === 'timeline') {
const badge = $id('nav-badge-events');
if (badge) { badge.textContent = '0'; badge.style.display = 'none'; }
}
// Close mobile nav
$id('nav-tabs')?.classList.remove('nav-open');
// Render the tab
const renderer = _tabRenderers[tab];
if (renderer) renderer();
}
// ── Keyboard Shortcuts ──────────────────────────────────────
// extraHandlers: { onEscape, onRefresh, onToggleSound }
export function setupKeyboardShortcuts(extraHandlers) {
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT' || e.target.tagName === 'TEXTAREA') {
if (e.key === 'Escape') e.target.blur();
return;
}
switch (e.key) {
case '/':
e.preventDefault();
if (S.tab === 'timeline') $id('search-input')?.focus();
break;
case 'Escape':
if (extraHandlers?.onEscape) extraHandlers.onEscape();
break;
case '1': switchTab('overview'); break;
case '2': switchTab('timeline'); break;
case '3': switchTab('sessions'); break;
case '4': switchTab('credentials'); break;
case '5': switchTab('killchain'); break;
case '6': switchTab('mitre'); break;
case 'r':
if (extraHandlers?.onRefresh) extraHandlers.onRefresh();
break;
case 's':
if (extraHandlers?.onToggleSound) extraHandlers.onToggleSound();
break;
}
});
}