#!/bin/bash # Ginxsom Admin API Test Script # Tests admin API endpoints using nak (for Nostr events) and curl # # Prerequisites: # - nak: https://github.com/fiatjaf/nak # - curl # - jq (for JSON parsing) # - Admin pubkey configured in ginxsom server_config set -e # Configuration GINXSOM_URL="http://localhost:9001" # Test admin keys (for development/testing only - DO NOT USE IN PRODUCTION) TEST_ADMIN_PRIVKEY="993bf9c54fc00bd32a5a1ce64b6d384a5fce109df1e9aee9be1052c1e5cd8120" TEST_ADMIN_PUBKEY="2ef05348f28d24e0f0ed0751278442c27b62c823c37af8d8d89d8592c6ee84e7" ADMIN_PRIVKEY="${ADMIN_PRIVKEY:-${TEST_ADMIN_PRIVKEY}}" ADMIN_PUBKEY="" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } check_dependencies() { log_info "Checking dependencies..." for cmd in nak curl jq; do if ! command -v $cmd &> /dev/null; then log_error "$cmd is not installed" case $cmd in nak) echo "Install from: https://github.com/fiatjaf/nak" ;; jq) echo "Install jq for JSON processing" ;; curl) echo "curl should be available in most systems" ;; esac exit 1 fi done log_success "All dependencies found" } generate_admin_keys() { if [[ -z "$ADMIN_PRIVKEY" ]]; then log_info "Generating new admin key pair..." ADMIN_PRIVKEY=$(nak key generate) log_warning "Generated new admin private key: $ADMIN_PRIVKEY" log_warning "Save this key for future use: export ADMIN_PRIVKEY='$ADMIN_PRIVKEY'" fi ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public) log_info "Admin public key: $ADMIN_PUBKEY" } create_admin_event() { local method="$1" local endpoint="$2" local content="admin_request" local expiration=$(($(date +%s) + 3600)) # 1 hour from now # Create Nostr event with nak - use kind 33335 for admin/configuration events local event=$(nak event -k 33335 -c "$content" \ --tag method="$method" \ --tag endpoint="$endpoint" \ --tag expiration="$expiration" \ --sec "$ADMIN_PRIVKEY") echo "$event" } send_admin_request() { local method="$1" local endpoint="$2" local data="$3" log_info "Testing $method $endpoint" # Create authenticated Nostr event with method and endpoint local event=$(create_admin_event "$method" "$endpoint") local auth_header="Nostr $(echo "$event" | base64 -w 0)" # Send request with curl local curl_args=(-s -w "%{http_code}" -H "Authorization: $auth_header") if [[ "$method" == "PUT" && -n "$data" ]]; then curl_args+=(-H "Content-Type: application/json" -d "$data") fi local response=$(curl "${curl_args[@]}" -X "$method" "$GINXSOM_URL$endpoint") local http_code="${response: -3}" local body="${response%???}" if [[ "$http_code" =~ ^2 ]]; then log_success "$method $endpoint - HTTP $http_code" if [[ -n "$body" ]]; then echo "$body" | jq . 2>/dev/null || echo "$body" fi else log_error "$method $endpoint - HTTP $http_code" echo "$body" | jq . 2>/dev/null || echo "$body" fi return $([[ "$http_code" =~ ^2 ]]) } test_health_endpoint() { log_info "=== Testing Health Endpoint (no auth required) ===" local response=$(curl -s -w "%{http_code}" "$GINXSOM_URL/api/health") local http_code="${response: -3}" local body="${response%???}" if [[ "$http_code" =~ ^2 ]]; then log_success "GET /api/health - HTTP $http_code" echo "$body" | jq . else log_error "GET /api/health - HTTP $http_code" echo "$body" fi } test_stats_endpoint() { log_info "=== Testing Statistics Endpoint ===" send_admin_request "GET" "/api/stats" } test_config_endpoints() { log_info "=== Testing Configuration Endpoints ===" # Get current config send_admin_request "GET" "/api/config" # Update config local config_update='{ "max_file_size": "209715200", "require_auth": "true", "nip94_enabled": "true" }' send_admin_request "PUT" "/api/config" "$config_update" # Get config again to verify send_admin_request "GET" "/api/config" } test_files_endpoint() { log_info "=== Testing Files Endpoint ===" send_admin_request "GET" "/api/files?limit=10&offset=0" } configure_server_admin() { log_warning "=== Server Configuration Required ===" log_warning "To use this admin interface, add the following to your ginxsom database:" log_warning "" log_warning "sqlite3 db/ginxsom.db << EOF" log_warning "INSERT OR REPLACE INTO server_config (key, value, description) VALUES" log_warning " ('admin_pubkey', '$ADMIN_PUBKEY', 'Nostr public key authorized for admin operations')," log_warning " ('admin_enabled', 'true', 'Enable admin interface');" log_warning "EOF" log_warning "" log_warning "Then restart ginxsom server." echo "" log_warning "Or use the Nak utility to interact with the API:" echo "" log_warning " # Create an event" echo " EVENT=\$(nak event -k 24242 -c 'admin_request' --tag t='GET' --tag expiration=\$(date -d '+1 hour' +%s) --sec '$ADMIN_PRIVKEY')" echo "" log_warning " # Send authenticated request" echo " curl -H \"Authorization: Nostr \$(echo \"\$EVENT\" | base64 -w 0)\" http://localhost:9001/api/stats" echo "" } main() { echo "=== Ginxsom Admin API Test Suite ===" echo "" check_dependencies generate_admin_keys # Setup admin configuration automatically echo "" log_info "Setting up admin configuration..." ./tests/init_admin.sh echo "" # Test endpoints test_health_endpoint echo "" test_stats_endpoint echo "" test_config_endpoints echo "" test_files_endpoint echo "" log_success "Admin API testing complete!" log_info "Admin pubkey for server config: $ADMIN_PUBKEY" } # Allow sourcing for individual function testing if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi