From 3dcc89d3a32b183d97cfd8826bb0468397f158ef Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Fri, 26 Dec 2025 16:51:59 +0100 Subject: [PATCH] feat: SecuBox modules v2 - Responsive cards with versions and actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major improvements to modules page: - Responsive grid layout with modern card design - Module versions display (v0.0.9) - Category filter tabs (All, Security, Monitoring, Network, System) - Quick actions (Start/Stop/Restart/Dashboard) - Real-time status indicators with animations - Emoji icons properly displayed - Auto-refresh every 30 seconds Changes: - modules.js: Complete rewrite with responsive cards - modules.css: New CSS with theme support and animations - secubox config: Added emoji icons and version fields - RPCD backend: Added version field to module data Features: ✨ Responsive 3-column grid (auto-adapts to screen size) đŸŽ¯ Category filtering with animated tabs â–ļī¸ One-click start/stop/restart actions 📊 Dashboard quick links for each module đŸ’Ģ Smooth animations and hover effects 🌓 Full dark/light theme support 📱 Mobile-friendly design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- deploy-modules-v2.sh | 42 ++ deploy-secubox-fix.sh | 37 ++ .../luci-static/resources/secubox/modules.css | 442 ++++++++++++++++++ .../resources/view/secubox/modules.js | 407 ++++++++++++++-- luci-app-secubox/root/etc/config/secubox | 44 +- .../root/usr/libexec/rpcd/luci.secubox | 22 +- 6 files changed, 931 insertions(+), 63 deletions(-) create mode 100755 deploy-modules-v2.sh create mode 100755 deploy-secubox-fix.sh create mode 100644 luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css diff --git a/deploy-modules-v2.sh b/deploy-modules-v2.sh new file mode 100755 index 00000000..26fc8516 --- /dev/null +++ b/deploy-modules-v2.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Deploy SecuBox Modules v2 - Responsive cards with versions and actions + +ROUTER="root@192.168.8.191" + +echo "🚀 Deploying SecuBox Modules v2 to $ROUTER" +echo "" + +echo "đŸ“Ļ Deploying modules view and CSS..." +scp luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js \ + "$ROUTER:/www/luci-static/resources/view/secubox/" + +scp luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css \ + "$ROUTER:/www/luci-static/resources/secubox/" + +echo "📝 Deploying updated config with versions..." +scp luci-app-secubox/root/etc/config/secubox \ + "$ROUTER:/etc/config/secubox" + +echo "🔧 Deploying updated RPCD backend..." +scp luci-app-secubox/root/usr/libexec/rpcd/luci.secubox \ + "$ROUTER:/usr/libexec/rpcd/" + +echo "🔄 Setting permissions and restarting services..." +ssh "$ROUTER" "chmod +x /usr/libexec/rpcd/luci.secubox" +ssh "$ROUTER" "chmod 644 /www/luci-static/resources/view/secubox/modules.js" +ssh "$ROUTER" "chmod 644 /www/luci-static/resources/secubox/modules.css" +ssh "$ROUTER" "/etc/init.d/rpcd restart" + +echo "" +echo "✅ Modules v2 deployed successfully!" +echo "" +echo "🎨 New features:" +echo " â€ĸ Responsive grid layout" +echo " â€ĸ Module versions (v0.0.9)" +echo " â€ĸ Category filter tabs" +echo " â€ĸ Start/Stop/Restart actions" +echo " â€ĸ Dashboard quick links" +echo " â€ĸ Real-time status indicators" +echo " â€ĸ Modern card design with icons" +echo "" +echo "👉 Refresh your browser (Ctrl+Shift+R) and go to SecuBox → Modules" diff --git a/deploy-secubox-fix.sh b/deploy-secubox-fix.sh new file mode 100755 index 00000000..ba830948 --- /dev/null +++ b/deploy-secubox-fix.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Deploy SecuBox config fix - Module icons emoji fix + +ROUTER="root@192.168.8.191" + +echo "🔧 Deploying SecuBox config fix to $ROUTER" +echo "" + +echo "📝 Backing up current config..." +ssh "$ROUTER" "cp /etc/config/secubox /etc/config/secubox.backup.$(date +%Y%m%d-%H%M%S)" + +echo "đŸ“Ļ Deploying updated config with emoji icons..." +scp luci-app-secubox/root/etc/config/secubox "$ROUTER:/etc/config/secubox" + +echo "🔄 Restarting RPCD..." +ssh "$ROUTER" "/etc/init.d/rpcd restart" + +echo "" +echo "✅ Config deployed successfully!" +echo "" +echo "🎨 Fixed module icons:" +echo " đŸ›Ąī¸ CrowdSec Dashboard" +echo " 📊 Netdata Dashboard" +echo " 🔍 Netifyd Dashboard" +echo " 🔒 WireGuard Dashboard" +echo " 🌐 Network Modes" +echo " đŸ‘ī¸ Client Guardian" +echo " âš™ī¸ System Hub" +echo " đŸ“Ļ CDN Cache" +echo " 📡 Bandwidth Manager" +echo " 🔑 Auth Guardian" +echo " â–ļī¸ Media Flow" +echo " đŸ–Ĩī¸ Virtual Host Manager" +echo " 📈 Traffic Shaper" +echo " 🔐 KSM Manager" +echo "" +echo "👉 Refresh your browser (Ctrl+Shift+R) to see the changes" diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css new file mode 100644 index 00000000..b990b35b --- /dev/null +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css @@ -0,0 +1,442 @@ +/* SecuBox Modules Page Styles */ + +.secubox-modules-page { + max-width: 1400px; + margin: 0 auto; + padding: 20px; +} + +/* Header Section */ +.secubox-modules-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 12px; + margin-top: 16px; +} + +.secubox-stat-badge { + display: flex; + flex-direction: column; + align-items: center; + padding: 16px; + background: var(--sb-bg-card); + border: 2px solid var(--sb-border); + border-radius: 12px; + transition: all 0.2s; +} + +.secubox-stat-badge:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px var(--sb-shadow); +} + +.secubox-stat-badge.secubox-stat-success { + border-color: #22c55e; + background: linear-gradient(135deg, var(--sb-bg-card) 0%, rgba(34, 197, 94, 0.1) 100%); +} + +.secubox-stat-badge.secubox-stat-warning { + border-color: #f59e0b; + background: linear-gradient(135deg, var(--sb-bg-card) 0%, rgba(245, 158, 11, 0.1) 100%); +} + +.secubox-stat-badge.secubox-stat-muted { + border-color: #64748b; + background: linear-gradient(135deg, var(--sb-bg-card) 0%, rgba(100, 116, 139, 0.05) 100%); +} + +.secubox-stat-value { + font-size: 32px; + font-weight: 700; + color: var(--sb-text); + margin-bottom: 4px; +} + +.secubox-stat-label { + font-size: 12px; + color: var(--sb-text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +/* Filter Tabs */ +.secubox-filter-tabs { + display: flex; + gap: 8px; + margin: 24px 0; + flex-wrap: wrap; +} + +.secubox-filter-tab { + padding: 10px 20px; + background: var(--sb-bg-card); + border: 2px solid var(--sb-border); + border-radius: 8px; + color: var(--sb-text); + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; +} + +.secubox-filter-tab:hover { + background: var(--sb-bg); + border-color: var(--sb-primary); +} + +.secubox-filter-tab.active { + background: var(--sb-primary); + border-color: var(--sb-primary); + color: white; +} + +/* Modules Grid */ +.secubox-modules-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); + gap: 20px; + margin-bottom: 24px; +} + +@media (max-width: 768px) { + .secubox-modules-grid { + grid-template-columns: 1fr; + } +} + +/* Module Card */ +.secubox-module-card { + background: var(--sb-bg-card); + border-radius: 12px; + border: 1px solid var(--sb-border); + overflow: hidden; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + flex-direction: column; +} + +.secubox-module-card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px var(--sb-hover-shadow); +} + +.secubox-module-card.secubox-module-running { + border-left-width: 4px; +} + +.secubox-module-card.secubox-module-stopped { + opacity: 0.85; +} + +.secubox-module-card.secubox-module-not-installed { + opacity: 0.6; +} + +/* Card Header */ +.secubox-module-card-header { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 20px; + background: linear-gradient(135deg, var(--sb-bg) 0%, var(--sb-bg-card) 100%); + border-bottom: 1px solid var(--sb-border); +} + +.secubox-module-icon { + font-size: 36px; + flex-shrink: 0; + line-height: 1; +} + +.secubox-module-info { + flex: 1; + min-width: 0; +} + +.secubox-module-name { + margin: 0 0 8px 0; + font-size: 18px; + font-weight: 600; + color: var(--sb-text); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.secubox-module-meta { + display: flex; + gap: 12px; + flex-wrap: wrap; +} + +.secubox-module-category, +.secubox-module-version { + font-size: 12px; + padding: 4px 8px; + border-radius: 6px; + background: var(--sb-bg); + color: var(--sb-text-muted); + border: 1px solid var(--sb-border); +} + +.secubox-status-indicator { + width: 12px; + height: 12px; + border-radius: 50%; + flex-shrink: 0; + margin-top: 6px; +} + +.secubox-status-indicator.secubox-status-running { + background: #22c55e; + box-shadow: 0 0 8px #22c55e; + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +.secubox-status-indicator.secubox-status-stopped { + background: #f59e0b; +} + +.secubox-status-indicator.secubox-status-not-installed { + background: #64748b; +} + +@keyframes pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} + +/* Card Body */ +.secubox-module-card-body { + padding: 20px; + flex: 1; + display: flex; + flex-direction: column; + gap: 16px; +} + +.secubox-module-description { + margin: 0; + color: var(--sb-text); + font-size: 14px; + line-height: 1.6; +} + +.secubox-module-details { + display: flex; + flex-direction: column; + gap: 8px; +} + +.secubox-module-detail { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; +} + +.secubox-detail-label { + color: var(--sb-text-muted); + font-weight: 500; + min-width: 70px; +} + +.secubox-detail-value { + color: var(--sb-text); + flex: 1; +} + +.secubox-detail-value code { + background: var(--sb-bg); + padding: 2px 6px; + border-radius: 4px; + font-size: 12px; + font-family: monospace; + border: 1px solid var(--sb-border); +} + +.secubox-status-text-running { + color: #22c55e; + font-weight: 600; +} + +.secubox-status-text-stopped { + color: #f59e0b; + font-weight: 600; +} + +.secubox-status-text-not-installed { + color: #64748b; +} + +/* Card Actions */ +.secubox-module-card-actions { + display: flex; + gap: 8px; + padding: 16px 20px; + background: var(--sb-bg); + border-top: 1px solid var(--sb-border); + flex-wrap: wrap; +} + +.secubox-btn { + padding: 8px 16px; + border-radius: 6px; + font-size: 13px; + font-weight: 500; + border: none; + cursor: pointer; + transition: all 0.2s; + text-decoration: none; + display: inline-flex; + align-items: center; + justify-content: center; + white-space: nowrap; +} + +.secubox-btn:hover { + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); +} + +.secubox-btn:active { + transform: translateY(0); +} + +.secubox-btn-sm { + padding: 6px 12px; + font-size: 12px; +} + +.secubox-btn-primary { + background: var(--sb-primary); + color: white; +} + +.secubox-btn-primary:hover { + background: var(--sb-primary-dark); +} + +.secubox-btn-success { + background: #22c55e; + color: white; +} + +.secubox-btn-success:hover { + background: #16a34a; +} + +.secubox-btn-danger { + background: #ef4444; + color: white; +} + +.secubox-btn-danger:hover { + background: #dc2626; +} + +.secubox-btn-warning { + background: #f59e0b; + color: white; +} + +.secubox-btn-warning:hover { + background: #d97706; +} + +.secubox-btn-secondary { + background: var(--sb-bg-card); + color: var(--sb-text-muted); + border: 1px solid var(--sb-border); +} + +.secubox-btn-secondary:hover { + background: var(--sb-bg); +} + +.secubox-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.secubox-btn:disabled:hover { + transform: none; + box-shadow: none; +} + +/* Empty State */ +.secubox-empty-state { + grid-column: 1 / -1; + text-align: center; + padding: 60px 20px; + background: var(--sb-bg-card); + border: 2px dashed var(--sb-border); + border-radius: 12px; +} + +.secubox-empty-icon { + font-size: 64px; + margin-bottom: 16px; +} + +.secubox-empty-title { + font-size: 20px; + font-weight: 600; + color: var(--sb-text); + margin-bottom: 8px; +} + +.secubox-empty-text { + color: var(--sb-text-muted); + font-size: 14px; +} + +/* Responsive Design */ +@media (max-width: 480px) { + .secubox-modules-page { + padding: 12px; + } + + .secubox-modules-stats { + grid-template-columns: repeat(2, 1fr); + } + + .secubox-filter-tabs { + gap: 6px; + } + + .secubox-filter-tab { + padding: 8px 12px; + font-size: 12px; + } + + .secubox-module-card-header { + padding: 16px; + } + + .secubox-module-card-body { + padding: 16px; + } + + .secubox-module-card-actions { + padding: 12px 16px; + } + + .secubox-btn { + flex: 1; + min-width: 0; + } +} + +/* Dark/Light theme specific adjustments */ +[data-theme="light"] .secubox-module-card:hover { + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .secubox-stat-badge:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); +} diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js index 8b9f9ef0..dffc59e3 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js @@ -1,51 +1,378 @@ 'use strict'; 'require view'; -'require rpc'; +'require ui'; +'require dom'; +'require secubox/api as API'; 'require secubox/theme as Theme'; +'require poll'; + +// Load CSS +document.head.appendChild(E('link', { + 'rel': 'stylesheet', + 'type': 'text/css', + 'href': L.resource('secubox/secubox.css') +})); +document.head.appendChild(E('link', { + 'rel': 'stylesheet', + 'type': 'text/css', + 'href': L.resource('secubox/modules.css') +})); // Initialize theme Theme.init(); -var callModules = rpc.declare({ - object: 'luci.secubox', - method: 'modules', - expect: { modules: [] } -}); - return view.extend({ - load: function() { - return callModules(); - }, - render: function(data) { - var modules = Array.isArray(data) ? data : (data && data.modules ? data.modules : []); + modulesData: [], - if (modules.length === 0) { - return E('div', {'class':'cbi-map'}, [ - E('h2', {}, 'đŸ“Ļ SecuBox Modules'), - E('div', {'style':'color:#856404;padding:20px;background:#fff3cd;border:2px solid #ffc107;border-radius:8px'}, - E('p', {}, 'âš ī¸ No modules found. Please check your configuration.')) - ]); - } + load: function() { + return this.refreshData(); + }, - return E('div', {'class':'cbi-map'}, [ - E('h2', {}, 'đŸ“Ļ SecuBox Modules'), - E('p', {'style':'color:#64748b;margin-bottom:20px'}, - modules.length + ' modules available â€ĸ ' + - modules.filter(function(m) { return m.installed; }).length + ' installed â€ĸ ' + - modules.filter(function(m) { return m.running; }).length + ' running' - ), - E('div', {'style':'display:grid;gap:12px'}, modules.map(function(m) { - return E('div', {'style':'background:#1e293b;padding:16px;border-radius:8px;border-left:4px solid '+(m.color||'#64748b')}, [ - E('div', {'style':'font-weight:bold;color:#f1f5f9'}, m.name || m.id || 'Unknown'), - E('div', {'style':'color:#94a3b8;font-size:14px;margin:4px 0'}, m.description || ''), - E('div', {'style':'display:flex;gap:8px;margin-top:8px'}, [ - E('span', {'style':'padding:2px 8px;border-radius:4px;font-size:12px;background:'+(m.running?'#22c55e20;color:#22c55e':m.installed?'#f59e0b20;color:#f59e0b':'#64748b20;color:#64748b')}, - m.running ? '✓ Running' : m.installed ? '○ Stopped' : '- Not Installed'), - E('span', {'style':'padding:2px 8px;border-radius:4px;font-size:12px;background:#1e293b;color:#94a3b8;border:1px solid #334155'}, - m.category || 'other') - ]) - ]); - })) - ]); - } + refreshData: function() { + var self = this; + return API.getModules().then(function(data) { + self.modulesData = data.modules || []; + return data; + }); + }, + + render: function(data) { + var self = this; + var modules = this.modulesData; + + var container = E('div', { 'class': 'secubox-modules-page' }); + + // Header with stats + container.appendChild(this.renderHeader(modules)); + + // Filter tabs + container.appendChild(this.renderFilterTabs()); + + // Modules grid + container.appendChild(E('div', { 'id': 'modules-grid', 'class': 'secubox-modules-grid' }, + this.renderModuleCards(modules, 'all') + )); + + // Auto-refresh + poll.add(function() { + return self.refreshData().then(function() { + self.updateModulesGrid(); + }); + }, 30); + + return container; + }, + + renderHeader: function(modules) { + var total = modules.length; + var installed = modules.filter(function(m) { return m.installed; }).length; + var running = modules.filter(function(m) { return m.running; }).length; + var stopped = installed - running; + + return E('div', { 'class': 'secubox-page-header' }, [ + E('div', {}, [ + E('h2', {}, 'đŸ“Ļ SecuBox Modules'), + E('p', { 'class': 'secubox-page-subtitle' }, + 'Manage and monitor all SecuBox modules') + ]), + E('div', { 'class': 'secubox-modules-stats' }, [ + E('div', { 'class': 'secubox-stat-badge' }, [ + E('span', { 'class': 'secubox-stat-value' }, total), + E('span', { 'class': 'secubox-stat-label' }, 'Total') + ]), + E('div', { 'class': 'secubox-stat-badge secubox-stat-success' }, [ + E('span', { 'class': 'secubox-stat-value' }, running), + E('span', { 'class': 'secubox-stat-label' }, 'Running') + ]), + E('div', { 'class': 'secubox-stat-badge secubox-stat-warning' }, [ + E('span', { 'class': 'secubox-stat-value' }, stopped), + E('span', { 'class': 'secubox-stat-label' }, 'Stopped') + ]), + E('div', { 'class': 'secubox-stat-badge secubox-stat-muted' }, [ + E('span', { 'class': 'secubox-stat-value' }, total - installed), + E('span', { 'class': 'secubox-stat-label' }, 'Available') + ]) + ]) + ]); + }, + + renderFilterTabs: function() { + var self = this; + var tabs = [ + { id: 'all', label: 'All Modules', icon: 'đŸ“Ļ' }, + { id: 'security', label: 'Security', icon: 'đŸ›Ąī¸' }, + { id: 'monitoring', label: 'Monitoring', icon: '📊' }, + { id: 'network', label: 'Network', icon: '🌐' }, + { id: 'system', label: 'System', icon: 'âš™ī¸' } + ]; + + return E('div', { 'class': 'secubox-filter-tabs' }, + tabs.map(function(tab) { + return E('button', { + 'class': 'secubox-filter-tab' + (tab.id === 'all' ? ' active' : ''), + 'data-filter': tab.id, + 'click': function(ev) { + document.querySelectorAll('.secubox-filter-tab').forEach(function(el) { + el.classList.remove('active'); + }); + ev.target.classList.add('active'); + self.filterModules(tab.id); + } + }, tab.icon + ' ' + tab.label); + }) + ); + }, + + renderModuleCards: function(modules, filter) { + var self = this; + + var filtered = filter === 'all' ? modules : + modules.filter(function(m) { return m.category === filter; }); + + if (filtered.length === 0) { + return E('div', { 'class': 'secubox-empty-state' }, [ + E('div', { 'class': 'secubox-empty-icon' }, '📭'), + E('div', { 'class': 'secubox-empty-title' }, 'No modules found'), + E('div', { 'class': 'secubox-empty-text' }, 'Try selecting a different category') + ]); + } + + return filtered.map(function(module) { + return self.renderModuleCard(module); + }); + }, + + renderModuleCard: function(module) { + var self = this; + var isRunning = module.running; + var isInstalled = module.installed; + var statusClass = isRunning ? 'running' : (isInstalled ? 'stopped' : 'not-installed'); + + return E('div', { + 'class': 'secubox-module-card secubox-module-' + statusClass, + 'style': 'border-left: 4px solid ' + (module.color || '#64748b') + }, [ + // Card Header + E('div', { 'class': 'secubox-module-card-header' }, [ + E('div', { 'class': 'secubox-module-icon' }, module.icon || 'đŸ“Ļ'), + E('div', { 'class': 'secubox-module-info' }, [ + E('h3', { 'class': 'secubox-module-name' }, module.name || module.id), + E('div', { 'class': 'secubox-module-meta' }, [ + E('span', { 'class': 'secubox-module-category' }, + this.getCategoryIcon(module.category) + ' ' + (module.category || 'other')), + E('span', { 'class': 'secubox-module-version' }, + 'v' + (module.version || '0.0.9')) + ]) + ]), + E('div', { + 'class': 'secubox-status-indicator secubox-status-' + statusClass, + 'title': isRunning ? 'Running' : (isInstalled ? 'Stopped' : 'Not Installed') + }) + ]), + + // Card Body + E('div', { 'class': 'secubox-module-card-body' }, [ + E('p', { 'class': 'secubox-module-description' }, + module.description || 'No description available'), + + E('div', { 'class': 'secubox-module-details' }, [ + E('div', { 'class': 'secubox-module-detail' }, [ + E('span', { 'class': 'secubox-detail-label' }, 'Package:'), + E('code', { 'class': 'secubox-detail-value' }, module.package || 'N/A') + ]), + E('div', { 'class': 'secubox-module-detail' }, [ + E('span', { 'class': 'secubox-detail-label' }, 'Status:'), + E('span', { + 'class': 'secubox-detail-value secubox-status-text-' + statusClass + }, isRunning ? '● Running' : (isInstalled ? '○ Stopped' : '- Not Installed')) + ]) + ]) + ]), + + // Card Actions + E('div', { 'class': 'secubox-module-card-actions' }, + this.renderModuleActions(module)) + ]); + }, + + renderModuleActions: function(module) { + var self = this; + var actions = []; + + if (!module.installed) { + actions.push( + E('button', { + 'class': 'secubox-btn secubox-btn-secondary secubox-btn-sm', + 'disabled': true + }, 'đŸ“Ĩ Install') + ); + } else { + // Start/Stop button + if (module.running) { + actions.push( + E('button', { + 'class': 'secubox-btn secubox-btn-danger secubox-btn-sm', + 'click': function() { + self.stopModule(module); + } + }, 'âšī¸ Stop') + ); + } else { + actions.push( + E('button', { + 'class': 'secubox-btn secubox-btn-success secubox-btn-sm', + 'click': function() { + self.startModule(module); + } + }, 'â–ļī¸ Start') + ); + } + + // Restart button (only if running) + if (module.running) { + actions.push( + E('button', { + 'class': 'secubox-btn secubox-btn-warning secubox-btn-sm', + 'click': function() { + self.restartModule(module); + } + }, '🔄 Restart') + ); + } + + // Dashboard link + var dashboardPath = this.getModuleDashboardPath(module.id); + if (dashboardPath) { + actions.push( + E('a', { + 'href': L.url(dashboardPath), + 'class': 'secubox-btn secubox-btn-primary secubox-btn-sm' + }, '📊 Dashboard') + ); + } + } + + return actions; + }, + + getModuleDashboardPath: function(moduleId) { + var paths = { + 'crowdsec': 'admin/secubox/security/crowdsec', + 'netdata': 'admin/secubox/monitoring/netdata', + 'netifyd': 'admin/secubox/security/netifyd', + 'wireguard': 'admin/secubox/network/wireguard', + 'network_modes': 'admin/secubox/network/modes', + 'client_guardian': 'admin/secubox/security/guardian', + 'system_hub': 'admin/system/system-hub/overview', + 'bandwidth_manager': 'admin/secubox/network/bandwidth', + 'auth_guardian': 'admin/secubox/security/auth', + 'media_flow': 'admin/secubox/network/media', + 'vhost_manager': 'admin/secubox/system/vhost', + 'traffic_shaper': 'admin/secubox/network/shaper', + 'cdn_cache': 'admin/secubox/network/cdn', + 'ksm_manager': 'admin/secubox/security/ksm' + }; + return paths[moduleId] || null; + }, + + getCategoryIcon: function(category) { + var icons = { + 'security': 'đŸ›Ąī¸', + 'monitoring': '📊', + 'network': '🌐', + 'system': 'âš™ī¸', + 'other': 'đŸ“Ļ' + }; + return icons[category] || icons['other']; + }, + + startModule: function(module) { + var self = this; + ui.showModal(_('Starting Module'), [ + E('p', {}, _('Starting') + ' ' + module.name + '...') + ]); + + API.startModule(module.id).then(function(result) { + ui.hideModal(); + if (result && result.success !== false) { + ui.addNotification(null, E('p', module.name + ' started successfully'), 'info'); + self.refreshData().then(function() { + self.updateModulesGrid(); + }); + } else { + ui.addNotification(null, E('p', 'Failed to start ' + module.name), 'error'); + } + }).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', 'Error: ' + err.message), 'error'); + }); + }, + + stopModule: function(module) { + var self = this; + ui.showModal(_('Stopping Module'), [ + E('p', {}, _('Stopping') + ' ' + module.name + '...') + ]); + + API.stopModule(module.id).then(function(result) { + ui.hideModal(); + if (result && result.success !== false) { + ui.addNotification(null, E('p', module.name + ' stopped successfully'), 'info'); + self.refreshData().then(function() { + self.updateModulesGrid(); + }); + } else { + ui.addNotification(null, E('p', 'Failed to stop ' + module.name), 'error'); + } + }).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', 'Error: ' + err.message), 'error'); + }); + }, + + restartModule: function(module) { + var self = this; + ui.showModal(_('Restarting Module'), [ + E('p', {}, _('Restarting') + ' ' + module.name + '...') + ]); + + API.restartModule(module.id).then(function(result) { + ui.hideModal(); + if (result && result.success !== false) { + ui.addNotification(null, E('p', module.name + ' restarted successfully'), 'info'); + self.refreshData().then(function() { + self.updateModulesGrid(); + }); + } else { + ui.addNotification(null, E('p', 'Failed to restart ' + module.name), 'error'); + } + }).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', 'Error: ' + err.message), 'error'); + }); + }, + + filterModules: function(category) { + var grid = document.getElementById('modules-grid'); + if (grid) { + dom.content(grid, this.renderModuleCards(this.modulesData, category)); + } + }, + + updateModulesGrid: function() { + var activeTab = document.querySelector('.secubox-filter-tab.active'); + var filter = activeTab ? activeTab.getAttribute('data-filter') : 'all'; + this.filterModules(filter); + + // Update header stats + var header = document.querySelector('.secubox-modules-stats'); + if (header && header.parentNode) { + var newHeader = this.renderHeader(this.modulesData); + header.parentNode.replaceChild(newHeader.querySelector('.secubox-modules-stats'), header); + } + }, + + handleSaveApply: null, + handleSave: null, + handleReset: null }); diff --git a/luci-app-secubox/root/etc/config/secubox b/luci-app-secubox/root/etc/config/secubox index c4ce8509..49f1e52e 100644 --- a/luci-app-secubox/root/etc/config/secubox +++ b/luci-app-secubox/root/etc/config/secubox @@ -1,6 +1,6 @@ config secubox 'main' option enabled '1' - option version '0.0.1-beta' + option version '0.1.1' option auto_discovery '1' option notifications '1' option theme 'dark' @@ -12,9 +12,10 @@ config module 'crowdsec' option name 'CrowdSec Dashboard' option description 'Collaborative threat intelligence' option category 'security' - option icon 'shield' + option icon 'đŸ›Ąī¸' option color '#22c55e' option package 'luci-app-crowdsec-dashboard' + option version '0.0.9' option config 'crowdsec' option installed '0' option enabled '0' @@ -23,9 +24,10 @@ config module 'netdata' option name 'Netdata Dashboard' option description 'Real-time system monitoring' option category 'monitoring' - option icon 'chart' + option icon '📊' option color '#00ab44' option package 'luci-app-netdata-dashboard' + option version '0.0.9' option config 'netdata' option installed '0' option enabled '0' @@ -34,9 +36,10 @@ config module 'netifyd' option name 'Netifyd Dashboard' option description 'Deep packet inspection' option category 'security' - option icon 'search' + option icon '🔍' option color '#8b5cf6' option package 'luci-app-netifyd-dashboard' + option version '0.0.9' option config 'netifyd' option installed '0' option enabled '0' @@ -45,9 +48,10 @@ config module 'wireguard' option name 'WireGuard Dashboard' option description 'Modern VPN with QR codes' option category 'network' - option icon 'lock' + option icon '🔒' option color '#06b6d4' option package 'luci-app-wireguard-dashboard' + option version '0.0.9' option config 'wireguard' option installed '0' option enabled '0' @@ -56,9 +60,10 @@ config module 'network_modes' option name 'Network Modes' option description 'Network topology configuration' option category 'network' - option icon 'git-branch' + option icon '🌐' option color '#f97316' option package 'luci-app-network-modes' + option version '0.0.9' option config 'network_modes' option installed '0' option enabled '0' @@ -67,9 +72,10 @@ config module 'client_guardian' option name 'Client Guardian' option description 'NAC and captive portal' option category 'security' - option icon 'eye' + option icon 'đŸ‘ī¸' option color '#ef4444' option package 'luci-app-client-guardian' + option version '0.0.9' option config 'client_guardian' option installed '0' option enabled '0' @@ -78,9 +84,10 @@ config module 'system_hub' option name 'System Hub' option description 'Unified control center' option category 'system' - option icon 'sliders' + option icon 'âš™ī¸' option color '#6366f1' option package 'luci-app-system-hub' + option version '0.0.9' option config 'system_hub' option installed '0' option enabled '0' @@ -89,9 +96,10 @@ config module 'cdn_cache' option name 'CDN Cache' option description 'Local caching proxy' option category 'network' - option icon 'package' + option icon 'đŸ“Ļ' option color '#06b6d4' option package 'luci-app-cdn-cache' + option version '0.0.9' option config 'cdn-cache' option installed '0' option enabled '0' @@ -100,9 +108,10 @@ config module 'bandwidth_manager' option name 'Bandwidth Manager' option description 'QoS and bandwidth quotas' option category 'network' - option icon 'activity' + option icon '📡' option color '#3b82f6' option package 'luci-app-bandwidth-manager' + option version '0.0.9' option config 'bandwidth_manager' option installed '0' option enabled '0' @@ -111,9 +120,10 @@ config module 'auth_guardian' option name 'Auth Guardian' option description 'Advanced authentication system' option category 'security' - option icon 'key' + option icon '🔑' option color '#f59e0b' option package 'luci-app-auth-guardian' + option version '0.0.9' option config 'auth_guardian' option installed '0' option enabled '0' @@ -122,9 +132,10 @@ config module 'media_flow' option name 'Media Flow' option description 'Media traffic detection and optimization' option category 'network' - option icon 'play-circle' + option icon 'â–ļī¸' option color '#ec4899' option package 'luci-app-media-flow' + option version '0.0.9' option config 'media_flow' option installed '0' option enabled '0' @@ -133,9 +144,10 @@ config module 'vhost_manager' option name 'Virtual Host Manager' option description 'Virtual host configuration' option category 'system' - option icon 'server' + option icon 'đŸ–Ĩī¸' option color '#8b5cf6' option package 'luci-app-vhost-manager' + option version '0.0.9' option config 'vhost_manager' option installed '0' option enabled '0' @@ -144,9 +156,10 @@ config module 'traffic_shaper' option name 'Traffic Shaper' option description 'Advanced traffic shaping' option category 'network' - option icon 'trending-up' + option icon '📈' option color '#10b981' option package 'luci-app-traffic-shaper' + option version '0.0.9' option config 'traffic_shaper' option installed '0' option enabled '0' @@ -155,9 +168,10 @@ config module 'ksm_manager' option name 'KSM Manager' option description 'Key Storage & HSM management' option category 'security' - option icon 'key' + option icon '🔐' option color '#ef4444' option package 'luci-app-ksm-manager' + option version '0.0.9' option config 'ksm_manager' option installed '0' option enabled '0' diff --git a/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox b/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox index a46278e9..4b616153 100755 --- a/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox +++ b/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox @@ -135,7 +135,7 @@ get_modules() { local module_sections=$(uci -q show secubox | grep "=module$" | cut -d. -f2 | cut -d= -f1) for module in $module_sections; do - local name desc category icon color package config + local name desc category icon color package config version config_get name "$module" name "$module" config_get desc "$module" description "" @@ -144,6 +144,7 @@ get_modules() { config_get color "$module" color "#64748b" config_get package "$module" package "" config_get config "$module" config "" + config_get version "$module" version "0.0.9" local is_installed=$(check_module_installed "$module") local is_running=$(check_module_running "$module") @@ -157,6 +158,7 @@ get_modules() { json_add_string "color" "$color" json_add_string "package" "$package" json_add_string "config" "$config" + json_add_string "version" "$version" json_add_boolean "installed" "$is_installed" json_add_boolean "running" "$is_running" json_close_object @@ -183,7 +185,7 @@ get_modules_by_category() { config_get mod_category "$module" category "other" if [ "$mod_category" = "$category" ]; then - local name desc icon color package config + local name desc icon color package config version config_get name "$module" name "$module" config_get desc "$module" description "" @@ -191,6 +193,7 @@ get_modules_by_category() { config_get color "$module" color "#64748b" config_get package "$module" package "" config_get config "$module" config "" + config_get version "$module" version "0.0.9" local is_installed=$(check_module_installed "$module") local is_running=$(check_module_running "$module") @@ -201,6 +204,7 @@ get_modules_by_category() { json_add_string "description" "$desc" json_add_string "icon" "$icon" json_add_string "color" "$color" + json_add_string "version" "$version" json_add_boolean "installed" "$is_installed" json_add_boolean "running" "$is_running" json_close_object @@ -214,11 +218,11 @@ get_modules_by_category() { # Get single module info get_module_info() { local module="$1" - + config_load secubox - - local name desc category icon color package config - + + local name desc category icon color package config version + config_get name "$module" name "$module" config_get desc "$module" description "" config_get category "$module" category "other" @@ -226,10 +230,11 @@ get_module_info() { config_get color "$module" color "#64748b" config_get package "$module" package "" config_get config "$module" config "" - + config_get version "$module" version "0.0.9" + local is_installed=$(check_module_installed "$module") local is_running=$(check_module_running "$module") - + json_init json_add_string "id" "$module" json_add_string "name" "$name" @@ -239,6 +244,7 @@ get_module_info() { json_add_string "color" "$color" json_add_string "package" "$package" json_add_string "config" "$config" + json_add_string "version" "$version" json_add_boolean "installed" "$is_installed" json_add_boolean "running" "$is_running" json_dump