From 6314884f009d6ef8483a9e7efea1eef86a25f915 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sun, 28 Dec 2025 16:29:04 +0100 Subject: [PATCH] feat: Add help system integration and fix menu structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created help system (help.js, help.css) for all modules - Integrated help button in network-modes module - Fixed menu structure: removed empty Network Management category - Fixed all dashboard and modules page links - Added website deployment script - Created comprehensive documentation New Files: - DOCS/HELP_INTEGRATION_PLAN.md - DOCS/WEBSITE_DEPLOYMENT_GUIDE.md - EXAMPLES/help-button-integration.js - luci-app-secubox/htdocs/luci-static/resources/secubox/help.js - luci-app-secubox/htdocs/luci-static/resources/secubox/help.css - secubox-tools/deploy-website.sh Modified: - luci-app-network-modes: Added help button integration - luci-app-secubox: Fixed menu paths and module links πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .claude/context.md | 203 ++------ .codex/context.md | 1 + DOCS/HELP_INTEGRATION_PLAN.md | 441 ++++++++++++++++++ DOCS/MODULE_STATUS.md | 8 +- DOCS/WEBSITE_DEPLOYMENT_GUIDE.md | 361 ++++++++++++++ EXAMPLES/README.md | 140 ++++++ EXAMPLES/help-button-integration.js | 356 ++++++++++++++ .../resources/view/network-modes/overview.js | 10 +- .../root/usr/libexec/rpcd/luci.network-modes | 43 +- .../luci/menu.d/luci-app-network-modes.json | 16 +- .../resources/secubox/dashboard.css | 12 + .../luci-static/resources/secubox/help.css | 322 +++++++++++++ .../luci-static/resources/secubox/help.js | 183 ++++++++ .../luci-static/resources/secubox/modules.css | 12 + .../luci-static/resources/secubox/secubox.css | 242 ++++++++++ .../resources/view/secubox/dashboard.js | 96 ++-- .../resources/view/secubox/help.js | 203 ++++++++ .../resources/view/secubox/modules.js | 65 +-- .../share/luci/menu.d/luci-app-secubox.json | 10 +- scripts/sync_module_versions.py | 68 +++ scripts/sync_module_versions.sh | 6 + secubox-tools/deploy-website.sh | 99 ++++ 22 files changed, 2648 insertions(+), 249 deletions(-) create mode 100644 DOCS/HELP_INTEGRATION_PLAN.md create mode 100644 DOCS/WEBSITE_DEPLOYMENT_GUIDE.md create mode 100644 EXAMPLES/README.md create mode 100644 EXAMPLES/help-button-integration.js create mode 100644 luci-app-secubox/htdocs/luci-static/resources/secubox/help.css create mode 100644 luci-app-secubox/htdocs/luci-static/resources/secubox/help.js create mode 100644 luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js create mode 100755 scripts/sync_module_versions.py create mode 100755 scripts/sync_module_versions.sh create mode 100755 secubox-tools/deploy-website.sh diff --git a/.claude/context.md b/.claude/context.md index af687816..379e975b 100644 --- a/.claude/context.md +++ b/.claude/context.md @@ -1,164 +1,59 @@ -# SecuBox Project Context for Claude AI +# SecuBox Context -## 🎯 Project Identity +## What SecuBox OpenWrt Suite Is +SecuBox is a suite of LuCI applications that ship advanced security, monitoring, and automation dashboards for OpenWrt routers. Each `luci-app-*` package combines LuCI JavaScript views, RPCD backends, UCI integration, ACL policies, and shared CSS built on the SecuBox design system (dark-first palette, Inter + JetBrains Mono). GitHub Actions builds the packages for every supported architecture (`x86`, `ARM`, `MIPS`) and the repo also carries tooling for validation, repair, deployment, and firmware image creation. -**Name**: SecuBox -**Type**: Modular security suite for OpenWrt routers -**Version**: 1.0.0 -**Author**: CyberMind.fr (Gandalf) -**License**: Apache-2.0 +## Repository Layout +- `.claude/` – authoritative assistant guidance, prompts, and settings +- `.github/workflows/` – CI definitions (package build matrix, validation, firmware images) +- `luci-app-*/` – one directory per LuCI module (Makefile, README, `htdocs/`, `root/`) +- `secubox-tools/` – validation/build/deploy helpers (`local-build.sh`, `validate-modules.sh`, etc.) +- `templates/` – scaffolding for new LuCI packages +- Root docs: `README.md`, `QUICK-START.md`, `DEVELOPMENT-GUIDELINES.md`, `CLAUDE.md`, `DOCUMENTATION-INDEX.md`, `CODE-TEMPLATES.md`, `FEATURE-REGENERATION-PROMPTS.md`, `MODULE_STATUS.md`, `PERMISSIONS-GUIDE.md`, `VALIDATION-GUIDE.md`, etc. +- Deploy scripts: `deploy-module-template.sh`, `deploy-*.sh` (system hub, secubox, beta releases, etc.) +- Test fixtures: `test-direct.js`, `test-modules-simple.js` -## πŸ—οΈ Architecture Overview +## Module Map (Purpose & Entry Points) +Each module follows the same structure: `Makefile`, module-specific README, JavaScript views under `htdocs/luci-static/resources/view//`, API helpers under `htdocs/luci-static/resources//api.js`, CSS in the same folder, RPCD backend in `root/usr/libexec/rpcd/luci.`, menu JSON under `root/usr/share/luci/menu.d/`, and ACL JSON under `root/usr/share/rpcd/acl.d/`. -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ LuCI Web Interface β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ View.js β”‚ β”‚ View.js β”‚ β”‚ View.js β”‚ β”‚ View.js β”‚ ... β”‚ -β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ JSON-RPC β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ RPCD Daemon β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Script β”‚ β”‚ Script β”‚ β”‚ Script β”‚ β”‚ Script β”‚ ... β”‚ -β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ β”‚ UCI β”‚ Shell β”‚ System β”‚ β”‚ -β”‚ β”‚ Config β”‚ Commands β”‚ Services β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` +| Module | Purpose | Primary Views (JS) | +|--------|---------|--------------------| +| `luci-app-secubox` | Central SecuBox hub (module launcher, dashboard, dev status) | `secubox/dashboard.js`, `modules.js`, `modules-minimal.js`, `dev-status.js`, `alerts.js`, `monitoring.js`, `settings.js` +| `luci-app-system-hub` | System control center (health, services, diagnostics, remote) | `system-hub/overview.js`, `health.js`, `services.js`, `components.js`, `logs.js`, `backup.js`, `diagnostics.js`, `remote.js`, `settings.js`, `dev-status.js` +| `luci-app-crowdsec-dashboard` | CrowdSec decision, alerts, bouncer management | `crowdsec-dashboard/overview.js`, `alerts.js`, `decisions.js`, `bouncers.js`, `metrics.js`, `settings.js` +| `luci-app-netdata-dashboard` | Netdata monitoring integration | `netdata-dashboard/dashboard.js`, `system.js`, `network.js`, `processes.js`, `realtime.js`, `settings.js` +| `luci-app-netifyd-dashboard` | DPI / application intelligence | `netifyd-dashboard/overview.js`, `applications.js`, `devices.js`, `flows.js`, `risks.js`, `talkers.js`, `settings.js` +| `luci-app-network-modes` | Switch router/AP/bridge/sniffer modes | `network-modes/overview.js`, `wizard.js`, `sniffer.js`, `accesspoint.js`, `relay.js`, `router.js`, `settings.js` +| `luci-app-wireguard-dashboard` | WireGuard VPN monitoring/config | `wireguard-dashboard/overview.js`, `peers.js`, `traffic.js`, `config.js`, `settings.js`, `qrcodes.js` +| `luci-app-client-guardian` | NAC + captive portal + parental controls | `client-guardian/overview.js`, `clients.js`, `zones.js`, `portal.js`, `captive.js`, `alerts.js`, `parental.js`, `settings.js`, `logs.js` +| `luci-app-auth-guardian` | Authentication/voucher/OAuth portal | `auth-guardian/overview.js`, `sessions.js`, `vouchers.js`, `oauth.js`, `splash.js`, `bypass.js` +| `luci-app-bandwidth-manager` | QoS, quotas, priority classes | `bandwidth-manager/overview.js`, `classes.js`, `rules.js`, `schedules.js`, `media.js`, `clients.js`, `usage.js`, `quotas.js`, `settings.js` +| `luci-app-media-flow` | Streaming/media traffic analytics | `media-flow/dashboard.js`, `services.js`, `clients.js`, `history.js`, `alerts.js` +| `luci-app-cdn-cache` | Local CDN cache policies & stats | `cdn-cache/overview.js`, `policies.js`, `cache.js`, `statistics.js`, `maintenance.js`, `settings.js` +| `luci-app-vhost-manager` | Virtual hosts & SSL orchestration | `vhost-manager/overview.js`, `vhosts.js`, `internal.js`, `redirects.js`, `ssl.js`, `certificates.js`, `logs.js` +| `luci-app-traffic-shaper` | Advanced traffic shaping presets | `traffic-shaper/overview.js`, `classes.js`, `rules.js`, `stats.js`, `presets.js` +| `luci-app-ksm-manager` | Secure key/certificate management | `ksm-manager/overview.js`, `keys.js`, `secrets.js`, `certificates.js`, `ssh.js`, `hsm.js`, `audit.js`, `settings.js` -## πŸ“ Module Structure Template +(Modules not listed explicitly above share the same structure; inspect each `luci-app-*/htdocs/luci-static/resources/view//` directory for the definitive entrypoints.) -``` -luci-app-{module-name}/ -β”œβ”€β”€ Makefile # OpenWrt package definition -β”œβ”€β”€ README.md # Module documentation -β”œβ”€β”€ htdocs/ -β”‚ └── luci-static/ -β”‚ └── resources/ -β”‚ └── view/ -β”‚ └── {module_name}/ # Underscore version -β”‚ β”œβ”€β”€ main.js # Main view -β”‚ └── {subview}.js # Optional subviews -└── root/ - β”œβ”€β”€ etc/ - β”‚ β”œβ”€β”€ config/ - β”‚ β”‚ └── {module_name} # UCI configuration - β”‚ β”œβ”€β”€ init.d/ - β”‚ β”‚ └── {module_name} # Service init script (optional) - β”‚ └── uci-defaults/ - β”‚ └── 99-{module_name} # First-run setup - └── usr/ - β”œβ”€β”€ libexec/ - β”‚ └── rpcd/ - β”‚ └── {module-name} # Hyphen version - RPCD backend - └── share/ - β”œβ”€β”€ luci/ - β”‚ └── menu.d/ - β”‚ └── luci-app-{module-name}.json - └── rpcd/ - └── acl.d/ - └── luci-app-{module-name}.json -``` +## Stack & Integration Points +- **Frontend**: LuCI JavaScript views (`view.extend`) + SecuBox design system CSS. Every view imports the per-module `api.js` module for ubus calls and includes shared styles like `system-hub/common.css`. +- **Backend**: RPCD shell scripts under `root/usr/libexec/rpcd/luci.` expose ubus methods (`status`, `get_*`, `set_*`, etc.). Modules often also ship helper scripts under `/usr/libexec/secubox/` and UCI defaults under `root/etc/uci-defaults/`. +- **UBus / RPC**: JavaScript uses `rpc.declare` with `object: 'luci.'`. RPCD `list` and `call` cases must mirror these names. +- **Menu/ACL**: JSON files in `root/usr/share/luci/menu.d/` and `root/usr/share/rpcd/acl.d/` keep navigation and permissions consistent with the views and RPCD backend. +- **Packaging**: OpenWrt LuCI package Makefiles include `luci.mk`, define `PKG_FILE_MODES` for executable scripts (typically RPCD 755), and mark packages as `LUCI_PKGARCH:=all` because they are script-only. -## πŸ“‹ Naming Conventions - -| Context | Format | Example | -|---------|--------|---------| -| Package name | luci-app-{module-name} | luci-app-vhost-manager | -| RPCD script | {module-name} | vhost-manager | -| UCI config | {module_name} | vhost_manager | -| View path | {module_name}/ | vhost_manager/ | -| ubus object | luci.{module-name} | luci.vhost-manager | -| Menu path | admin/services/{module_name} | admin/services/vhost_manager | - -## πŸ”§ Code Standards - -### Makefile Template - -```makefile -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-{module-name} -PKG_VERSION:=1.0.0 -PKG_RELEASE:=1 -PKG_LICENSE:=Apache-2.0 -PKG_MAINTAINER:=CyberMind - -LUCI_TITLE:=LuCI - {Module Title} -LUCI_DESCRIPTION:={Description} -LUCI_DEPENDS:=+luci-base +rpcd {+other-deps} -LUCI_PKGARCH:=all - -include $(TOPDIR)/feeds/luci/luci.mk -``` - -### RPCD Script Template - -```sh -#!/bin/sh -# RPCD backend for {module-name} - -. /lib/functions.sh -. /usr/share/libubox/jshn.sh - -json_init - -case "$1" in - list) - # MUST list all available methods - json_add_object "status" - json_close_object - json_add_object "get_config" - json_close_object - json_add_object "set_config" - json_add_string "config" "object" - json_close_object - # Add more methods here - json_dump - ;; - - call) - case "$2" in - status) - # MUST implement status method - json_add_string "module" "{module-name}" - json_add_string "version" "2.0.0" - json_add_boolean "enabled" 1 - json_add_string "status" "running" - json_dump - ;; - - get_config) - # Read from UCI - json_add_object "config" - # config_load "{module_name}" - json_close_object - json_dump - ;; - - set_config) - read -r input - json_load "$input" - # Apply to UCI - json_init - json_add_boolean "success" 1 - json_dump - ;; - - *) - json_add_int "error" -32601 - json_add_string "message" "Method not found" - json_dump - ;; - esac - ;; -esac -``` +## Glossary +- **LuCI** – OpenWrt web interface framework (Lua backend + JS frontend) +- **RPCD** – Daemon providing ubus RPC endpoints; modules drop scripts in `/usr/libexec/rpcd/` +- **ubus** – OpenWrt message bus used for remote procedure calls +- **UCI** – Unified Configuration Interface (files in `/etc/config/`) +- **ACL** – RPCD permission JSON files in `/usr/share/rpcd/acl.d/` +- **PKG_FILE_MODES** – Makefile variable forcing specific permissions for installed files +- **SecuBox Design System** – Shared CSS variables (`--sh-*`) and components defined in `system-hub/common.css` +- **Validation suite** – `./secubox-tools/validate-modules.sh`, `validate-module-generation.sh`, `pre-push-validation.sh` +- **Deploy script** – `deploy-module-template.sh` (backup, copy JS/CSS/RPCD/menu/ACL, fix perms, restart services) +- **Fix permissions** – Toujours lancer `./secubox-tools/fix-permissions.sh --local` avant commit et `--remote ` aprΓ¨s dΓ©ploiement pour garantir `644` sur CSS/JS et `755` sur scripts exΓ©cutables ### ACL File Template diff --git a/.codex/context.md b/.codex/context.md index 8f21de36..a4962082 100644 --- a/.codex/context.md +++ b/.codex/context.md @@ -53,3 +53,4 @@ Each module follows the same structure: `Makefile`, module-specific README, Java - **SecuBox Design System** – Shared CSS variables (`--sh-*`) and components defined in `system-hub/common.css` - **Validation suite** – `./secubox-tools/validate-modules.sh`, `validate-module-generation.sh`, `pre-push-validation.sh` - **Deploy script** – `deploy-module-template.sh` (backup, copy JS/CSS/RPCD/menu/ACL, fix perms, restart services) +- **Fix permissions** – Always run `./secubox-tools/fix-permissions.sh --local` before committing and `--remote ` after deploying to enforce `644` web assets / `755` executables diff --git a/DOCS/HELP_INTEGRATION_PLAN.md b/DOCS/HELP_INTEGRATION_PLAN.md new file mode 100644 index 00000000..f40612c6 --- /dev/null +++ b/DOCS/HELP_INTEGRATION_PLAN.md @@ -0,0 +1,441 @@ +# SecuBox Website Help/Info Button Integration Plan + +**Version:** 1.0 +**Date:** 2025-12-28 +**Status:** Planning Phase + +## Overview + +This document outlines the strategy for integrating the SecuBox marketing/documentation website with the OpenWrt LuCI modules, providing seamless access to help documentation via help/info buttons in each module. + +## Current Architecture + +### Website Location +- **Remote URL:** `https://secubox.cybermood.eu/` +- **Local Router Path:** `/www/luci-static/secubox/` +- **Access URL:** `http://[router-ip]/luci-static/secubox/` + +### Module Structure +All SecuBox modules follow a consistent pattern: +``` +luci-app-{module-name}/ +β”œβ”€β”€ htdocs/luci-static/resources/ +β”‚ β”œβ”€β”€ view/{module-name}/ +β”‚ β”‚ β”œβ”€β”€ overview.js (main dashboard) +β”‚ β”‚ └── *.js (other views) +β”‚ └── {module-name}/ +β”‚ β”œβ”€β”€ api.js +β”‚ β”œβ”€β”€ theme.js (optional) +β”‚ └── *.css +``` + +### Key Modules +1. **luci-app-secubox** - Central control hub +2. **luci-app-system-hub** - System monitoring +3. **luci-app-network-modes** - Network configuration +4. **luci-app-client-guardian** - Client management +5. **luci-app-bandwidth-manager** - Traffic shaping +6. **luci-app-cdn-cache** - CDN caching +7. **luci-app-traffic-shaper** - QoS management +8. **luci-app-wireguard-dashboard** - VPN management +9. **luci-app-crowdsec-dashboard** - Security monitoring +10. **luci-app-netdata-dashboard** - Performance metrics + +## Integration Strategy + +### Phase 1: Shared Help Utilities (RECOMMENDED) + +Create a centralized help button library that all modules can use. + +#### Implementation Steps + +1. **Create Shared Help Module** + ```javascript + // Location: luci-app-secubox/htdocs/luci-static/resources/secubox/help.js + + 'use strict'; + 'require baseclass'; + + return baseclass.extend({ + /** + * Create a help button element + * @param {string} moduleName - Module identifier (e.g., 'network-modes') + * @param {string} position - Button position: 'header', 'footer', 'floating' + * @param {object} options - Custom options + */ + createHelpButton: function(moduleName, position, options) { + var opts = options || {}; + var helpUrl = this.getHelpUrl(moduleName); + var buttonClass = 'sb-help-btn sb-help-' + position; + + return E('a', { + 'class': buttonClass, + 'href': helpUrl, + 'target': opts.target || '_blank', + 'title': opts.title || _('View Help & Documentation') + }, [ + E('span', { 'class': 'sb-help-icon' }, opts.icon || '❓'), + opts.showLabel !== false ? E('span', { 'class': 'sb-help-label' }, opts.label || _('Help')) : null + ]); + }, + + /** + * Get help URL for a module + * @param {string} moduleName - Module identifier + */ + getHelpUrl: function(moduleName) { + var baseUrl = '/luci-static/secubox/'; + var moduleMap = { + 'secubox': 'index.html#modules', + 'system-hub': 'demo-secubox-hub.html', + 'network-modes': 'demo-network-modes.html', + 'client-guardian': 'demo-client-guardian.html', + 'bandwidth-manager': 'demo-bandwidth.html', + 'cdn-cache': 'demo-cdn-cache.html', + 'traffic-shaper': 'demo-traffic-shaper.html', + 'wireguard-dashboard': 'demo-wireguard.html', + 'crowdsec-dashboard': 'demo-crowdsec.html', + 'netdata-dashboard': 'demo-netdata.html', + 'netifyd-dashboard': 'demo-netifyd.html', + 'auth-guardian': 'demo-auth.html', + 'vhost-manager': 'demo-vhost.html', + 'ksm-manager': 'demo-ksm-manager.html', + 'media-flow': 'demo-media.html' + }; + + return baseUrl + (moduleMap[moduleName] || 'index.html'); + }, + + /** + * Open help in modal (for inline help) + * @param {string} moduleName - Module identifier + */ + openHelpModal: function(moduleName) { + var helpUrl = this.getHelpUrl(moduleName); + var iframe = E('iframe', { + 'src': helpUrl, + 'style': 'width: 100%; height: 70vh; border: none; border-radius: 8px;' + }); + + ui.showModal(_('Help & Documentation'), [ + E('div', { 'style': 'min-height: 70vh;' }, [iframe]), + E('div', { 'class': 'right', 'style': 'margin-top: 1rem;' }, [ + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ]); + } + }); + ``` + +2. **Create Common CSS Styles** + ```css + /* Location: luci-app-secubox/htdocs/luci-static/resources/secubox/help.css */ + + /* Base Help Button Styles */ + .sb-help-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border-radius: 8px; + text-decoration: none; + font-weight: 500; + transition: all 0.3s ease; + border: 2px solid transparent; + cursor: pointer; + } + + .sb-help-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); + border-color: rgba(255, 255, 255, 0.3); + } + + .sb-help-icon { + font-size: 1.2em; + } + + /* Header Position */ + .sb-help-header { + margin-left: auto; + padding: 0.4rem 0.8rem; + font-size: 0.9em; + } + + /* Footer Position */ + .sb-help-footer { + margin-top: 2rem; + } + + /* Floating Button (bottom-right) */ + .sb-help-floating { + position: fixed; + bottom: 2rem; + right: 2rem; + z-index: 1000; + border-radius: 50%; + width: 60px; + height: 60px; + padding: 0; + justify-content: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + } + + .sb-help-floating .sb-help-label { + display: none; + } + + .sb-help-floating .sb-help-icon { + font-size: 1.8em; + } + + /* Dark theme adjustments */ + [data-theme="dark"] .sb-help-btn { + background: linear-gradient(135deg, #4c51bf 0%, #553c9a 100%); + } + ``` + +3. **Update Each Module** + + **Example: luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js** + ```javascript + 'use strict'; + 'require view'; + 'require dom'; + 'require ui'; + 'require network-modes.api as api'; + 'require secubox/help as Help'; // ADD THIS + + return view.extend({ + title: _('Network Modes'), + + load: function() { + return api.getAllData(); + }, + + render: function(data) { + var self = this; + // ... existing code ... + + var view = E('div', { 'class': 'network-modes-dashboard' }, [ + // Load help CSS + E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/help.css') }), + + // Header with help button + E('div', { 'class': 'nm-header' }, [ + E('div', { 'class': 'nm-logo' }, [ + E('div', { 'class': 'nm-logo-icon' }, '🌐'), + E('div', { 'class': 'nm-logo-text' }, ['Network ', E('span', {}, 'Configuration')]) + ]), + E('div', { 'class': 'nm-mode-badge ' + currentMode }, [ + E('span', { 'class': 'nm-mode-dot' }), + currentModeInfo ? currentModeInfo.name : currentMode + ]), + // ADD HELP BUTTON + Help.createHelpButton('network-modes', 'header', { + icon: 'πŸ“–', + label: _('Help') + }) + ]), + + // ... rest of the UI ... + ]); + + return view; + } + }); + ``` + +### Phase 2: Alternative Approaches + +#### Approach A: Floating Help Button +Add a global floating help button that appears on all SecuBox module pages. + +**Pros:** +- Non-intrusive +- Consistent UX across all modules +- Easy to implement globally + +**Cons:** +- May overlap with other floating elements +- Less discoverable + +#### Approach B: Header Integration +Add help buttons to the header of each module dashboard. + +**Pros:** +- Highly visible +- Natural placement +- Follows common UI patterns + +**Cons:** +- Requires modifications to each module +- May clutter header on small screens + +#### Approach C: Quick Actions Integration +Add help as a quick action in modules that have action panels (like SecuBox dashboard). + +**Pros:** +- Fits existing UI pattern +- Grouped with other utilities +- Consistent with current design + +**Cons:** +- Only works for modules with action panels +- Less prominent + +## Recommended Implementation Plan + +### Step 1: Create Foundation (Week 1) +1. Create `secubox/help.js` utility module +2. Create `secubox/help.css` stylesheet +3. Deploy to test router +4. Verify accessibility + +### Step 2: Integrate Core Modules (Week 2) +Update these critical modules first: +1. `luci-app-secubox` (main dashboard) +2. `luci-app-system-hub` +3. `luci-app-network-modes` + +Test on production router. + +### Step 3: Roll Out to All Modules (Week 3) +Update remaining modules: +1. `luci-app-client-guardian` +2. `luci-app-bandwidth-manager` +3. `luci-app-cdn-cache` +4. `luci-app-traffic-shaper` +5. `luci-app-wireguard-dashboard` +6. `luci-app-crowdsec-dashboard` +7. `luci-app-netdata-dashboard` +8. Other modules + +### Step 4: User Testing & Refinement (Week 4) +1. Gather user feedback +2. Adjust positioning/styling +3. Add localization if needed +4. Document for end users + +## Module-to-Help Page Mapping + +| Module | Help Page | Status | +|--------|-----------|--------| +| secubox | index.html#modules | Available | +| system-hub | demo-secubox-hub.html | Available | +| network-modes | demo-network-modes.html | Available | +| client-guardian | demo-client-guardian.html | Available | +| bandwidth-manager | demo-bandwidth.html | Available | +| cdn-cache | demo-cdn-cache.html | Available | +| traffic-shaper | demo-traffic-shaper.html | Available | +| wireguard-dashboard | demo-wireguard.html | Available | +| crowdsec-dashboard | demo-crowdsec.html | Available | +| netdata-dashboard | demo-netdata.html | Available | +| netifyd-dashboard | demo-netifyd.html | Available | +| auth-guardian | demo-auth.html | Available | +| vhost-manager | demo-vhost.html | Available | +| ksm-manager | demo-ksm-manager.html | Available | +| media-flow | demo-media.html | Available | + +## Deployment Workflow + +### Website Updates +```bash +# From secubox-openwrt directory +./secubox-tools/deploy-website.sh root@192.168.8.191 ../secubox-website +``` + +### Module Updates with Help Integration +```bash +# Build and deploy individual module +./secubox-tools/deploy-network-modes.sh root@192.168.8.191 + +# Or build all modules +./secubox-tools/local-build.sh build-all +``` + +## Testing Checklist + +- [ ] Help button appears in module header +- [ ] Help button links to correct documentation page +- [ ] Help page opens in new tab (or modal if configured) +- [ ] Styling is consistent across all modules +- [ ] Button is responsive on mobile devices +- [ ] Dark/light theme support +- [ ] Localization support (if applicable) +- [ ] No JavaScript errors in console +- [ ] Works on both local router and remote deployment + +## Future Enhancements + +### Enhanced Features +1. **Context-Sensitive Help** + - Different help URLs based on current page/section + - Deep linking to specific documentation sections + +2. **Inline Help Tooltips** + - Hover tooltips for specific UI elements + - Quick tips without leaving page + +3. **Help Search** + - Search box in help modal + - Full-text search across documentation + +4. **Interactive Tutorials** + - Step-by-step walkthroughs + - Guided tours for new users + +5. **Changelog Integration** + - Show "What's New" on version updates + - Link to release notes + +## Technical Considerations + +### Performance +- Help resources are static files (no API calls) +- Minimal JavaScript overhead (~2KB) +- CSS loaded only when needed +- No impact on module core functionality + +### Compatibility +- Works with LuCI 18.06+ +- Compatible with all modern browsers +- Graceful degradation for older browsers + +### Security +- All help content served from same origin +- No external dependencies +- No XSS risks (static HTML/CSS/JS) + +### Maintenance +- Centralized help utility (single point of update) +- Module changes are minimal (1-3 lines per module) +- Website updates independent of module updates + +## References + +- **Deployment Script:** `secubox-tools/deploy-website.sh` +- **Module Template:** `secubox-tools/deploy-module-template.sh` +- **Website Repository:** `/home/reepost/CyberMindStudio/_files/secubox-website/` +- **Current Deployment:** `http://192.168.8.191/luci-static/secubox/` + +## Questions & Decisions Needed + +1. **Button Position:** Header, Floating, or both? +2. **Modal vs New Tab:** Should help open in modal or new tab? +3. **Mobile UX:** How should help button behave on small screens? +4. **Localization:** Support multiple languages for help content? +5. **Analytics:** Track help usage (privacy-respecting)? + +## Approval Status + +- [ ] Technical approach approved +- [ ] UI/UX design approved +- [ ] Implementation timeline approved +- [ ] Testing plan approved +- [ ] Deployment strategy approved diff --git a/DOCS/MODULE_STATUS.md b/DOCS/MODULE_STATUS.md index 005456a6..c44f2edf 100644 --- a/DOCS/MODULE_STATUS.md +++ b/DOCS/MODULE_STATUS.md @@ -150,8 +150,8 @@ - **Use Cases**: Traffic analysis, bandwidth optimization, security monitoring #### luci-app-network-modes -- **Version**: 0.3.1-1 -- **Status**: βœ… In Heavily Development Stage +- **Version**: 0.3.5-1 +- **Status**: βœ… Production Ready - **Description**: Dynamic network mode switching and configuration - **Views**: 7 (overview, wizard, router, relay, accesspoint, sniffer, settings) - **JavaScript Lines**: 2,104 @@ -171,8 +171,8 @@ - DHCP server/client mode switching - Interface bridging automation - **Recent Updates**: - - v0.3.1: Enhanced mode switching logic - - Improved configuration persistence + - v0.3.5: Auto-deploy proxies (Squid/TinyProxy/Privoxy), DoH, nginx vhosts, and Let’s Encrypt certificates + - Auto-apply advanced WiFi (802.11r/k/v, band steering) and tcpdump packet capture per mode - **Integration**: network, firewall, DHCP, hostapd/wpa_supplicant --- diff --git a/DOCS/WEBSITE_DEPLOYMENT_GUIDE.md b/DOCS/WEBSITE_DEPLOYMENT_GUIDE.md new file mode 100644 index 00000000..7aefa066 --- /dev/null +++ b/DOCS/WEBSITE_DEPLOYMENT_GUIDE.md @@ -0,0 +1,361 @@ +# SecuBox Website Deployment Guide + +**Version:** 1.0 +**Date:** 2025-12-28 + +## Overview + +This guide explains how to deploy the SecuBox marketing/documentation website to an OpenWrt router, making it accessible locally for help and documentation purposes. + +## Prerequisites + +- OpenWrt router with SSH access +- SecuBox website files (from `secubox-website` repository) +- Network connectivity to router +- Sufficient storage space on router (approx. 1-2 MB) + +## Deployment Script + +### Location +``` +secubox-openwrt/secubox-tools/deploy-website.sh +``` + +### Usage + +#### Basic Deployment +```bash +# Deploy to default router (192.168.1.1) +./secubox-tools/deploy-website.sh + +# Deploy to specific router +./secubox-tools/deploy-website.sh root@192.168.8.191 + +# Deploy from specific website directory +./secubox-tools/deploy-website.sh root@192.168.8.191 /path/to/secubox-website +``` + +#### Full Example +```bash +cd /home/reepost/CyberMindStudio/_files/secubox-openwrt + +# Deploy website to router at 192.168.8.191 +./secubox-tools/deploy-website.sh root@192.168.8.191 ../secubox-website +``` + +### What the Script Does + +1. **Prepares Files** - Creates compressed archive excluding: + - `.git` directory + - `.claude` directory + - Markdown files (*.md) + - README and LICENSE files + +2. **Creates Backup** - Backs up existing website if present + +3. **Deploys Files** - Uploads and extracts to `/www/luci-static/secubox/` + +4. **Sets Permissions** - Ensures proper file permissions: + - Directories: 755 + - HTML files: 644 + - JavaScript files: 644 + - CSS files: 644 + +5. **Cleanup** - Removes temporary files + +## Website Structure on Router + +### Directory Layout +``` +/www/luci-static/secubox/ +β”œβ”€β”€ index.html (main landing page) +β”œβ”€β”€ campaign.html +β”œβ”€β”€ demo-*.html (module demos) +β”œβ”€β”€ dev-status-widget.js +β”œβ”€β”€ i18n.js +β”œβ”€β”€ i18n/ +β”‚ └── *.json (language files) +└── blog/ + └── *.html (blog posts) +``` + +### Access URLs + +After deployment, the website is accessible at: + +- **Local Router:** `http://[router-ip]/luci-static/secubox/` +- **Example:** `http://192.168.8.191/luci-static/secubox/` + +#### Individual Pages +- Main: `http://192.168.8.191/luci-static/secubox/index.html` +- System Hub: `http://192.168.8.191/luci-static/secubox/demo-secubox-hub.html` +- Network Modes: `http://192.168.8.191/luci-static/secubox/demo-network-modes.html` +- Client Guardian: `http://192.168.8.191/luci-static/secubox/demo-client-guardian.html` +- etc. + +## Deployment Workflow + +### 1. Update Website Content + +```bash +# Navigate to website directory +cd /home/reepost/CyberMindStudio/_files/secubox-website + +# Edit files as needed +# Test locally if possible +``` + +### 2. Deploy to Router + +```bash +# Navigate to OpenWrt directory +cd /home/reepost/CyberMindStudio/_files/secubox-openwrt + +# Deploy +./secubox-tools/deploy-website.sh root@192.168.8.191 +``` + +### 3. Verify Deployment + +```bash +# Check files on router +ssh root@192.168.8.191 "ls -la /www/luci-static/secubox/" + +# Test access via browser +curl http://192.168.8.191/luci-static/secubox/index.html +``` + +## Manual Deployment (Alternative) + +If the script doesn't work, you can deploy manually: + +```bash +# 1. Create tarball +cd /path/to/secubox-website +tar czf /tmp/secubox-website.tar.gz \ + --exclude='.git' \ + --exclude='.claude' \ + --exclude='*.md' \ + . + +# 2. Upload to router +scp /tmp/secubox-website.tar.gz root@192.168.8.191:/tmp/ + +# 3. Extract on router +ssh root@192.168.8.191 << 'EOF' +mkdir -p /www/luci-static/secubox +cd /www/luci-static/secubox +tar xzf /tmp/secubox-website.tar.gz +chmod 755 . +find . -type d -exec chmod 755 {} \; +find . -type f -name "*.html" -exec chmod 644 {} \; +find . -type f -name "*.js" -exec chmod 644 {} \; +rm /tmp/secubox-website.tar.gz +EOF + +# 4. Cleanup +rm /tmp/secubox-website.tar.gz +``` + +## Troubleshooting + +### Issue: "No route to host" +**Solution:** Verify router IP address is correct +```bash +ping 192.168.8.191 +``` + +### Issue: "Permission denied" +**Solution:** Ensure SSH access is configured +```bash +# Test SSH connection +ssh root@192.168.8.191 "echo 'Connected'" +``` + +### Issue: "Not enough space" +**Solution:** Check available storage +```bash +ssh root@192.168.8.191 "df -h /www" + +# If needed, clear cache +ssh root@192.168.8.191 "rm -rf /tmp/luci-*" +``` + +### Issue: "Files not accessible via HTTP" +**Solution:** Check web server status +```bash +ssh root@192.168.8.191 "/etc/init.d/uhttpd status" +ssh root@192.168.8.191 "/etc/init.d/uhttpd restart" +``` + +### Issue: "404 Not Found" +**Solution:** Verify files exist and check permissions +```bash +ssh root@192.168.8.191 "ls -la /www/luci-static/secubox/ | head -20" +``` + +## Integration with Modules + +Once deployed, modules can link to the help pages: + +```javascript +// Example: Link to help in a module +var helpUrl = '/luci-static/secubox/demo-network-modes.html'; +var helpButton = E('a', { + 'href': helpUrl, + 'target': '_blank', + 'class': 'btn' +}, 'Help'); +``` + +See `HELP_INTEGRATION_PLAN.md` for detailed integration guide. + +## Maintenance + +### Updating Website + +To update the website after making changes: + +```bash +# 1. Edit files in secubox-website/ +cd /home/reepost/CyberMindStudio/_files/secubox-website +# ... make changes ... + +# 2. Redeploy +cd ../secubox-openwrt +./secubox-tools/deploy-website.sh root@192.168.8.191 +``` + +### Rollback + +If deployment fails, restore from backup: + +```bash +ssh root@192.168.8.191 << 'EOF' +# Find latest backup +BACKUP=$(ls -t /tmp/secubox-website-backup-* | head -1) +if [ -n "$BACKUP" ]; then + rm -rf /www/luci-static/secubox/* + cp -a $BACKUP/* /www/luci-static/secubox/ + echo "Restored from $BACKUP" +fi +EOF +``` + +### Remove Website + +To completely remove the website: + +```bash +ssh root@192.168.8.191 "rm -rf /www/luci-static/secubox" +``` + +## Performance Optimization + +### Enable Compression (Optional) + +Configure uhttpd to serve compressed content: + +```bash +ssh root@192.168.8.191 << 'EOF' +# Add gzip compression to uhttpd config +uci set uhttpd.main.compression='1' +uci commit uhttpd +/etc/init.d/uhttpd restart +EOF +``` + +### Cache Headers (Optional) + +Add cache headers for static assets: + +```bash +ssh root@192.168.8.191 << 'EOF' +# Create .htaccess-like configuration for caching +# (requires additional uhttpd configuration) +EOF +``` + +## Security Considerations + +### Access Control + +The website is publicly accessible on the router's LAN. To restrict access: + +```bash +# Option 1: Firewall rules (restrict to specific IPs) +ssh root@192.168.8.191 << 'EOF' +# Add firewall rules as needed +EOF + +# Option 2: HTTP authentication (requires uhttpd configuration) +``` + +### Content Security + +- Website contains only static HTML/CSS/JavaScript +- No server-side execution +- No database connections +- No sensitive data exposure + +## Automated Deployment + +### Cron Job (Optional) + +To auto-deploy on schedule: + +```bash +# Add to router crontab +ssh root@192.168.8.191 "crontab -e" + +# Add line (example: deploy daily at 3 AM): +# 0 3 * * * cd /tmp && wget http://server/secubox-website.tar.gz && tar xzf secubox-website.tar.gz -C /www/luci-static/secubox/ +``` + +### Git Hook (Advanced) + +Deploy automatically on git push: + +```bash +# In secubox-website/.git/hooks/post-commit +#!/bin/bash +cd /home/reepost/CyberMindStudio/_files/secubox-openwrt +./secubox-tools/deploy-website.sh root@192.168.8.191 +``` + +## Monitoring + +### Check Deployment Status + +```bash +# Verify files +ssh root@192.168.8.191 "find /www/luci-static/secubox -type f | wc -l" + +# Check disk usage +ssh root@192.168.8.191 "du -sh /www/luci-static/secubox" + +# View access logs (if logging enabled) +ssh root@192.168.8.191 "logread | grep uhttpd" +``` + +## Related Documentation + +- **Help Integration:** `HELP_INTEGRATION_PLAN.md` +- **Module Development:** `LUCI_DEVELOPMENT_REFERENCE.md` +- **Deployment Scripts:** `secubox-tools/deploy-*.sh` + +## Support + +For issues or questions: +1. Check troubleshooting section above +2. Review router logs: `ssh root@router "logread"` +3. Test network connectivity +4. Verify file permissions + +## Changelog + +### v1.0 (2025-12-28) +- Initial deployment script +- Documentation created +- Tested on router 192.168.8.191 +- Supports automatic website directory detection diff --git a/EXAMPLES/README.md b/EXAMPLES/README.md new file mode 100644 index 00000000..bf56e47d --- /dev/null +++ b/EXAMPLES/README.md @@ -0,0 +1,140 @@ +# SecuBox Code Examples + +This directory contains practical code examples for SecuBox module development and integration. + +## Available Examples + +### help-button-integration.js +Comprehensive examples for integrating help/documentation buttons into SecuBox modules. + +**What's Included:** +- Shared help utility module +- Module integration examples +- Multiple UI patterns (header, floating, quick actions) +- Context-sensitive help +- CSS styling examples + +**Use Cases:** +- Adding help buttons to module dashboards +- Linking to website documentation +- Creating consistent help UX across modules + +## Related Documentation + +- **Integration Plan:** `../DOCS/HELP_INTEGRATION_PLAN.md` +- **Deployment Guide:** `../DOCS/WEBSITE_DEPLOYMENT_GUIDE.md` +- **LuCI Development:** `../DOCS/LUCI_DEVELOPMENT_REFERENCE.md` + +## How to Use Examples + +1. **Review the example code** to understand the pattern +2. **Copy relevant sections** to your module +3. **Customize** module names, URLs, and styling +4. **Test** on development router +5. **Deploy** using deployment scripts + +## Integration Workflow + +```bash +# 1. Deploy website to router +./secubox-tools/deploy-website.sh root@192.168.8.191 + +# 2. Add help button code to your module +# (see help-button-integration.js) + +# 3. Build and deploy module +./secubox-tools/local-build.sh build luci-app-your-module +./secubox-tools/deploy-network-modes.sh root@192.168.8.191 + +# 4. Test in browser +open http://192.168.8.191/cgi-bin/luci/admin/secubox/your-module +``` + +## Common Patterns + +### Pattern 1: Header Help Button +```javascript +'require secubox/help as Help'; + +E('div', { 'class': 'header' }, [ + E('h2', {}, 'Module Title'), + Help.createHelpButton('module-name', 'header') +]) +``` + +### Pattern 2: Floating Help Button +```javascript +E('a', { + 'class': 'sb-help-floating', + 'href': '/luci-static/secubox/demo-module.html', + 'target': '_blank' +}, [E('span', {}, '❓')]) +``` + +### Pattern 3: Quick Action +```javascript +buttons.push( + E('button', { + 'class': 'action-btn', + 'click': function() { + window.open('/luci-static/secubox/demo-module.html', '_blank'); + } + }, ['πŸ“– Help']) +) +``` + +## Module-Specific Examples + +Each module can have different help button placements: + +| Module | Recommended Position | Example File | +|--------|---------------------|--------------| +| SecuBox Dashboard | Quick Actions | help-button-integration.js (Ex 3) | +| System Hub | Header Badge | help-button-integration.js (Ex 4) | +| Network Modes | Header Button | help-button-integration.js (Ex 2) | +| Other Modules | Floating Button | help-button-integration.js (Ex 5) | + +## Testing Checklist + +- [ ] Help button is visible +- [ ] Clicking opens correct documentation page +- [ ] Styling matches module theme +- [ ] Works in dark/light mode +- [ ] Responsive on mobile +- [ ] No console errors +- [ ] Accessible via keyboard + +## Contributing Examples + +To add new examples: + +1. Create descriptive JavaScript file +2. Include clear comments +3. Show complete, working code +4. Update this README +5. Test on actual router + +## Support + +For questions about examples: +- Review related documentation in `DOCS/` +- Check module source code in `luci-app-*/` +- Test on development router first + +## Quick Reference + +**Website Base URL:** `/luci-static/secubox/` + +**Module Help Pages:** +- secubox β†’ `index.html#modules` +- system-hub β†’ `demo-secubox-hub.html` +- network-modes β†’ `demo-network-modes.html` +- client-guardian β†’ `demo-client-guardian.html` +- bandwidth-manager β†’ `demo-bandwidth.html` +- traffic-shaper β†’ `demo-traffic-shaper.html` +- (See help-button-integration.js for complete list) + +**Help Utility Methods:** +- `Help.createHelpButton(module, position, options)` +- `Help.getHelpUrl(module)` +- `Help.openHelpModal(module)` diff --git a/EXAMPLES/help-button-integration.js b/EXAMPLES/help-button-integration.js new file mode 100644 index 00000000..335f0d44 --- /dev/null +++ b/EXAMPLES/help-button-integration.js @@ -0,0 +1,356 @@ +/** + * SecuBox Help Button Integration Example + * + * This file demonstrates how to integrate help buttons into SecuBox modules + * to link with the deployed website documentation. + * + * Version: 1.0 + * Date: 2025-12-28 + */ + +// ============================================================================ +// EXAMPLE 1: Shared Help Utility (Recommended) +// ============================================================================ + +// File: luci-app-secubox/htdocs/luci-static/resources/secubox/help.js + +'use strict'; +'require baseclass'; + +return baseclass.extend({ + /** + * Create a help button element + * @param {string} moduleName - Module identifier (e.g., 'network-modes') + * @param {string} position - Button position: 'header', 'footer', 'floating' + * @param {object} options - Custom options + */ + createHelpButton: function(moduleName, position, options) { + var opts = options || {}; + var helpUrl = this.getHelpUrl(moduleName); + var buttonClass = 'sb-help-btn sb-help-' + position; + + return E('a', { + 'class': buttonClass, + 'href': helpUrl, + 'target': opts.target || '_blank', + 'title': opts.title || _('View Help & Documentation'), + 'style': opts.style || '' + }, [ + E('span', { 'class': 'sb-help-icon' }, opts.icon || '❓'), + opts.showLabel !== false ? E('span', { 'class': 'sb-help-label' }, opts.label || _('Help')) : null + ]); + }, + + /** + * Get help URL for a module + * @param {string} moduleName - Module identifier + */ + getHelpUrl: function(moduleName) { + var baseUrl = '/luci-static/secubox/'; + var moduleMap = { + 'secubox': 'index.html#modules', + 'system-hub': 'demo-secubox-hub.html', + 'network-modes': 'demo-network-modes.html', + 'client-guardian': 'demo-client-guardian.html', + 'bandwidth-manager': 'demo-bandwidth.html', + 'cdn-cache': 'demo-cdn-cache.html', + 'traffic-shaper': 'demo-traffic-shaper.html', + 'wireguard-dashboard': 'demo-wireguard.html', + 'crowdsec-dashboard': 'demo-crowdsec.html', + 'netdata-dashboard': 'demo-netdata.html', + 'netifyd-dashboard': 'demo-netifyd.html', + 'auth-guardian': 'demo-auth.html', + 'vhost-manager': 'demo-vhost.html', + 'ksm-manager': 'demo-ksm-manager.html', + 'media-flow': 'demo-media.html' + }; + + return baseUrl + (moduleMap[moduleName] || 'index.html'); + }, + + /** + * Open help in modal (for inline help) + * @param {string} moduleName - Module identifier + */ + openHelpModal: function(moduleName) { + var helpUrl = this.getHelpUrl(moduleName); + var iframe = E('iframe', { + 'src': helpUrl, + 'style': 'width: 100%; height: 70vh; border: none; border-radius: 8px;' + }); + + ui.showModal(_('Help & Documentation'), [ + E('div', { 'style': 'min-height: 70vh;' }, [iframe]), + E('div', { 'class': 'right', 'style': 'margin-top: 1rem;' }, [ + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ]); + } +}); + +// ============================================================================ +// EXAMPLE 2: Module Integration (Network Modes) +// ============================================================================ + +// File: luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js + +'use strict'; +'require view'; +'require dom'; +'require ui'; +'require network-modes.api as api'; +'require secubox/help as Help'; // ← ADD THIS LINE + +return view.extend({ + title: _('Network Modes'), + + load: function() { + return api.getAllData(); + }, + + render: function(data) { + var self = this; + var status = data.status || {}; + var currentMode = status.current_mode || 'router'; + + var view = E('div', { 'class': 'network-modes-dashboard' }, [ + // Load help CSS + E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/help.css') }), + + // Header with help button + E('div', { 'class': 'nm-header' }, [ + E('div', { 'class': 'nm-logo' }, [ + E('div', { 'class': 'nm-logo-icon' }, '🌐'), + E('div', { 'class': 'nm-logo-text' }, ['Network ', E('span', {}, 'Configuration')]) + ]), + E('div', { 'class': 'nm-mode-badge ' + currentMode }, [ + E('span', { 'class': 'nm-mode-dot' }), + currentMode + ]), + // ← ADD HELP BUTTON HERE + Help.createHelpButton('network-modes', 'header', { + icon: 'πŸ“–', + label: _('Help') + }) + ]), + + // Rest of the dashboard... + ]); + + return view; + } +}); + +// ============================================================================ +// EXAMPLE 3: SecuBox Dashboard Integration (Quick Actions) +// ============================================================================ + +// File: luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js +// Add to renderQuickActions method + +renderQuickActions: function() { + var self = this; + var actions = [ + { name: 'restart_rpcd', label: 'RPCD', icon: 'πŸ”„', color: '#6366f1' }, + { name: 'restart_uhttpd', label: 'Web Server', icon: '🌐', color: '#00ab44' }, + { name: 'restart_network', label: 'Network', icon: 'πŸ“‘', color: '#06b6d4' }, + { name: 'restart_firewall', label: 'Firewall', icon: 'πŸ›‘οΈ', color: '#ef4444' }, + { name: 'clear_cache', label: 'Clear Cache', icon: '🧹', color: '#f59e0b' }, + { name: 'backup_config', label: 'Backup', icon: 'πŸ’Ύ', color: '#8b5cf6' } + ]; + + var buttons = actions.map(function(action) { + return E('button', { + 'class': 'secubox-action-btn', + 'style': 'border-color: ' + action.color, + 'click': function() { + self.executeQuickAction(action.name, action.label); + } + }, [ + E('span', { 'class': 'secubox-action-icon' }, action.icon), + E('span', { 'class': 'secubox-action-label' }, action.label) + ]); + }); + + // ← ADD HELP BUTTON TO QUICK ACTIONS + buttons.push( + E('button', { + 'class': 'secubox-action-btn', + 'style': 'border-color: #667eea', + 'click': function() { + window.open('/luci-static/secubox/index.html#modules', '_blank'); + } + }, [ + E('span', { 'class': 'secubox-action-icon' }, 'πŸ“–'), + E('span', { 'class': 'secubox-action-label' }, _('Help')) + ]) + ); + + return E('div', { 'class': 'secubox-card' }, [ + E('h3', { 'class': 'secubox-card-title' }, '⚑ Quick Actions'), + E('div', { 'class': 'secubox-actions-grid' }, buttons) + ]); +}, + +// ============================================================================ +// EXAMPLE 4: System Hub Integration (Header Badge Style) +// ============================================================================ + +// File: luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/overview.js +// Modify renderHeader method + +renderHeader: function() { + var score = this.healthData.score || 0; + var scoreClass = score >= 80 ? 'excellent' : (score >= 60 ? 'good' : 'warning'); + var scoreLabel = score >= 80 ? 'Excellent' : (score >= 60 ? 'Good' : 'Warning'); + + return E('div', { 'class': 'sh-dashboard-header' }, [ + E('div', { 'class': 'sh-dashboard-header-content' }, [ + E('div', {}, [ + E('h2', {}, 'βš™οΈ System Control Center'), + E('p', { 'class': 'sh-dashboard-subtitle' }, 'System Monitoring & Management Center') + ]), + E('div', { 'class': 'sh-dashboard-header-info' }, [ + E('div', { 'class': 'sh-header-badge-group' }, [ + E('span', { 'class': 'sh-dashboard-badge sh-dashboard-badge-version' }, + 'v0.3.6'), + E('span', { 'class': 'sh-dashboard-badge' }, + '⏱️ ' + (this.sysInfo.uptime_formatted || '0d 0h 0m')), + E('span', { 'class': 'sh-dashboard-badge' }, + 'πŸ–₯️ ' + (this.sysInfo.hostname || 'OpenWrt')), + // ← ADD HELP BADGE + E('a', { + 'class': 'sh-dashboard-badge sh-help-badge', + 'href': '/luci-static/secubox/demo-secubox-hub.html', + 'target': '_blank', + 'title': _('View Help') + }, 'πŸ“– Help') + ]), + this.renderHealthGauge(score, scoreClass, scoreLabel) + ]) + ]) + ]); +}, + +// ============================================================================ +// EXAMPLE 5: Floating Help Button (Global) +// ============================================================================ + +// Add to any module's render method for a floating help button + +render: function(data) { + var container = E('div', { 'class': 'module-dashboard' }, [ + // ... module content ... + + // ← ADD FLOATING HELP BUTTON + E('a', { + 'class': 'sb-help-floating', + 'href': '/luci-static/secubox/demo-module.html', + 'target': '_blank', + 'title': _('Help & Documentation') + }, [ + E('span', { 'class': 'sb-help-icon' }, '❓') + ]) + ]); + + return container; +} + +// ============================================================================ +// EXAMPLE 6: Inline Modal Help +// ============================================================================ + +// Use Help.openHelpModal() for inline help + +E('button', { + 'class': 'btn cbi-button-action', + 'click': function() { + Help.openHelpModal('network-modes'); + } +}, [ + E('span', {}, '❓ '), + _('Help') +]) + +// ============================================================================ +// EXAMPLE 7: Context-Sensitive Help +// ============================================================================ + +// Different help URLs based on context + +getContextualHelpUrl: function(context) { + var baseUrl = '/luci-static/secubox/demo-network-modes.html'; + var anchors = { + 'sniffer': '#sniffer-mode', + 'accesspoint': '#access-point-mode', + 'relay': '#relay-mode', + 'router': '#router-mode' + }; + + return baseUrl + (anchors[context] || ''); +} + +// Then use it: +E('a', { + 'href': this.getContextualHelpUrl('sniffer'), + 'target': '_blank' +}, _('Learn about Sniffer Mode')) + +// ============================================================================ +// CSS INTEGRATION EXAMPLE +// ============================================================================ + +/* +File: luci-app-secubox/htdocs/luci-static/resources/secubox/help.css + +Add to existing module CSS for consistent styling: +*/ + +/* Help Button Base */ +.sb-help-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border-radius: 8px; + text-decoration: none; + font-weight: 500; + transition: all 0.3s ease; + border: 2px solid transparent; + cursor: pointer; +} + +.sb-help-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); +} + +/* Floating position */ +.sb-help-floating { + position: fixed; + bottom: 2rem; + right: 2rem; + z-index: 1000; + width: 60px; + height: 60px; + border-radius: 50%; + padding: 0; + justify-content: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +/* System Hub badge style */ +.sh-help-badge { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + transition: all 0.3s ease; +} + +.sh-help-badge:hover { + transform: scale(1.05); + box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4); +} diff --git a/luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js b/luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js index 6017f73d..d2becb1a 100644 --- a/luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js +++ b/luci-app-network-modes/htdocs/luci-static/resources/view/network-modes/overview.js @@ -3,6 +3,7 @@ 'require dom'; 'require ui'; 'require network-modes.api as api'; +'require secubox/help as Help'; return view.extend({ title: _('Network Modes'), @@ -62,6 +63,9 @@ return view.extend({ var currentModeInfo = modeInfos[currentMode]; var view = E('div', { 'class': 'network-modes-dashboard' }, [ + // Load help CSS + E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/help.css') }), + // Header E('div', { 'class': 'nm-header' }, [ E('div', { 'class': 'nm-logo' }, [ @@ -71,7 +75,11 @@ return view.extend({ E('div', { 'class': 'nm-mode-badge ' + currentMode }, [ E('span', { 'class': 'nm-mode-dot' }), currentModeInfo ? currentModeInfo.name : currentMode - ]) + ]), + Help.createHelpButton('network-modes', 'header', { + icon: 'πŸ“–', + label: _('Help') + }) ]), // Current Mode Display Card diff --git a/luci-app-network-modes/root/usr/libexec/rpcd/luci.network-modes b/luci-app-network-modes/root/usr/libexec/rpcd/luci.network-modes index 0057dc12..5dfa19c1 100755 --- a/luci-app-network-modes/root/usr/libexec/rpcd/luci.network-modes +++ b/luci-app-network-modes/root/usr/libexec/rpcd/luci.network-modes @@ -448,8 +448,8 @@ apply_mode() { apply_accesspoint_features ;; - relay) - # Repeater mode: STA + AP relay + relay) + # Repeater mode: STA + AP relay # Client interface (sta) uci set network.wwan=interface uci set network.wwan.proto='dhcp' @@ -465,12 +465,41 @@ apply_mode() { uci set network.stabridge.proto='relay' uci set network.stabridge.network='lan wwan' - apply_wireguard_config - apply_mtu_clamping - enable_tcp_bbr - ;; + apply_wireguard_config + apply_mtu_clamping + enable_tcp_bbr + ;; - bridge) + sniffer) + local ports=$(uci -q get network-modes.sniffer.bridge_ports || echo "eth0 eth1") + local bridge_iface=$(uci -q get network-modes.sniffer.bridge_interface || echo "br-lan") + local promisc=$(uci -q get network-modes.sniffer.promiscuous || echo 1) + + uci delete network.wan 2>/dev/null + uci set network.lan=interface + uci set network.lan.proto='none' + uci set network.lan.type='bridge' + uci set network.lan.ifname="$ports" + uci set network.lan.delegate='0' + uci set network.lan.device="$bridge_iface" + + uci set dhcp.lan=dhcp + uci set dhcp.lan.interface='lan' + uci set dhcp.lan.ignore='1' + + uci set firewall.@zone[0].input='ACCEPT' + uci set firewall.@zone[0].output='ACCEPT' + uci set firewall.@zone[0].forward='ACCEPT' + uci delete firewall.@zone[1] 2>/dev/null + + if [ "$promisc" = "1" ]; then + for port in $ports; do + ip link set "$port" promisc on 2>/dev/null || true + done + fi + ;; + + bridge) # Pure L2 bridge: all interfaces bridged, DHCP client uci delete network.wan 2>/dev/null diff --git a/luci-app-network-modes/root/usr/share/luci/menu.d/luci-app-network-modes.json b/luci-app-network-modes/root/usr/share/luci/menu.d/luci-app-network-modes.json index 17483871..65f8cce7 100644 --- a/luci-app-network-modes/root/usr/share/luci/menu.d/luci-app-network-modes.json +++ b/luci-app-network-modes/root/usr/share/luci/menu.d/luci-app-network-modes.json @@ -1,5 +1,5 @@ { - "admin/secubox/network/network-modes": { + "admin/secubox/network-modes": { "title": "Network Modes", "order": 20, "action": { @@ -9,7 +9,7 @@ "acl": ["luci-app-network-modes"] } }, - "admin/secubox/network/network-modes/overview": { + "admin/secubox/network-modes/overview": { "title": "Overview", "order": 10, "action": { @@ -17,7 +17,7 @@ "path": "network-modes/overview" } }, - "admin/secubox/network/network-modes/wizard": { + "admin/secubox/network-modes/wizard": { "title": "Mode Wizard", "order": 20, "action": { @@ -25,7 +25,7 @@ "path": "network-modes/wizard" } }, - "admin/secubox/network/network-modes/router": { + "admin/secubox/network-modes/router": { "title": "Router Mode", "order": 30, "action": { @@ -33,7 +33,7 @@ "path": "network-modes/router" } }, - "admin/secubox/network/network-modes/accesspoint": { + "admin/secubox/network-modes/accesspoint": { "title": "Access Point Mode", "order": 40, "action": { @@ -41,7 +41,7 @@ "path": "network-modes/accesspoint" } }, - "admin/secubox/network/network-modes/relay": { + "admin/secubox/network-modes/relay": { "title": "Relay Mode", "order": 50, "action": { @@ -49,7 +49,7 @@ "path": "network-modes/relay" } }, - "admin/secubox/network/network-modes/sniffer": { + "admin/secubox/network-modes/sniffer": { "title": "Sniffer Mode", "order": 60, "action": { @@ -57,7 +57,7 @@ "path": "network-modes/sniffer" } }, - "admin/secubox/network/network-modes/settings": { + "admin/secubox/network-modes/settings": { "title": "Settings", "order": 90, "action": { diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/dashboard.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/dashboard.css index 9db6bb00..5bcf59cd 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/dashboard.css +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/dashboard.css @@ -244,6 +244,18 @@ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3); } +.secubox-tab-bonus { + background: linear-gradient(135deg, #f97316 0%, #ec4899 100%); + border: none; + color: white; + box-shadow: 0 10px 24px rgba(236, 72, 153, 0.35); +} + +.secubox-tab-bonus:hover { + background: linear-gradient(135deg, #fb923c 0%, #f472b6 100%); + box-shadow: 0 12px 28px rgba(236, 72, 153, 0.4); +} + .secubox-tab-icon { font-size: 16px; line-height: 1; diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/help.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/help.css new file mode 100644 index 00000000..afee9b82 --- /dev/null +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/help.css @@ -0,0 +1,322 @@ +/** + * SecuBox Help System Styles + * Version: 1.0.0 + */ + +/* ============================================================================ + Base Help Button Styles + ============================================================================ */ + +.sb-help-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white !important; + border-radius: 8px; + text-decoration: none; + font-weight: 500; + font-size: 0.9rem; + transition: all 0.3s ease; + border: 2px solid transparent; + cursor: pointer; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.sb-help-btn:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); + border-color: rgba(255, 255, 255, 0.3); + color: white !important; + text-decoration: none; +} + +.sb-help-btn:active { + transform: translateY(0); + box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3); +} + +.sb-help-icon { + font-size: 1.2em; + line-height: 1; + display: inline-flex; + align-items: center; +} + +.sb-help-label { + white-space: nowrap; +} + +/* ============================================================================ + Position Variants + ============================================================================ */ + +/* Header Position - Compact style for headers */ +.sb-help-header { + margin-left: auto; + padding: 0.4rem 0.8rem; + font-size: 0.85em; + align-self: center; +} + +/* Footer Position - Full width on mobile */ +.sb-help-footer { + margin-top: 2rem; + width: 100%; + justify-content: center; +} + +@media (min-width: 768px) { + .sb-help-footer { + width: auto; + } +} + +/* Badge Style - Minimal, badge-like appearance */ +.sb-help-badge { + padding: 0.3rem 0.6rem; + font-size: 0.8rem; + border-radius: 4px; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white !important; + text-decoration: none; + transition: all 0.3s ease; + display: inline-flex; + align-items: center; + gap: 0.3rem; +} + +.sb-help-badge:hover { + transform: scale(1.05); + box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4); + color: white !important; +} + +/* Floating Button - Fixed position, circular */ +.sb-help-floating { + position: fixed; + bottom: 2rem; + right: 2rem; + z-index: 1000; + border-radius: 50%; + width: 60px; + height: 60px; + padding: 0; + justify-content: center; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); +} + +.sb-help-floating .sb-help-label { + display: none; +} + +.sb-help-floating .sb-help-icon { + font-size: 1.8em; +} + +.sb-help-floating:hover { + transform: scale(1.1); + box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5); +} + +/* Hide floating button on small screens to avoid overlap */ +@media (max-width: 768px) { + .sb-help-floating { + bottom: 1rem; + right: 1rem; + width: 50px; + height: 50px; + } + + .sb-help-floating .sb-help-icon { + font-size: 1.5em; + } +} + +/* ============================================================================ + Tooltip Styles + ============================================================================ */ + +.sb-help-tooltip { + display: inline-flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border-radius: 50%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + font-size: 12px; + cursor: help; + margin-left: 0.3rem; + transition: all 0.2s ease; +} + +.sb-help-tooltip:hover { + transform: scale(1.2); + box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4); +} + +/* ============================================================================ + Dark Theme Support + ============================================================================ */ + +[data-theme="dark"] .sb-help-btn { + background: linear-gradient(135deg, #4c51bf 0%, #553c9a 100%); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +[data-theme="dark"] .sb-help-btn:hover { + box-shadow: 0 4px 12px rgba(76, 81, 191, 0.5); + border-color: rgba(255, 255, 255, 0.2); +} + +[data-theme="dark"] .sb-help-badge { + background: linear-gradient(135deg, #4c51bf 0%, #553c9a 100%); +} + +[data-theme="dark"] .sb-help-tooltip { + background: linear-gradient(135deg, #4c51bf 0%, #553c9a 100%); +} + +/* ============================================================================ + Button States + ============================================================================ */ + +.sb-help-btn:disabled, +.sb-help-btn.disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; +} + +.sb-help-btn:focus { + outline: 2px solid #667eea; + outline-offset: 2px; +} + +/* ============================================================================ + Loading State + ============================================================================ */ + +.sb-help-btn.loading { + position: relative; + color: transparent !important; +} + +.sb-help-btn.loading::after { + content: ''; + position: absolute; + width: 16px; + height: 16px; + top: 50%; + left: 50%; + margin-left: -8px; + margin-top: -8px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-radius: 50%; + border-top-color: white; + animation: sb-help-spin 0.6s linear infinite; +} + +@keyframes sb-help-spin { + to { transform: rotate(360deg); } +} + +/* ============================================================================ + Integration with Existing Modules + ============================================================================ */ + +/* SecuBox Dashboard */ +.secubox-actions-grid .sb-help-btn { + width: 100%; + justify-content: center; +} + +/* System Hub */ +.sh-dashboard-header .sb-help-badge { + margin-left: 0.5rem; +} + +/* Network Modes */ +.nm-header .sb-help-btn { + margin-left: auto; +} + +/* ============================================================================ + Accessibility + ============================================================================ */ + +/* High contrast mode support */ +@media (prefers-contrast: high) { + .sb-help-btn { + border: 2px solid currentColor; + } +} + +/* Reduced motion support */ +@media (prefers-reduced-motion: reduce) { + .sb-help-btn, + .sb-help-tooltip, + .sb-help-floating { + transition: none; + } + + .sb-help-btn:hover, + .sb-help-floating:hover { + transform: none; + } + + .sb-help-btn.loading::after { + animation: none; + border-top-color: transparent; + } +} + +/* Focus visible for keyboard navigation */ +.sb-help-btn:focus-visible { + outline: 3px solid #667eea; + outline-offset: 3px; +} + +/* ============================================================================ + Print Styles + ============================================================================ */ + +@media print { + .sb-help-btn, + .sb-help-floating, + .sb-help-tooltip { + display: none !important; + } +} + +/* ============================================================================ + Responsive Adjustments + ============================================================================ */ + +@media (max-width: 480px) { + .sb-help-btn { + font-size: 0.85rem; + padding: 0.4rem 0.7rem; + } + + .sb-help-header { + padding: 0.3rem 0.6rem; + } + + /* Stack label vertically on very small screens if needed */ + .sb-help-btn.sb-help-stacked { + flex-direction: column; + gap: 0.2rem; + } + + .sb-help-btn.sb-help-stacked .sb-help-icon { + font-size: 1.4em; + } + + .sb-help-btn.sb-help-stacked .sb-help-label { + font-size: 0.75rem; + } +} diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/help.js b/luci-app-secubox/htdocs/luci-static/resources/secubox/help.js new file mode 100644 index 00000000..746f332a --- /dev/null +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/help.js @@ -0,0 +1,183 @@ +'use strict'; +'require baseclass'; +'require ui'; + +/** + * SecuBox Help System + * Provides centralized help/documentation access for all SecuBox modules + * Version: 1.0.0 + */ + +console.log('πŸ“– SecuBox Help System v1.0.0 loaded'); + +return baseclass.extend({ + /** + * Create a help button element + * @param {string} moduleName - Module identifier (e.g., 'network-modes') + * @param {string} position - Button position: 'header', 'footer', 'floating', 'badge' + * @param {object} options - Custom options + * @returns {Element} Help button element + */ + createHelpButton: function(moduleName, position, options) { + var opts = options || {}; + var helpUrl = this.getHelpUrl(moduleName); + var buttonClass = 'sb-help-btn sb-help-' + position; + var target = opts.target || '_blank'; + + // Handle modal vs new tab + if (opts.modal) { + var self = this; + return E('button', { + 'class': buttonClass, + 'title': opts.title || _('View Help & Documentation'), + 'style': opts.style || '', + 'click': function(ev) { + ev.preventDefault(); + self.openHelpModal(moduleName); + } + }, [ + E('span', { 'class': 'sb-help-icon' }, opts.icon || '❓'), + opts.showLabel !== false ? E('span', { 'class': 'sb-help-label' }, opts.label || _('Help')) : null + ]); + } + + // Regular link button + return E('a', { + 'class': buttonClass, + 'href': helpUrl, + 'target': target, + 'title': opts.title || _('View Help & Documentation'), + 'style': opts.style || '' + }, [ + E('span', { 'class': 'sb-help-icon' }, opts.icon || '❓'), + opts.showLabel !== false ? E('span', { 'class': 'sb-help-label' }, opts.label || _('Help')) : null + ]); + }, + + /** + * Get help URL for a module + * @param {string} moduleName - Module identifier + * @param {string} anchor - Optional anchor/section (e.g., '#features') + * @returns {string} Help page URL + */ + getHelpUrl: function(moduleName, anchor) { + var baseUrl = '/luci-static/secubox/'; + var moduleMap = { + 'secubox': 'index.html#modules', + 'system-hub': 'demo-secubox-hub.html', + 'network-modes': 'demo-network-modes.html', + 'client-guardian': 'demo-client-guardian.html', + 'bandwidth-manager': 'demo-bandwidth.html', + 'cdn-cache': 'demo-cdn-cache.html', + 'traffic-shaper': 'demo-traffic-shaper.html', + 'wireguard-dashboard': 'demo-wireguard.html', + 'crowdsec-dashboard': 'demo-crowdsec.html', + 'netdata-dashboard': 'demo-netdata.html', + 'netifyd-dashboard': 'demo-netifyd.html', + 'auth-guardian': 'demo-auth.html', + 'vhost-manager': 'demo-vhost.html', + 'ksm-manager': 'demo-ksm-manager.html', + 'media-flow': 'demo-media.html' + }; + + var url = baseUrl + (moduleMap[moduleName] || 'index.html'); + return anchor ? url + anchor : url; + }, + + /** + * Open help in modal dialog with iframe + * @param {string} moduleName - Module identifier + * @param {object} options - Modal options + */ + openHelpModal: function(moduleName, options) { + var opts = options || {}; + var helpUrl = this.getHelpUrl(moduleName); + var modalTitle = opts.title || _('Help & Documentation'); + + var iframe = E('iframe', { + 'src': helpUrl, + 'style': 'width: 100%; height: 70vh; border: none; border-radius: 8px; background: white;', + 'frameborder': '0' + }); + + var modal = E('div', { 'style': 'min-height: 70vh;' }, [ + iframe, + E('div', { + 'class': 'right', + 'style': 'margin-top: 1rem; display: flex; gap: 0.5rem; justify-content: flex-end;' + }, [ + opts.showOpenButton !== false ? E('a', { + 'class': 'btn cbi-button-neutral', + 'href': helpUrl, + 'target': '_blank' + }, [ + 'πŸ”— ', + _('Open in New Tab') + ]) : null, + E('button', { + 'class': 'btn cbi-button-action', + 'click': ui.hideModal + }, _('Close')) + ]) + ]); + + ui.showModal(modalTitle, [modal]); + }, + + /** + * Create a quick help tooltip + * @param {string} text - Tooltip text + * @param {string} moduleName - Optional module for "Learn More" link + * @returns {Element} Tooltip element + */ + createTooltip: function(text, moduleName) { + var tooltip = E('span', { + 'class': 'sb-help-tooltip', + 'title': text + }, '❓'); + + if (moduleName) { + var self = this; + tooltip.addEventListener('click', function(ev) { + ev.preventDefault(); + window.open(self.getHelpUrl(moduleName), '_blank'); + }); + } + + return tooltip; + }, + + /** + * Check if help page exists (basic check) + * @param {string} moduleName - Module identifier + * @returns {boolean} True if help page is configured + */ + hasHelpPage: function(moduleName) { + var url = this.getHelpUrl(moduleName); + return url.indexOf('demo-') !== -1 || moduleName === 'secubox'; + }, + + /** + * Get all available help pages + * @returns {object} Map of module names to help URLs + */ + getAllHelpPages: function() { + return { + 'secubox': this.getHelpUrl('secubox'), + 'system-hub': this.getHelpUrl('system-hub'), + 'network-modes': this.getHelpUrl('network-modes'), + 'client-guardian': this.getHelpUrl('client-guardian'), + 'bandwidth-manager': this.getHelpUrl('bandwidth-manager'), + 'cdn-cache': this.getHelpUrl('cdn-cache'), + 'traffic-shaper': this.getHelpUrl('traffic-shaper'), + 'wireguard-dashboard': this.getHelpUrl('wireguard-dashboard'), + 'crowdsec-dashboard': this.getHelpUrl('crowdsec-dashboard'), + 'netdata-dashboard': this.getHelpUrl('netdata-dashboard'), + 'netifyd-dashboard': this.getHelpUrl('netifyd-dashboard'), + 'auth-guardian': this.getHelpUrl('auth-guardian'), + 'vhost-manager': this.getHelpUrl('vhost-manager'), + 'ksm-manager': this.getHelpUrl('ksm-manager'), + 'media-flow': this.getHelpUrl('media-flow') + }; + } +}); diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css index c61d87a9..0cbd1ec4 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/modules.css @@ -92,6 +92,18 @@ color: white; } +.secubox-filter-tab-bonus { + background: linear-gradient(135deg, #f97316 0%, #ec4899 100%); + border-color: transparent; + color: white; + box-shadow: 0 8px 20px rgba(249, 115, 22, 0.35); +} + +.secubox-filter-tab-bonus:hover { + transform: translateY(-2px); + box-shadow: 0 10px 24px rgba(236, 72, 153, 0.35); +} + /* Modules Grid */ .secubox-modules-grid { display: grid; diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/secubox.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/secubox.css index ad9e786b..1796db21 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/secubox.css +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/secubox.css @@ -345,6 +345,228 @@ font-style: italic; } +/* SecuBox Help Bonus Page */ +.secubox-help-page { + display: flex; + flex-direction: column; + gap: 20px; +} + +.secubox-help-hero { + display: flex; + gap: 32px; + align-items: center; + background: linear-gradient(135deg, #312e81 0%, #0f172a 60%, #1e293b 100%); + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: 0 20px 60px rgba(15, 23, 42, 0.45); + color: #eef2ff; +} + +.secubox-help-hero-text { + flex: 1; +} + +.secubox-help-eyebrow { + display: inline-flex; + align-items: center; + gap: 6px; + text-transform: uppercase; + letter-spacing: 0.2em; + font-size: 11px; + font-weight: 600; + color: rgba(255, 255, 255, 0.6); +} + +.secubox-help-subtitle { + color: rgba(255, 255, 255, 0.9); + font-size: 15px; + margin: 12px 0 0 0; +} + +.secubox-help-hero-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); + gap: 16px; + margin-top: 20px; +} + +.secubox-help-hero-stat { + background: rgba(15, 23, 42, 0.55); + border-radius: 10px; + padding: 14px 16px; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.secubox-help-hero-stat-icon { + font-size: 22px; + margin-bottom: 6px; +} + +.secubox-help-hero-stat-value { + display: block; + font-size: 20px; + font-weight: 700; +} + +.secubox-help-hero-stat-label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.04em; + color: rgba(255, 255, 255, 0.7); +} + +.secubox-help-hero-actions { + display: flex; + flex-direction: column; + gap: 12px; + min-width: 230px; +} + +.secubox-help-cta { + background: linear-gradient(135deg, #22c55e 0%, #15803d 100%) !important; + box-shadow: 0 10px 30px rgba(21, 128, 61, 0.45); +} + +.secubox-card-title-row { + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; +} + +.secubox-card-hint { + font-size: 13px; + color: var(--sb-text-muted); +} + +.secubox-help-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 16px; + margin-top: 16px; +} + +.secubox-help-card { + background: var(--sb-bg-card); + border: 1px solid var(--sb-border); + border-radius: 12px; + padding: 18px; + display: flex; + flex-direction: row; + gap: 16px; + align-items: center; + text-decoration: none; + color: inherit; + transition: all 0.2s ease; +} + +.secubox-help-card-body { + flex: 1; +} + +.secubox-help-card:hover { + border-color: var(--sb-primary); + transform: translateY(-2px); + box-shadow: 0 12px 24px var(--sb-hover-shadow); +} + +.secubox-help-card-icon { + font-size: 28px; + width: 48px; + height: 48px; + border-radius: 10px; + background: rgba(99, 102, 241, 0.12); + display: flex; + align-items: center; + justify-content: center; +} + +.secubox-help-card-title { + margin: 0; + font-size: 16px; + font-weight: 600; + color: var(--sb-text); +} + +.secubox-help-card-text { + margin: 4px 0 8px 0; + font-size: 13px; + color: var(--sb-text-muted); +} + +.secubox-help-card-link { + font-size: 12px; + font-weight: 600; + color: var(--sb-primary); + text-transform: uppercase; + letter-spacing: 0.08em; +} + +.secubox-help-support-grid { + margin-top: 16px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 16px; +} + +.secubox-help-support-item { + border: 1px dashed var(--sb-border); + border-radius: 10px; + padding: 16px; + background: rgba(99, 102, 241, 0.04); +} + +.secubox-help-support-icon { + font-size: 24px; + margin-bottom: 8px; +} + +.secubox-help-support-title { + font-weight: 600; + margin-bottom: 6px; + color: var(--sb-text); +} + +.secubox-help-support-text { + margin: 0; + font-size: 13px; + color: var(--sb-text-muted); + line-height: 1.5; +} + +.secubox-help-support-actions { + margin-top: 20px; + display: flex; + flex-wrap: wrap; + gap: 12px; +} + +.secubox-help-footer { + background: var(--sb-bg-card); + border: 1px solid var(--sb-border); + border-radius: 14px; + padding: 20px; + text-align: center; +} + +.secubox-help-footer-text { + font-size: 14px; + color: var(--sb-text-muted); + margin-bottom: 10px; +} + +.secubox-help-footer-links { + display: inline-flex; + justify-content: center; + gap: 8px; + color: var(--sb-primary); + font-weight: 600; +} + +.secubox-help-footer-links .sep { + color: var(--sb-text-muted); +} + /* Responsive Design */ @media (max-width: 768px) { .secubox-health-grid { @@ -358,4 +580,24 @@ .secubox-modules-grid { grid-template-columns: 1fr; } + + .secubox-help-hero { + flex-direction: column; + text-align: center; + } + + .secubox-help-hero-actions { + width: 100%; + flex-direction: row; + justify-content: center; + } + + .secubox-help-card { + flex-direction: column; + text-align: center; + } + + .secubox-help-support-actions { + justify-content: center; + } } diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js index 51346e39..1bfba063 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/dashboard.js @@ -239,20 +239,20 @@ return view.extend({ // Map module IDs to their dashboard paths var modulePaths = { - 'crowdsec': 'admin/secubox/security/crowdsec/overview', - 'netdata': 'admin/secubox/monitoring/netdata/dashboard', - 'netifyd': 'admin/secubox/security/netifyd/overview', - 'wireguard': 'admin/secubox/network/wireguard/overview', - 'network_modes': 'admin/secubox/network/network-modes/overview', - 'client_guardian': 'admin/secubox/security/client-guardian/overview', - 'system_hub': 'admin/secubox/system/system-hub/overview', - 'bandwidth_manager': 'admin/secubox/network/bandwidth-manager/overview', - 'auth_guardian': 'admin/secubox/security/auth-guardian/overview', - 'media_flow': 'admin/secubox/monitoring/mediaflow/dashboard', - 'vhost_manager': 'admin/secubox/services/vhosts/overview', - 'traffic_shaper': 'admin/secubox/network/traffic-shaper/overview', - 'cdn_cache': 'admin/secubox/network/cdn-cache/overview', - 'ksm_manager': 'admin/secubox/security/ksm-manager/overview' + 'crowdsec': 'admin/secubox/crowdsec/overview', + 'netdata': 'admin/secubox/netdata/dashboard', + 'netifyd': 'admin/secubox/netifyd/overview', + 'wireguard': 'admin/secubox/wireguard/overview', + 'network_modes': 'admin/secubox/network-modes/overview', + 'client_guardian': 'admin/secubox/client-guardian/overview', + 'system_hub': 'admin/secubox/system-hub/overview', + 'bandwidth_manager': 'admin/secubox/bandwidth-manager/overview', + 'auth_guardian': 'admin/secubox/auth-guardian/overview', + 'media_flow': 'admin/secubox/mediaflow/dashboard', + 'vhost_manager': 'admin/secubox/vhosts/overview', + 'traffic_shaper': 'admin/secubox/traffic-shaper/overview', + 'cdn_cache': 'admin/secubox/cdn-cache/overview', + 'ksm_manager': 'admin/secubox/ksm-manager/overview' }; var moduleCards = filteredModules.map(function(module) { @@ -302,22 +302,34 @@ return view.extend({ { id: 'monitoring', label: 'Monitoring', icon: 'πŸ“Š' } ]; - var filterTabs = E('div', { 'class': 'secubox-filter-tabs' }, - filters.map(function(filter) { - var isActive = self.activeFilter === filter.id; - return E('div', { - 'class': 'secubox-filter-tab' + (isActive ? ' active' : ''), - 'click': function() { - self.activeFilter = filter.id; - self.updateModulesGrid(); - } - }, [ - E('span', { 'class': 'secubox-tab-icon' }, filter.icon), - E('span', { 'class': 'secubox-tab-label' }, filter.label) - ]); - }) + var filterTabButtons = filters.map(function(filter) { + var isActive = self.activeFilter === filter.id; + return E('div', { + 'class': 'secubox-filter-tab' + (isActive ? ' active' : ''), + 'click': function() { + self.activeFilter = filter.id; + self.updateModulesGrid(); + } + }, [ + E('span', { 'class': 'secubox-tab-icon' }, filter.icon), + E('span', { 'class': 'secubox-tab-label' }, filter.label) + ]); + }); + + filterTabButtons.push( + E('div', { + 'class': 'secubox-filter-tab secubox-tab-bonus', + 'click': function() { + window.location.href = L.url('admin/secubox/help'); + } + }, [ + E('span', { 'class': 'secubox-tab-icon' }, '✨'), + E('span', { 'class': 'secubox-tab-label' }, _('Bonus Β· Help Γ  SecuBox')) + ]) ); + var filterTabs = E('div', { 'class': 'secubox-filter-tabs' }, filterTabButtons); + return E('div', { 'class': 'secubox-card' }, [ E('h3', { 'class': 'secubox-card-title' }, '🎯 Active Modules (' + activeModules.length + ')'), filterTabs, @@ -359,20 +371,20 @@ return view.extend({ // Map module IDs to their dashboard paths var modulePaths = { - 'crowdsec': 'admin/secubox/security/crowdsec/overview', - 'netdata': 'admin/secubox/monitoring/netdata/dashboard', - 'netifyd': 'admin/secubox/security/netifyd/overview', - 'wireguard': 'admin/secubox/network/wireguard/overview', - 'network_modes': 'admin/secubox/network/network-modes/overview', - 'client_guardian': 'admin/secubox/security/client-guardian/overview', - 'system_hub': 'admin/secubox/system/system-hub/overview', - 'bandwidth_manager': 'admin/secubox/network/bandwidth-manager/overview', - 'auth_guardian': 'admin/secubox/security/auth-guardian/overview', - 'media_flow': 'admin/secubox/monitoring/mediaflow/dashboard', - 'vhost_manager': 'admin/secubox/services/vhosts/overview', - 'traffic_shaper': 'admin/secubox/network/traffic-shaper/overview', - 'cdn_cache': 'admin/secubox/network/cdn-cache/overview', - 'ksm_manager': 'admin/secubox/security/ksm-manager/overview' + 'crowdsec': 'admin/secubox/crowdsec/overview', + 'netdata': 'admin/secubox/netdata/dashboard', + 'netifyd': 'admin/secubox/netifyd/overview', + 'wireguard': 'admin/secubox/wireguard/overview', + 'network_modes': 'admin/secubox/network-modes/overview', + 'client_guardian': 'admin/secubox/client-guardian/overview', + 'system_hub': 'admin/secubox/system-hub/overview', + 'bandwidth_manager': 'admin/secubox/bandwidth-manager/overview', + 'auth_guardian': 'admin/secubox/auth-guardian/overview', + 'media_flow': 'admin/secubox/mediaflow/dashboard', + 'vhost_manager': 'admin/secubox/vhosts/overview', + 'traffic_shaper': 'admin/secubox/traffic-shaper/overview', + 'cdn_cache': 'admin/secubox/cdn-cache/overview', + 'ksm_manager': 'admin/secubox/ksm-manager/overview' }; var moduleCards = filteredModules.map(function(module) { diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js new file mode 100644 index 00000000..b6250b8c --- /dev/null +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js @@ -0,0 +1,203 @@ +'use strict'; +'require view'; +'require dom'; +'require secubox/api as API'; +'require secubox/help as Help'; +'require secubox/theme as Theme'; + +// Ensure SecuBox theme variables are loaded for this view +Theme.init(); + +// Load base SecuBox + help styles +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/help.css') +})); + +return view.extend({ + load: function() { + return API.getStatus(); + }, + + render: function(status) { + var data = status || {}; + var helpPages = Help.getAllHelpPages(); + + return E('div', { 'class': 'secubox-help-page' }, [ + this.renderHero(data), + this.renderHelpCatalog(helpPages), + this.renderSupportSection(), + this.renderFooter() + ]); + }, + + renderHero: function(status) { + return E('div', { 'class': 'secubox-card secubox-help-hero' }, [ + E('div', { 'class': 'secubox-help-hero-text' }, [ + E('span', { 'class': 'secubox-help-eyebrow' }, _('Bonus Tab')), + E('h2', {}, _('Help Γ  SecuBox')), + E('p', { 'class': 'secubox-help-subtitle' }, + _('Retrouvez la documentation, les guides et toutes les faΓ§ons de soutenir la suite SecuBox.')), + E('div', { 'class': 'secubox-help-hero-stats' }, [ + this.renderHeroStat('πŸ“¦', _('Modules Couvertβ€’eβ€’s'), Object.keys(Help.getAllHelpPages()).length), + this.renderHeroStat('βš™οΈ', _('Version Actuelle'), status.version || 'v1.0.0'), + this.renderHeroStat('🌐', _('Site Officiel'), 'secubox.cybermood.eu') + ]) + ]), + E('div', { 'class': 'secubox-help-hero-actions' }, [ + Help.createHelpButton('secubox', 'header', { + icon: 'πŸ“š', + label: _('Ouvrir la knowledge base'), + modal: true + }), + E('a', { + 'class': 'sb-help-btn sb-help-header secubox-help-cta', + 'href': 'https://secubox.cybermood.eu/#contact', + 'target': '_blank' + }, [ + E('span', { 'class': 'sb-help-icon' }, '🀝'), + E('span', { 'class': 'sb-help-label' }, _('Contacter SecuBox')) + ]) + ]) + ]); + }, + + renderHeroStat: function(icon, label, value) { + return E('div', { 'class': 'secubox-help-hero-stat' }, [ + E('div', { 'class': 'secubox-help-hero-stat-icon' }, icon), + E('div', { 'class': 'secubox-help-hero-stat-value' }, value), + E('div', { 'class': 'secubox-help-hero-stat-label' }, label) + ]); + }, + + renderHelpCatalog: function(pages) { + var self = this; + var entries = Object.keys(pages || {}); + + return E('div', { 'class': 'secubox-card' }, [ + E('div', { 'class': 'secubox-card-title-row' }, [ + E('h3', { 'class': 'secubox-card-title' }, 'πŸ“˜ ' + _('Documentation Express')), + E('span', { 'class': 'secubox-card-hint' }, + _('Chaque tuile ouvre la doc dΓ©diΓ©e dans un nouvel onglet.')) + ]), + E('div', { 'class': 'secubox-help-grid' }, + entries.map(function(key) { + return self.renderHelpCard(key, pages[key]); + }) + ) + ]); + }, + + renderHelpCard: function(key, url) { + var info = this.getModuleInfo(key); + + return E('a', { + 'class': 'secubox-help-card', + 'href': url, + 'target': '_blank' + }, [ + E('div', { 'class': 'secubox-help-card-icon' }, info.icon), + E('div', { 'class': 'secubox-help-card-body' }, [ + E('h4', { 'class': 'secubox-help-card-title' }, info.title), + E('p', { 'class': 'secubox-help-card-text' }, info.description || _('Guide officiel et FAQ.')) + ]), + E('span', { 'class': 'secubox-help-card-link' }, _('Voir la doc β†’')) + ]); + }, + + renderSupportSection: function() { + var items = [ + { + icon: 'πŸ’¬', + title: _('Feedback & idΓ©es'), + text: _('Partagez vos retours via GitHub Issues ou email pour faire Γ©voluer les modules.') + }, + { + icon: 'πŸ› οΈ', + title: _('Contribuer au code'), + text: _('Forkez le dΓ©pΓ΄t SecuBox, proposez des amΓ©liorations, corrigez des bugs, crΓ©ez de nouveaux helpers.') + }, + { + icon: 'πŸ€—', + title: _('Soutenir le projet'), + text: _('Commandes pro, sponsoring ou partenariats : contactez CyberMind.fr pour renforcer SecuBox.') + } + ]; + + return E('div', { 'class': 'secubox-card secubox-help-support' }, [ + E('h3', { 'class': 'secubox-card-title' }, '🀝 ' + _('Comment aider SecuBox ?')), + E('div', { 'class': 'secubox-help-support-grid' }, + items.map(function(item) { + return E('div', { 'class': 'secubox-help-support-item' }, [ + E('div', { 'class': 'secubox-help-support-icon' }, item.icon), + E('div', { 'class': 'secubox-help-support-title' }, item.title), + E('p', { 'class': 'secubox-help-support-text' }, item.text) + ]); + }) + ), + E('div', { 'class': 'secubox-help-support-actions' }, [ + Help.createHelpButton('secubox', 'footer', { + icon: 'πŸ’‘', + label: _('Ouvrir la FAQ') + }), + E('a', { + 'class': 'sb-help-btn sb-help-footer', + 'href': 'mailto:contact@cybermind.fr?subject=SecuBox%20Feedback' + }, [ + E('span', { 'class': 'sb-help-icon' }, 'βœ‰οΈ'), + E('span', { 'class': 'sb-help-label' }, _('Γ‰crire Γ  l’équipe')) + ]) + ]) + ]); + }, + + renderFooter: function() { + return E('div', { 'class': 'secubox-help-footer' }, [ + E('div', { 'class': 'secubox-help-footer-text' }, + _('Besoin d’un accompagnement premium ? SecuBox peut Γͺtre intΓ©grΓ©, maintenu et personnalisΓ© par CyberMind.fr.')), + E('div', { 'class': 'secubox-help-footer-links' }, [ + E('a', { + 'href': 'https://secubox.cybermood.eu/', + 'target': '_blank' + }, _('DΓ©couvrir le site vitrine')), + E('span', { 'class': 'sep' }, 'β€’'), + E('a', { + 'href': 'https://github.com/CyberMindStudio/secubox-openwrt', + 'target': '_blank' + }, _('GitHub SecuBox')) + ]) + ]); + }, + + getModuleInfo: function(key) { + var titles = { + 'secubox': { title: _('SecuBox Hub'), icon: 'πŸš€', description: _('Vue d’ensemble, modules et roadmap.') }, + 'system-hub': { title: _('System Hub'), icon: 'βš™οΈ', description: _('Surveillance systΓ¨me et diagnostics.') }, + 'network-modes': { title: _('Network Modes'), icon: '🌐', description: _('Guides de bascule et scΓ©narios rΓ©seau.') }, + 'client-guardian': { title: _('Client Guardian'), icon: 'πŸ›‘οΈ', description: _('Portail captif et NAC avancΓ©.') }, + 'bandwidth-manager': { title: _('Bandwidth Manager'), icon: 'πŸ“Ά', description: _('QoS, classes et quotas rΓ©seau.') }, + 'cdn-cache': { title: _('CDN Cache'), icon: 'πŸ—„οΈ', description: _('Cache CDN local et politiques.') }, + 'traffic-shaper': { title: _('Traffic Shaper'), icon: 'πŸŒ€', description: _('Profils et prΓ©rΓ©glages QoS.') }, + 'wireguard-dashboard': { title: _('WireGuard Dashboard'), icon: 'πŸ›œ', description: _('Peers, profils et QR codes.') }, + 'crowdsec-dashboard': { title: _('CrowdSec Dashboard'), icon: 'πŸ•΅οΈ', description: _('DΓ©cisions, bouncers et alertes.') }, + 'netdata-dashboard': { title: _('Netdata Dashboard'), icon: 'πŸ“Š', description: _('Monitoring temps rΓ©el Netdata.') }, + 'netifyd-dashboard': { title: _('Netifyd Dashboard'), icon: 'πŸ”', description: _('DPI, flux et risques applications.') }, + 'auth-guardian': { title: _('Auth Guardian'), icon: 'πŸ”', description: _('Auth portail, vouchers et OAuth.') }, + 'vhost-manager': { title: _('VHost Manager'), icon: '🧩', description: _('Virtual hosts, SSL & redirections.') }, + 'ksm-manager': { title: _('KSM Manager'), icon: 'πŸ”‘', description: _('Gestion clΓ©s et secrets sΓ©curisΓ©s.') }, + 'media-flow': { title: _('Media Flow'), icon: '🎬', description: _('Analytique streaming & clients.') } + }; + + var fallbackTitle = key.replace(/-/g, ' ').replace(/\b\w/g, function(c) { + return c.toUpperCase(); + }); + + return titles[key] || { title: fallbackTitle, icon: 'πŸ“¦' }; + } +}); 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 155ab638..c4d38dac 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 @@ -106,21 +106,30 @@ return view.extend({ { 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); - }) + var filterButtons = 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); + }); + + filterButtons.push( + E('button', { + 'class': 'secubox-filter-tab secubox-filter-tab-bonus', + 'click': function() { + window.location.href = L.url('admin/secubox/help'); + } + }, '✨ ' + _('Bonus Β· Help Γ  SecuBox')) ); + + return E('div', { 'class': 'secubox-filter-tabs' }, filterButtons); }, renderModuleCards: function(modules, filter) { @@ -256,20 +265,20 @@ return view.extend({ getModuleDashboardPath: function(moduleId) { var paths = { - 'crowdsec': 'admin/secubox/security/crowdsec/overview', - 'netdata': 'admin/secubox/monitoring/netdata/dashboard', - 'netifyd': 'admin/secubox/security/netifyd/overview', - 'wireguard': 'admin/secubox/network/wireguard/overview', - 'network_modes': 'admin/secubox/network/network-modes/overview', - 'client_guardian': 'admin/secubox/security/client-guardian/overview', - 'system_hub': 'admin/secubox/system/system-hub/overview', - 'bandwidth_manager': 'admin/secubox/network/bandwidth-manager/overview', - 'auth_guardian': 'admin/secubox/security/auth-guardian/overview', - 'media_flow': 'admin/secubox/monitoring/mediaflow/dashboard', - 'vhost_manager': 'admin/secubox/services/vhosts/overview', - 'traffic_shaper': 'admin/secubox/network/traffic-shaper/overview', - 'cdn_cache': 'admin/secubox/network/cdn-cache/overview', - 'ksm_manager': 'admin/secubox/security/ksm-manager/overview' + 'crowdsec': 'admin/secubox/crowdsec/overview', + 'netdata': 'admin/secubox/netdata/dashboard', + 'netifyd': 'admin/secubox/netifyd/overview', + 'wireguard': 'admin/secubox/wireguard/overview', + 'network_modes': 'admin/secubox/network-modes/overview', + 'client_guardian': 'admin/secubox/client-guardian/overview', + 'system_hub': 'admin/secubox/system-hub/overview', + 'bandwidth_manager': 'admin/secubox/bandwidth-manager/overview', + 'auth_guardian': 'admin/secubox/auth-guardian/overview', + 'media_flow': 'admin/secubox/mediaflow/dashboard', + 'vhost_manager': 'admin/secubox/vhosts/overview', + 'traffic_shaper': 'admin/secubox/traffic-shaper/overview', + 'cdn_cache': 'admin/secubox/cdn-cache/overview', + 'ksm_manager': 'admin/secubox/ksm-manager/overview' }; return paths[moduleId] || null; }, diff --git a/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json b/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json index c2c4ee29..3ed7a20c 100644 --- a/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json +++ b/luci-app-secubox/root/usr/share/luci/menu.d/luci-app-secubox.json @@ -39,11 +39,6 @@ "order": 10, "action": {"type": "view", "path": "secubox/monitoring"} }, - "admin/secubox/network": { - "title": "Network Management", - "order": 40, - "action": {"type": "firstchild"} - }, "admin/secubox/system": { "title": "System & Performance", "order": 50, @@ -53,5 +48,10 @@ "title": "Services & Applications", "order": 60, "action": {"type": "firstchild"} + }, + "admin/secubox/help": { + "title": "Bonus Β· Help Γ  SecuBox", + "order": 99, + "action": {"type": "view", "path": "secubox/help"} } } diff --git a/scripts/sync_module_versions.py b/scripts/sync_module_versions.py new file mode 100755 index 00000000..b8446ed4 --- /dev/null +++ b/scripts/sync_module_versions.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Synchronize module versions and website progress bars.""" +from __future__ import annotations +import re +import sys +from pathlib import Path +import difflib +import subprocess + +RE_WEBSITE = re.compile( + r'(
\s*\s*
v)' + r'([0-9]+\.[0-9]+\.[0-9]+)(?:\s*Β·\s*)([0-9.]+)(\s*/ 1.00
)' +) + + +def version_ratio(ver: str) -> float: + major, minor, patch = map(int, ver.split('.')) + return major + minor / 10 + patch / 100 + + +def update_website(html: Path) -> bool: + text = html.read_text() + + def repl(match: re.Match) -> str: + ver = match.group(4) + ratio = version_ratio(ver) + width = f"{ratio * 100:.0f}".rstrip('0').rstrip('.') + label = f"{ratio:.2f}".rstrip('0').rstrip('.') + return f"{match.group(1)}{width}{match.group(3)}{ver} Β· {label}{match.group(6)}" + + new_text, count = RE_WEBSITE.subn(repl, text) + if count: + if new_text == text: + return False + diff = difflib.unified_diff( + text.splitlines(keepends=True), + new_text.splitlines(keepends=True), + fromfile=str(html), + tofile=str(html) + ) + diff_text = ''.join(diff) + if not diff_text: + return False + subprocess.run(['patch', str(html)], input=diff_text.encode(), check=True) + return True + return False + + +def main() -> int: + repo_root = Path(__file__).resolve().parents[1] + site_dir = repo_root.parent / 'secubox-website' + + targets = [site_dir / 'index.html', site_dir / 'campaign.html'] + overall = False + + for html in targets: + if not html.exists(): + print(f'Skipping missing file: {html}', file=sys.stderr) + continue + if update_website(html): + print(f'Updated {html.name}') + overall = True + + print('Website progress sync', 'done' if overall else 'no changes') + return 0 + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/scripts/sync_module_versions.sh b/scripts/sync_module_versions.sh new file mode 100755 index 00000000..10fad911 --- /dev/null +++ b/scripts/sync_module_versions.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SCR="$REPO_ROOT/scripts/sync_module_versions.py" + +python3 "$SCR" diff --git a/secubox-tools/deploy-website.sh b/secubox-tools/deploy-website.sh new file mode 100755 index 00000000..6f0cf248 --- /dev/null +++ b/secubox-tools/deploy-website.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# Deploy SecuBox website to an OpenWrt router. +# Usage: ./secubox-tools/deploy-website.sh [root@192.168.1.1] [/path/to/website] + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +ROUTER_HOST="${1:-root@192.168.8.191}" +WEBSITE_PATH="${2:-}" +TARGET_DIR="/www/luci-static/secubox" + +# Determine website source path +if [[ -z "$WEBSITE_PATH" ]]; then + # Check common locations + COMMON_PATHS=( + "$REPO_ROOT/../secubox-website" + "$HOME/CyberMindStudio/_files/secubox-website" + "./secubox-website" + ) + + for path in "${COMMON_PATHS[@]}"; do + if [[ -d "$path" ]]; then + WEBSITE_PATH="$path" + break + fi + done + + if [[ -z "$WEBSITE_PATH" ]]; then + echo "ERROR: Website directory not found. Please specify path as second argument." >&2 + echo "Usage: $0 [router_host] [website_path]" >&2 + exit 1 + fi +fi + +if [[ ! -d "$WEBSITE_PATH" ]]; then + echo "ERROR: Website directory not found: $WEBSITE_PATH" >&2 + exit 1 +fi + +echo "[1/4] Preparing website files from $WEBSITE_PATH…" >&2 + +# Create tarball excluding unnecessary files +TARBALL="/tmp/secubox-website-$(date +%s).tar.gz" +(cd "$WEBSITE_PATH" && tar czf "$TARBALL" \ + --exclude='.git' \ + --exclude='.claude' \ + --exclude='*.md' \ + --exclude='.gitignore' \ + --exclude='README*' \ + --exclude='LICENSE' \ + .) + +echo "[2/4] Uploading website files to $ROUTER_HOST:$TARGET_DIR/" >&2 +scp "$TARBALL" "${ROUTER_HOST}:/tmp/secubox-website.tar.gz" + +echo "[3/4] Deploying website on router…" >&2 +ssh "$ROUTER_HOST" "sh -s" <&2 + mkdir -p "\$BACKUP_DIR" + cp -a "$TARGET_DIR"/* "\$BACKUP_DIR/" 2>/dev/null || true +fi + +# Extract new website +echo "[router] Extracting website files…" >&2 +cd "$TARGET_DIR" +tar xzf /tmp/secubox-website.tar.gz + +# Set proper permissions +chmod 755 "$TARGET_DIR" +find "$TARGET_DIR" -type d -exec chmod 755 {} \; +find "$TARGET_DIR" -type f -name "*.html" -exec chmod 644 {} \; +find "$TARGET_DIR" -type f -name "*.js" -exec chmod 644 {} \; +find "$TARGET_DIR" -type f -name "*.css" -exec chmod 644 {} \; 2>/dev/null || true + +# Clean up +rm -f /tmp/secubox-website.tar.gz + +echo "[router] Website deployed to $TARGET_DIR" +echo "[router] Access URL: http://\$(uci get network.lan.ipaddress 2>/dev/null || echo 'router-ip')/luci-static/secubox/" +EOF + +echo "[4/4] Cleaning up local tarball…" >&2 +rm -f "$TARBALL" + +echo "" +echo "βœ“ Website deployment completed successfully!" +echo " Target: $ROUTER_HOST:$TARGET_DIR" +echo " Files: $(find "$WEBSITE_PATH" -type f \( -name "*.html" -o -name "*.js" \) | wc -l) files deployed" +echo ""