#!/bin/sh # P2P Package Catalog Sync API # Aggregates package catalogs from all mesh peers echo "Content-Type: application/json" echo "Access-Control-Allow-Origin: *" echo "Access-Control-Allow-Methods: GET, POST, OPTIONS" echo "" # Handle CORS preflight if [ "$REQUEST_METHOD" = "OPTIONS" ]; then exit 0 fi # Load P2P feed library . /usr/lib/secubox/p2p-feed.sh 2>/dev/null # Parse query string parse_query() { local query="$QUERY_STRING" local key value PEER_FILTER="" REFRESH="" while [ -n "$query" ]; do key="${query%%=*}" query="${query#*=}" value="${query%%&*}" query="${query#*&}" [ "$query" = "$value" ] && query="" case "$key" in peer) PEER_FILTER="$value" ;; refresh) REFRESH="$value" ;; esac done } parse_query # Invalidate cache if refresh requested if [ "$REFRESH" = "1" ]; then invalidate_peer_cache fi # Get node info NODE_ID=$(get_local_node_id) NODE_NAME=$(get_local_node_name) UPDATED=$(date -Iseconds 2>/dev/null || date '+%Y-%m-%dT%H:%M:%S') # Start JSON output echo '{' echo "\"node_id\":\"$NODE_ID\"," echo "\"node_name\":\"$NODE_NAME\"," echo "\"updated\":\"$UPDATED\"," # Sync stats PEERS_SYNCED=0 PEERS_FAILED=0 TOTAL_PACKAGES=0 echo '"sources":[' FIRST_SOURCE=1 # Include local packages if feed_exists; then LOCAL_COUNT=$(get_package_count) TOTAL_PACKAGES=$LOCAL_COUNT echo '{' echo "\"node_id\":\"$NODE_ID\"," echo "\"node_name\":\"$NODE_NAME\"," echo "\"type\":\"local\"," echo "\"address\":\"local\"," echo "\"status\":\"ok\"," echo "\"feed_hash\":\"$(get_feed_hash)\"," echo "\"package_count\":$LOCAL_COUNT," echo "\"packages\":$(packages_to_json)" echo '}' FIRST_SOURCE=0 fi # Sync from peers PEERS_FILE="/tmp/secubox-p2p-peers.json" if [ -f "$PEERS_FILE" ]; then PEER_COUNT=$(jsonfilter -i "$PEERS_FILE" -e '@.peers[*]' 2>/dev/null | wc -l) I=0 while [ $I -lt $PEER_COUNT ]; do IS_LOCAL=$(jsonfilter -i "$PEERS_FILE" -e "@.peers[$I].is_local" 2>/dev/null) [ "$IS_LOCAL" = "true" ] && { I=$((I + 1)); continue; } PEER_ADDR=$(jsonfilter -i "$PEERS_FILE" -e "@.peers[$I].address" 2>/dev/null) PEER_NAME=$(jsonfilter -i "$PEERS_FILE" -e "@.peers[$I].name" 2>/dev/null) PEER_WG=$(jsonfilter -i "$PEERS_FILE" -e "@.peers[$I].wg_addresses" 2>/dev/null | cut -d',' -f1) # Prefer WireGuard address USE_ADDR="$PEER_ADDR" [ -n "$PEER_WG" ] && USE_ADDR="$PEER_WG" # Skip if filtering for specific peer if [ -n "$PEER_FILTER" ] && [ "$USE_ADDR" != "$PEER_FILTER" ] && [ "$PEER_NAME" != "$PEER_FILTER" ]; then I=$((I + 1)) continue fi [ -n "$USE_ADDR" ] || { I=$((I + 1)); continue; } # Fetch peer's package catalog PEER_CATALOG=$(curl -s --connect-timeout 5 --max-time 30 \ "http://${USE_ADDR}:7331/api/factory/packages" 2>/dev/null) [ $FIRST_SOURCE -eq 0 ] && echo ',' FIRST_SOURCE=0 if [ -n "$PEER_CATALOG" ]; then PEER_HASH=$(echo "$PEER_CATALOG" | jsonfilter -e '@.feed_hash' 2>/dev/null) PEER_PKG_COUNT=$(echo "$PEER_CATALOG" | jsonfilter -e '@.package_count' 2>/dev/null) PEER_PACKAGES=$(echo "$PEER_CATALOG" | jsonfilter -e '@.packages' 2>/dev/null) if [ -n "$PEER_HASH" ]; then PEERS_SYNCED=$((PEERS_SYNCED + 1)) TOTAL_PACKAGES=$((TOTAL_PACKAGES + ${PEER_PKG_COUNT:-0})) echo '{' echo "\"node_id\":\"$USE_ADDR\"," echo "\"node_name\":\"$PEER_NAME\"," echo "\"type\":\"peer\"," echo "\"address\":\"$USE_ADDR\"," echo "\"status\":\"ok\"," echo "\"feed_hash\":\"$PEER_HASH\"," echo "\"package_count\":${PEER_PKG_COUNT:-0}," echo "\"packages\":${PEER_PACKAGES:-[]}" echo '}' else PEERS_FAILED=$((PEERS_FAILED + 1)) echo '{' echo "\"node_id\":\"$USE_ADDR\"," echo "\"node_name\":\"$PEER_NAME\"," echo "\"type\":\"peer\"," echo "\"address\":\"$USE_ADDR\"," echo "\"status\":\"error\"," echo "\"error\":\"invalid_response\"" echo '}' fi else PEERS_FAILED=$((PEERS_FAILED + 1)) echo '{' echo "\"node_id\":\"$USE_ADDR\"," echo "\"node_name\":\"$PEER_NAME\"," echo "\"type\":\"peer\"," echo "\"address\":\"$USE_ADDR\"," echo "\"status\":\"unreachable\"," echo "\"error\":\"connection_failed\"" echo '}' fi I=$((I + 1)) done fi echo '],' # Summary stats echo "\"sync_stats\":{" echo "\"peers_synced\":$PEERS_SYNCED," echo "\"peers_failed\":$PEERS_FAILED," echo "\"total_packages\":$TOTAL_PACKAGES" echo '}' echo '}'