From b1c22b7f106341a2d100f46034ea44088e596218 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Tue, 10 Feb 2026 10:21:15 +0100 Subject: [PATCH] feat(dashboard): Add system overview infographic to LuCI admin - Add get_system_overview RPCD method - Add renderSystemOverview to admin dashboard.js - Display system health, resources, services, network, security stats - Styled with cyberpunk theme Co-Authored-By: Claude Opus 4.5 --- .../resources/secubox-admin/api.js | 8 +++ .../resources/view/secubox-admin/dashboard.js | 67 ++++++++++++++++++- .../root/usr/lib/secubox/rpcd.d/dashboard.sh | 15 +++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/secubox-admin/api.js b/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/secubox-admin/api.js index fa4c40a3..89227d45 100644 --- a/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/secubox-admin/api.js +++ b/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/secubox-admin/api.js @@ -51,6 +51,13 @@ var callGetHealth = rpc.declare({ expect: { } }); +// System Overview (infographic dashboard) +var callGetSystemOverview = rpc.declare({ + object: 'luci.secubox', + method: 'get_system_overview', + expect: { } +}); + var callGetAlerts = rpc.declare({ object: 'luci.secubox', method: 'get_alerts', @@ -458,6 +465,7 @@ return baseclass.extend({ getHealth: debugRPC('getHealth', callGetHealth, { retries: 1 }), getAlerts: debugRPC('getAlerts', callGetAlerts, { retries: 1 }), getLogs: debugRPC('getLogs', callGetLogs), + getSystemOverview: debugRPC('getSystemOverview', callGetSystemOverview, { retries: 1 }), // Catalog Sources (critical - more retries) getCatalogSources: debugRPC('getCatalogSources', callGetCatalogSources, { retries: 3, retryDelay: 2000 }), diff --git a/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/view/secubox-admin/dashboard.js b/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/view/secubox-admin/dashboard.js index 7da4cbbf..4940fb02 100644 --- a/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/view/secubox-admin/dashboard.js +++ b/package/secubox/luci-app-secubox-admin/htdocs/luci-static/resources/view/secubox-admin/dashboard.js @@ -51,7 +51,8 @@ return view.extend({ L.resolveDefault(API.getModules(), { modules: {} }), L.resolveDefault(API.getHealth(), {}), L.resolveDefault(API.getAlerts(), { alerts: [] }), - L.resolveDefault(API.checkUpdates(), { updates: [] }) + L.resolveDefault(API.checkUpdates(), { updates: [] }), + L.resolveDefault(API.getSystemOverview(), {}) ]); }, @@ -61,6 +62,7 @@ return view.extend({ var health = data[2]; var alerts = DataUtils.normalizeAlerts(data[3]); var updateInfo = DataUtils.normalizeUpdates(data[4]); + var sysOverview = data[5] || {}; var stats = DataUtils.buildAppStats(apps, modules, alerts, updateInfo, API.getAppStatus); var healthSnapshot = DataUtils.normalizeHealth(health); @@ -79,6 +81,9 @@ return view.extend({ E('div', { 'class': 'cyber-header-subtitle' }, 'System Overview ยท Applications ยท Health Monitoring') ]), + // System Overview Infographic + this.renderSystemOverview(sysOverview), + // Stats grid E('div', { 'class': 'stats-grid' }, [ Components.renderStatCard('๐Ÿ“ฆ', stats.totalApps, 'Total Apps', 'blue'), @@ -118,6 +123,66 @@ return view.extend({ return wrapper; }, + renderSystemOverview: function(overview) { + if (!overview || !overview.system) return E('div'); + + var sys = overview.system || {}; + var net = overview.network || {}; + var svc = overview.services || {}; + var sec = overview.security || {}; + + return E('div', { 'class': 'system-overview card', 'style': 'margin-bottom:20px;' }, [ + E('h3', { 'style': 'margin:0 0 16px 0;color:#0ff;' }, '๐Ÿ“Š SYSTEM OVERVIEW'), + E('div', { 'class': 'overview-grid', 'style': 'display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;' }, [ + // System section + E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [ + E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, 'โšก SYSTEM'), + E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [ + E('div', {}, 'Load: ' + (sys.load || 'N/A')), + E('div', {}, 'CPU: ' + (sys.cpu_used || 0) + '% used'), + E('div', {}, 'Uptime: ' + (sys.uptime || 'N/A')) + ]) + ]), + // Resources section + E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [ + E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '๐Ÿ’พ RESOURCES'), + E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [ + E('div', {}, 'Memory: ' + (sys.mem_free || 0) + 'MB free'), + E('div', {}, 'Disk /: ' + (sys.disk_root || 'N/A')), + E('div', {}, 'Disk /srv: ' + (sys.disk_srv || 'N/A')) + ]) + ]), + // Services section + E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [ + E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '๐Ÿ”ง SERVICES'), + E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [ + E('div', {}, 'HAProxy: ' + (svc.haproxy_backends || 0) + ' backends'), + E('div', {}, 'VHosts: ' + (svc.haproxy_vhosts || 0)), + E('div', {}, 'Sites: ' + (svc.metablog_sites || 0) + ' / Apps: ' + (svc.streamlit_apps || 0)) + ]) + ]), + // Network section + E('div', { 'class': 'overview-section', 'style': 'background:rgba(0,255,255,0.05);padding:12px;border-radius:8px;border:1px solid rgba(0,255,255,0.2);' }, [ + E('h4', { 'style': 'margin:0 0 8px 0;color:#0ff;font-size:12px;' }, '๐ŸŒ NETWORK'), + E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [ + E('div', {}, 'Connections: ' + (net.connections || 0)), + E('div', {}, 'Tor: ' + (net.tor || 0)), + E('div', {}, 'HTTPS: ' + (net.https || 0)) + ]) + ]), + // Security section + E('div', { 'class': 'overview-section', 'style': 'background:rgba(255,0,100,0.1);padding:12px;border-radius:8px;border:1px solid rgba(255,0,100,0.3);' }, [ + E('h4', { 'style': 'margin:0 0 8px 0;color:#ff0064;font-size:12px;' }, '๐Ÿ›ก๏ธ SECURITY'), + E('div', { 'style': 'font-size:11px;line-height:1.8;' }, [ + E('div', {}, 'Active Bans: ' + (sec.active_bans || 0)), + E('div', {}, 'SSRF: ' + (sec.attacks_ssrf || 0) + ' | Bots: ' + (sec.attacks_botscan || 0)), + E('div', {}, 'Countries: ' + (sec.top_countries || 'N/A')) + ]) + ]) + ]) + ]); + }, + renderHealthSummary: function(health) { if (!health) return E('div'); diff --git a/package/secubox/secubox-core/root/usr/lib/secubox/rpcd.d/dashboard.sh b/package/secubox/secubox-core/root/usr/lib/secubox/rpcd.d/dashboard.sh index e38f51de..c5c25b9b 100644 --- a/package/secubox/secubox-core/root/usr/lib/secubox/rpcd.d/dashboard.sh +++ b/package/secubox/secubox-core/root/usr/lib/secubox/rpcd.d/dashboard.sh @@ -7,6 +7,7 @@ # Register methods list_methods_dashboard() { add_method "get_dashboard_data" + add_method "get_system_overview" add_method "get_public_ips" add_method "refresh_public_ips" add_method_str "quick_action" "action" @@ -23,6 +24,9 @@ handle_dashboard() { get_dashboard_data) _do_dashboard_data ;; + get_system_overview) + _do_system_overview + ;; get_public_ips) _do_public_ips ;; @@ -46,6 +50,17 @@ handle_dashboard() { esac } +# System Overview - Full infographic data +_do_system_overview() { + if [ -x "/usr/sbin/secubox-dashboard" ]; then + /usr/sbin/secubox-dashboard json + else + json_init + json_add_string "error" "secubox-dashboard not installed" + json_dump + fi +} + # Dashboard summary data (optimized - no slow appstore call) _do_dashboard_data() { json_init