secubox-openwrt/package/secubox/secubox-p2p/root/www/api/factory/run
CyberMind-FR a9130715e9 feat(p2p): Add SecuBox Factory unified dashboard with signed Merkle snapshots
Implement mesh-distributed, cryptographically-validated control center:

- Add factory.sh library with Ed25519 signing via signify-openbsd
- Add Merkle tree calculation for /etc/config validation
- Add CGI endpoints: dashboard, tools, run, snapshot, pubkey
- Add KISS Web UI (~280 lines vanilla JS, inline CSS, zero deps)
- Add gossip-based 3-peer fanout for snapshot synchronization
- Add offline operations queue with replay on reconnect
- Add LuCI iframe integration under MirrorBox > Factory tab
- Configure uhttpd alias for /factory/ on port 7331
- Bump secubox-p2p version to 0.4.0

Factory UI accessible at http://<device>:7331/factory/

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:03:54 +01:00

160 lines
3.5 KiB
Bash

#!/bin/sh
# Factory Run - Execute tools
# CGI endpoint for SecuBox Factory
echo "Content-Type: application/json"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: POST, OPTIONS"
echo "Access-Control-Allow-Headers: Content-Type"
echo ""
# Handle CORS preflight
if [ "$REQUEST_METHOD" = "OPTIONS" ]; then
exit 0
fi
# Only allow POST
if [ "$REQUEST_METHOD" != "POST" ]; then
echo '{"success":false,"error":"method_not_allowed"}'
exit 1
fi
# Load factory library
. /usr/lib/secubox/factory.sh 2>/dev/null
# Read POST body
read -r body
# Parse tool ID from body
tool_id=$(echo "$body" | jsonfilter -e '@.tool' 2>/dev/null)
params=$(echo "$body" | jsonfilter -e '@.params' 2>/dev/null)
if [ -z "$tool_id" ]; then
echo '{"success":false,"error":"missing_tool_id"}'
exit 1
fi
# Log the action
factory_audit_log "tool_run" "$tool_id" 2>/dev/null
# Execute tool
output=""
success=1
case "$tool_id" in
snapshot)
hash=$(create_snapshot 2>&1)
output="Snapshot created with hash: $hash"
;;
verify)
result=$(verify_snapshot 2>&1)
output="Snapshot verification: $result"
[ "$result" != "valid" ] && success=0
;;
gossip)
result=$(gossip_sync 2>&1)
output="Gossip sync result: $result"
;;
discover)
if [ -x /usr/sbin/secubox-p2p ]; then
result=$(/usr/sbin/secubox-p2p discover 5 2>&1)
output="Discovery result: $result"
else
output="P2P daemon not available"
success=0
fi
;;
services)
if [ -x /usr/sbin/secubox-p2p ]; then
result=$(/usr/sbin/secubox-p2p services 2>&1)
output="$result"
else
output='{"error":"p2p_unavailable"}'
success=0
fi
;;
validate)
if [ -x /secubox-tools/validate-modules.sh ]; then
result=$(/secubox-tools/validate-modules.sh 2>&1 | tail -50)
output="$result"
else
output="Validation script not found on this device"
success=0
fi
;;
repair)
if [ -x /secubox-tools/secubox-repair.sh ]; then
result=$(/secubox-tools/secubox-repair.sh 2>&1 | tail -50)
output="$result"
else
output="Repair script not found on this device"
success=0
fi
;;
backup)
# Create sysupgrade backup
backup_file="/tmp/backup-$(date +%Y%m%d-%H%M%S).tar.gz"
if sysupgrade --create-backup "$backup_file" 2>/dev/null; then
size=$(ls -lh "$backup_file" 2>/dev/null | awk '{print $5}')
output="Backup created: $backup_file ($size)"
else
# Fallback: tar the config directory
backup_file="/tmp/backup-$(date +%Y%m%d-%H%M%S).tar.gz"
if tar -czf "$backup_file" /etc/config 2>/dev/null; then
size=$(ls -lh "$backup_file" 2>/dev/null | awk '{print $5}')
output="Config backup created: $backup_file ($size)"
else
output="Backup failed"
success=0
fi
fi
;;
pending)
count=$(pending_count 2>/dev/null || echo "0")
output="Pending operations: $count"
;;
replay)
result=$(replay_pending 2>&1)
output="Replay result: $result"
;;
fingerprint)
fp=$(factory_fingerprint 2>&1)
output="Node fingerprint: $fp"
;;
merkle)
merkle=$(merkle_config 2>&1)
output="Merkle root: $merkle"
;;
*)
output="Unknown tool: $tool_id"
success=0
;;
esac
# Update snapshot after action (if successful)
if [ $success -eq 1 ]; then
create_snapshot >/dev/null 2>&1
fi
# Escape output for JSON (basic escaping)
output_escaped=$(echo "$output" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | tr '\n' ' ' | tr '\t' ' ')
# Return result
if [ $success -eq 1 ]; then
echo "{\"success\":true,\"tool\":\"$tool_id\",\"output\":\"$output_escaped\"}"
else
echo "{\"success\":false,\"tool\":\"$tool_id\",\"error\":\"$output_escaped\"}"
fi