Edit, pull, and push Streamlit apps via Gitea:
CLI (slforge):
- edit: Open app source in Gitea web editor
- pull: Pull latest changes from Gitea repo
- push: Commit and push local changes to Gitea
- preview: Generate HTML preview of app
- Auto-creates org/repo on first edit
RPCD (5 new methods):
- gitea_status: Check Gitea connectivity and app repo status
- edit: Get Gitea editor URL for app
- pull: Pull from Gitea to local
- push: Push local changes to Gitea
- preview: Generate preview capture
LuCI (overview.js):
- Gitea status card with connection indicator
- Edit button opens Gitea web editor
- Pull button syncs from remote
- Editor modal for inline editing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- generate_landing() now uses /usr/share/metacatalog/templates/landing.html.tpl
- Fallback to basic inline HTML if template missing
- Enables easier landing page customization
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New scan_haproxy() function indexes HAProxy vhosts as catalog entries
- Skips entries already indexed from MetaBlogizer/Streamlit sources
- Extracts backend, port, SSL/WAF status from UCI config
- Auto-detects content type from backend name (streamlit, metablog, media, cloud)
- Updated cmd_scan to include haproxy source
- Total entries: 120 -> 246
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New luci-app-metacatalog package:
- RPCD backend with 10 methods (list_entries, list_books, search, etc.)
- ACL permissions for read/write access
- Menu entry under SecuBox
- KISS-themed dashboard with:
- Stats chips (entries, metablogs, streamlits, books)
- Virtual books shelf with color-coded cards
- Entry links to published content
- Sync button for manual refresh
- Landing page link
Deployed and tested on router.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add automatic mitmproxy route sync after vhost operations
- Route through WAF by default: sets original_backend for route resolution
- Add --nowaf option to bypass WAF routing if needed
- Prevents missing routes when creating new vhosts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem: get_overview RPC was timing out (30s+) due to 12+ sequential
cscli calls with CAPI data, causing "TypeError: can't assign to property
'countries' on 5" in LuCI.
Solution:
- Pre-cached architecture with /tmp/secubox/crowdsec-overview.json
- get_overview() returns cached data instantly (0.08s)
- refresh_overview_cache() runs via cron every minute
- Reduced cscli calls from 12 to 4 (metrics, decisions, alerts, bouncers)
- Extract flat decisions array using jsonfilter
- Manual JSON building to avoid jshn argument size limits
- Add /etc/cron.d/crowdsec-dashboard for periodic refresh
Also includes:
- Streamlit Control: Deploy functionality like metablogizer
- Streamlit Control: Enhanced Security page with WAF/CrowdSec data
- mitmproxy LuCI: Add timeout race to prevent page hang
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- get_installed_apps: Returns installed apps with menu paths and status
- get_kiss_menu: Returns dynamic menu by category (security, system, productivity, media)
- Enables KISS UI to dynamically show installed apps
- Updated ACL to include new methods
Also on router:
- Created rpcd-watchdog service that monitors rpcd every 60s
- Automatically restarts rpcd if luci module fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use printf to generate actual escape sequences instead of literal strings
- Fixes colors not rendering in 'secubox help' output
- POSIX sh heredoc doesn't interpret \033 escapes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Custom ASCII art banner with SecuBox branding
- Shows helpful info: CLI help, dashboard URL
- Installed to /etc/banner on device
- Added to conffiles for upgrade preservation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Without this rule, the build system attempts to run 'make' in the
build directory, which fails because there's no Makefile there.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix get_next_port() to check both uhttpd and metablogizer configs
- Add check-ports command to scan for duplicate port assignments
- Add fix-ports command to auto-assign new ports to duplicates
- Update WIP.md with 2026-03-10 changes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_service_health RPCD method to check all HAProxy routes
- Integrate /usr/sbin/service-health-check for backend HTTP probing
- Add health panel in services.js with up/down stats and health %
- Display down services list with tooltips showing IP:port
- Add refresh button for manual health check trigger
- Update ACL with get_service_health read permission
- 5-minute cache for health data with force-refresh option
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 4-layer architecture visualization (Core, AI, MirrorNet, Certification)
- 22+ features with dependency tracking (dependsOn/usedBy)
- 80+ components with status indicators
- Interactive filters: layer, status, category with localStorage persistence
- Feature cards: click to expand and see full dependencies
- Live RPCD data refresh (60s auto-refresh)
- Standalone HTML page for public access (/dev-status.html)
- ES5 compatible for older browsers
- Milestone timeline to v1.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Integrates ttyd WebSocket terminal into RTTY Remote module:
- New "Web Terminal" menu item in System Hub
- Iframe-based terminal embedding ttyd on port 7681
- Node selector for local/remote terminal access
- Remote node detection (direct ttyd or SSH fallback)
- Fullscreen and refresh controls
- RPCD method: start_terminal for remote node terminal info
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements token-based authentication that grants RPC and terminal access
without requiring LuCI credentials. Support technicians can connect using
a short 6-character code.
CLI commands:
- rttyctl token generate [ttl] [permissions]
- rttyctl token list
- rttyctl token validate <code>
- rttyctl token revoke <code>
- rttyctl token-rpc <code> <object> <method> [params]
RPCD methods:
- token_generate: Create support token with TTL
- token_list: List active tokens
- token_validate: Check token validity
- token_revoke: Revoke a token
- token_rpc: Execute RPC with token auth (no LuCI session needed)
LuCI Support Panel:
- Generate code with selectable validity (30m/1h/2h/4h)
- Enter code to connect to remote node
- Token-authenticated RPC execution
- Live token list with copy/revoke actions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Local addresses (127.0.0.1, localhost, 192.168.255.1, lan IP) now use
direct ubus call instead of HTTP JSON-RPC, providing full access to
all ubus methods without authentication restrictions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- jshn cannot embed raw JSON in objects, use printf instead
- Return proper {"success":true,"result":{...}} format
- Handle error cases with escaped error messages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix TypeError in support.js: add null checks for DOM elements
- Move menu entries from Services to System Hub (KISS UI)
- Menu paths: admin/secubox/system/system-hub/rtty-remote
- Menu paths: admin/secubox/system/system-hub/support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Dashboard now includes:
- Authoritative Zones table with View/Dump/Reload actions
- Import Zone modal with domain input
- Zone content viewer with download option
- Secondary DNS providers section
- Add Secondary modal (OVH/Gandi/Cloudflare support)
New RPC calls for zone_list, zone_dump, zone_import, zone_export,
zone_reload, secondary_list, secondary_add, secondary_remove.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove 2>/dev/null from for-loop glob pattern which causes syntax
error in BusyBox ash shell. The [ -f "$zf" ] check handles the
case when no zone files exist.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive zone management for DNS master functionality:
- vortexctl zone list/dump/import/export/reload commands
- Secondary DNS provider configuration (OVH support)
- RPCD methods for LuCI integration
- ACL permissions for new methods
This enables importing zones from external providers (Gandi) and
configuring OVH as secondary DNS with SecuBox as authoritative master.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Skip UCI userlists already defined in AUTH_USERLIST_FILE to avoid
duplicate 'secubox_users' userlist warning
- Fix indentation of nocache http-request rules in _emit_sorted_path_acls
- Use correct ACL names for path-based nocache rules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Port 8889 conflicts with avatar-tap Streamlit service.
Updated mitmproxy-in instance to use port 8890 for HAProxy WAF routing.
Changes:
- UCI config: proxy_port and listen_port now default to 8890
- mitmproxyctl: Updated fallback defaults and documentation
- README: Updated architecture diagrams with correct port
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Root cause: jshn overhead + subshell issues with piped while loops
- Solution: Direct JSON output with printf, temp file for vhosts
- Deployed ACL file for LuCI authentication
- Handler now returns 226 vhosts in <10 seconds
Also:
- Added ROADMAP.md with version milestones and dependency graph
- Updated WIP.md with today's completed tasks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Lyrion: Default media_path changed from /srv/media to /mnt/MUSIC
- PhotoPrism: Default originals_path changed from /srv/photoprism/originals to /mnt/PHOTO
These paths reflect the actual mount points used for external media storage.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PHOTOPRISM_READONLY=true to prevent writes to originals
- Add PHOTOPRISM_SIDECAR_PATH and PHOTOPRISM_CACHE_PATH to writable storage
- Create run_photoprism_cmd helper to pass environment to lxc-attach
- Fixes indexing on read-only Apple Photos library mounts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add originals_path option to UCI config (default: /srv/photoprism/originals)
- Add set_config RPC method to update originals_path from LuCI
- Add Storage Settings section to LuCI dashboard
- Update LXC config to use configurable ORIGINALS_PATH
- Update get_stats to scan originals_path instead of data_path/originals
- Lyrion media_path already configurable via Settings page
Both services now support external mount points:
- PhotoPrism: /mnt/PHOTO for photos
- Lyrion: /mnt/MUSIC for music
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace MariaDB with SQLite (no external database needed)
- Update LXC config with proper device permissions and capabilities
- Install libvips42 instead of mariadb-server
- Fix binary path to ./bin/photoprism
- Use environment variables instead of options.yml
- Simplify backup to just archive storage directory
- Update WIP.md with SQLite note
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-app-photoprism: LXC-based PhotoPrism deployment
- Debian Bookworm container with MariaDB, FFmpeg
- AI face recognition, object detection, places/maps
- photoprismctl CLI: install/start/stop/index/import/emancipate
- HAProxy integration via mitmproxy (WAF-safe)
- luci-app-photoprism: KISS-themed dashboard
- Stats cards (photos, videos, storage)
- Service controls and AI feature display
- Emancipate form for public exposure
- RPCD backend with 12 methods
docs: Update WIP.md with PhotoPrism feature
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix jshn boolean handling (use 1/0 instead of "true"/"false")
- Rework UI with dark theme compatible styling
- Add emoji-based status indicators (🔗🔒🛡️✅)
- Simplify interface with async Load More pagination
- Update README.md to v0.18.0 with 86 modules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Renamed from routes-status to vhosts-checker to avoid conflict with
OpenWrt's default network routes page.
- KISS UI theme with header chips and status cards
- Shows HAProxy vhosts with mitmproxy route status (OUT/IN)
- SSL certificate status indicators
- WAF bypass detection
- Sync routes and add missing route actions
- Accessible at Status → VHosts Checker and KISS UI Network → VHosts Checker
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite overview.js with KissTheme.wrap() for consistent SecuBox styling
- Add header chips for stats (vhosts, active, missing routes, WAF bypass, SSL)
- Add service status cards (HAProxy, mitmproxy, host IP)
- Add to KISS navigation under Network → Routes Status
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New package luci-app-routes-status providing:
- HAProxy vhosts status overview (218+ vhosts supported)
- mitmproxy route configuration status (OUT/IN routes)
- SSL certificate status indicators
- WAF bypass detection (vhosts not using mitmproxy_inspector)
- Sync routes and add missing route actions
- RPCD backend with batch processing for large vhost counts
Accessible at Status → Routes Status in LuCI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
secubox-users:
- Add gitea and jellyfin to supported services list
- Add create/update/delete handlers for gitea (via API) and jellyfin
- Update CLI help and status display to include new services
luci-app-secubox-users:
- Add jellyfin service checkbox and badge in frontend
- Update RPCD handler to check jellyfin service status
mitmproxy routing fix:
- nextcloudctl: Use host LAN IP instead of 127.0.0.1 for WAF routes
(mitmproxy runs in container, can't reach host's localhost)
- metablogizerctl: Same fix for mitmproxy route registration
- mitmproxyctl: Fix sync_metablogizer_routes to use host IP
This fixes 502/403 errors when accessing services through HAProxy->mitmproxy
because the mitmproxy container couldn't route to 127.0.0.1 on the host.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- network-modes: Remove orphan code block after final esac statement
- netdata-dashboard: Replace bash process substitution with POSIX awk
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, emancipation relied on secubox-route or mitmproxyctl sync-routes
which didn't reliably add routes to haproxy-routes.json. This caused newly
emancipated services to return 404 from mitmproxy.
Changes:
- streamlitctl: Direct JSON write as primary method for route registration
- metablogizerctl: Direct JSON write as primary method
- peertubectl: Direct JSON write as primary method
- pinaforectl: Direct JSON write + route through mitmproxy_inspector for WAF
All emancipation flows now directly write to /srv/mitmproxy-in/haproxy-routes.json
using Python, with secubox-route and mitmproxyctl as fallbacks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPCD returns 'bytes_saved' but the JS was looking for
'bandwidth_saved_bytes', causing the "BW Saved" stat to always show 0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>