From 693c18be2fa6b915d3a4e9599638911f3218996a Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Fri, 30 Jan 2026 09:27:56 +0100 Subject: [PATCH] feat(secubox): Add P2P Hub API and wizard-first menu - Make Setup Wizard the first menu item in SecuBox (order 5) - Add P2P Hub collaborative catalog API methods: - Peer discovery and management - Catalog sharing between SecuBox instances - Settings for P2P sharing preferences - Fix crowdsec-dashboard theme.js to return class instead of instance - Update views to properly instantiate theme class Co-Authored-By: Claude Opus 4.5 --- .../resources/crowdsec-dashboard/theme.js | 7 ++- .../view/crowdsec-dashboard/overview.js | 10 ++- .../view/crowdsec-dashboard/settings.js | 18 +++--- .../luci-static/resources/secubox/api.js | 63 +++++++++++++++++++ .../share/luci/menu.d/luci-app-secubox.json | 22 +++---- 5 files changed, 96 insertions(+), 24 deletions(-) diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js index 16423f90..ebc88999 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/crowdsec-dashboard/theme.js @@ -12,9 +12,12 @@ * - cyberpunk: Neon glow effects with orange/cyan accents * * Profiles can extend themes with custom configurations + * + * Usage: var theme = new (require('crowdsec-dashboard.theme'))(); + * theme.init().then(function() { ... }); */ -var ThemeManager = baseclass.extend({ +return baseclass.extend({ // Available themes themes: { 'classic': { @@ -241,5 +244,3 @@ var ThemeManager = baseclass.extend({ return 'cs-dashboard theme-' + (this.currentTheme || 'classic'); } }); - -return new ThemeManager(); diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js index 4f6dceea..e6b9fb03 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/overview.js @@ -5,7 +5,7 @@ 'require ui'; 'require uci'; 'require crowdsec-dashboard.api as api'; -'require crowdsec-dashboard.theme as theme'; +'require crowdsec-dashboard.theme as ThemeClass'; /** * CrowdSec SOC Dashboard - Overview @@ -13,12 +13,16 @@ * Version 1.1.0 */ +var themeInstance = new ThemeClass(); + return view.extend({ title: _('CrowdSec SOC'), + theme: themeInstance, load: function() { + var self = this; return Promise.all([ - theme.init(), + self.theme.init(), api.getOverview().catch(function() { return {}; }) ]); }, @@ -30,7 +34,7 @@ return view.extend({ // Apply theme class document.body.classList.add('cs-fullwidth'); - var view = E('div', { 'class': theme.getDashboardClass() }, [ + var view = E('div', { 'class': self.theme.getDashboardClass() }, [ this.renderHeader(status), this.renderNav('overview'), E('div', { 'id': 'cs-stats' }, this.renderStats(status)), diff --git a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js index c764d55c..fde6c79c 100644 --- a/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js +++ b/package/secubox/luci-app-crowdsec-dashboard/htdocs/luci-static/resources/view/crowdsec-dashboard/settings.js @@ -4,7 +4,7 @@ 'require ui'; 'require uci'; 'require crowdsec-dashboard.api as api'; -'require crowdsec-dashboard.theme as theme'; +'require crowdsec-dashboard.theme as ThemeClass'; /** * CrowdSec SOC - Settings View @@ -12,15 +12,19 @@ * With theme/appearance settings */ +var themeInstance = new ThemeClass(); + return view.extend({ title: _('Settings'), status: {}, machines: [], collections: [], + theme: themeInstance, load: function() { + var self = this; return Promise.all([ - theme.init(), + self.theme.init(), api.getStatus(), api.getMachines(), api.getCollections(), @@ -42,7 +46,7 @@ return view.extend({ document.body.classList.add('cs-fullwidth'); - return E('div', { 'class': theme.getDashboardClass() }, [ + return E('div', { 'class': self.theme.getDashboardClass() }, [ this.renderHeader(), this.renderNav('settings'), E('div', { 'class': 'cs-stats' }, this.renderServiceStats()), @@ -89,8 +93,8 @@ return view.extend({ var currentTheme = uci.get('crowdsec-dashboard', 'main', 'theme') || 'classic'; var currentProfile = uci.get('crowdsec-dashboard', 'main', 'profile') || 'default'; - var themes = theme.getThemes(); - var profiles = theme.getProfiles(); + var themes = this.theme.getThemes(); + var profiles = this.theme.getProfiles(); return E('div', {}, [ E('div', { 'style': 'margin-bottom: 16px;' }, [ @@ -127,11 +131,11 @@ return view.extend({ }, previewTheme: function(themeName) { - theme.switchTheme(themeName); + this.theme.switchTheme(themeName); }, previewProfile: function(profileName) { - theme.switchProfile(profileName); + this.theme.switchProfile(profileName); }, saveAppearance: function() { diff --git a/package/secubox/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js b/package/secubox/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js index e2a29ab4..a6198dd8 100644 --- a/package/secubox/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js +++ b/package/secubox/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js @@ -227,6 +227,60 @@ var callRemoveAppstoreApp = rpc.declare({ expect: { success: false } }); +// P2P Hub methods - Collaborative peer-to-peer app catalog sharing +var callGetP2PPeers = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_get_peers', + expect: { peers: [] } +}); + +var callP2PDiscover = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_discover', + expect: { peers: [], discovered: 0 } +}); + +var callP2PAddPeer = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_add_peer', + params: ['address', 'name'], + expect: { success: false } +}); + +var callP2PRemovePeer = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_remove_peer', + params: ['peer_id'], + expect: { success: false } +}); + +var callP2PGetPeerCatalog = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_get_peer_catalog', + params: ['peer_id'], + expect: { apps: [] } +}); + +var callP2PShareCatalog = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_share_catalog', + params: ['enabled'], + expect: { success: false } +}); + +var callP2PGetSettings = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_get_settings', + expect: { } +}); + +var callP2PSetSettings = rpc.declare({ + object: 'luci.secubox', + method: 'p2p_set_settings', + params: ['settings'], + expect: { success: false } +}); + function formatUptime(seconds) { if (!seconds) return '0s'; var d = Math.floor(seconds / 86400); @@ -284,6 +338,15 @@ return baseclass.extend({ getAppstoreApp: callGetAppstoreApp, installAppstoreApp: callInstallAppstoreApp, removeAppstoreApp: callRemoveAppstoreApp, + // P2P Hub - Collaborative catalog sharing + getP2PPeers: callGetP2PPeers, + p2pDiscover: callP2PDiscover, + p2pAddPeer: callP2PAddPeer, + p2pRemovePeer: callP2PRemovePeer, + p2pGetPeerCatalog: callP2PGetPeerCatalog, + p2pShareCatalog: callP2PShareCatalog, + p2pGetSettings: callP2PGetSettings, + p2pSetSettings: callP2PSetSettings, // Utilities formatUptime: formatUptime, formatBytes: formatBytes diff --git a/package/secubox/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json b/package/secubox/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json index fae2a9b4..5e325c09 100644 --- a/package/secubox/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json +++ b/package/secubox/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json @@ -9,6 +9,17 @@ "acl": ["luci-app-secubox"] } }, + "admin/secubox/wizard": { + "title": "Setup Wizard", + "order": 5, + "action": { + "type": "view", + "path": "secubox/wizard" + }, + "depends": { + "acl": ["luci-app-secubox"] + } + }, "admin/secubox/dashboard": { "title": "Dashboard", "order": 10, @@ -20,17 +31,6 @@ "acl": ["luci-app-secubox"] } }, - "admin/secubox/wizard": { - "title": "First-Run Wizard", - "order": 15, - "action": { - "type": "view", - "path": "secubox/wizard" - }, - "depends": { - "acl": ["luci-app-secubox"] - } - }, "admin/secubox/apps": { "title": "App Store", "order": 18,