#!/bin/bash
# Verify pentest remediation fixes on the live server.
# Exit 0 = all checks pass, Exit 1 = one or more failures.
# Usage: ./scripts/verify-pentest-fixes.sh [host] [password]

set -euo pipefail

HOST="${1:-192.168.1.228}"
PASSWORD="${2:-EwPDR8q45l0Upx@}"
BACKEND="http://$HOST:5678"
NGINX="http://$HOST"
PASS=0
FAIL=0

green() { printf "\033[32m  PASS\033[0m %s\n" "$1"; PASS=$((PASS+1)); }
red()   { printf "\033[31m  FAIL\033[0m %s\n" "$1"; FAIL=$((FAIL+1)); }
check() { if [ "$1" = "true" ]; then green "$2"; else red "$2"; fi; }

echo "============================================"
echo "  Pentest Fix Verification — $HOST"
echo "============================================"
echo ""

# --- Login and get session cookie ---
echo "--- Authentication ---"
LOGIN_RESP=$(curl -sv -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -d "{\"method\":\"auth.login\",\"params\":{\"password\":\"$PASSWORD\"}}" 2>&1)

COOKIE=$(echo "$LOGIN_RESP" | grep -i "set-cookie" | sed 's/.*session=//;s/;.*//' | head -1)
LOGIN_OK=$(echo "$LOGIN_RESP" | tail -1 | grep -q '"error":null' && echo true || echo false)
COOKIE_SET=$([ ${#COOKIE} -gt 10 ] && echo true || echo false)

check "$LOGIN_OK" "AUTH-001: Login returns success"
check "$COOKIE_SET" "AUTH-001: Login sets HttpOnly session cookie (len=${#COOKIE})"

HTTPONLY=$(echo "$LOGIN_RESP" | grep -i "set-cookie" | grep -qi "httponly" && echo true || echo false)
SAMESITE=$(echo "$LOGIN_RESP" | grep -i "set-cookie" | grep -qi "samesite" && echo true || echo false)
check "$HTTPONLY" "AUTH-001: Cookie has HttpOnly flag"
check "$SAMESITE" "AUTH-001: Cookie has SameSite flag"

# --- Unauthenticated access should be blocked ---
echo ""
echo "--- Unauthenticated Access (should all be 401) ---"

for METHOD in "node.did" "node.signChallenge" "node-list-peers" "package.install" "container-list" "auth.resetOnboarding" "bitcoin.getinfo" "lnd.getinfo"; do
  CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BACKEND/rpc/v1" \
    -H 'Content-Type: application/json' \
    -d "{\"method\":\"$METHOD\",\"params\":{}}")
  check "$([ "$CODE" = "401" ] && echo true || echo false)" "AUTH-002: $METHOD without auth → $CODE"
done

# --- WebSocket without auth ---
WS_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Upgrade: websocket" -H "Connection: Upgrade" \
  -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  -H "Sec-WebSocket-Version: 13" "$BACKEND/ws/db")
check "$([ "$WS_CODE" = "401" ] && echo true || echo false)" "AUTH-007: WebSocket without auth → $WS_CODE"

# --- Container logs & LND proxy without auth ---
LOGS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$BACKEND/api/container/logs?app_id=bitcoin&lines=10")
check "$([ "$LOGS_CODE" = "401" ] && echo true || echo false)" "AUTH-012: Container logs without auth → $LOGS_CODE"

LND_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$BACKEND/proxy/lnd/v1/getinfo")
check "$([ "$LND_CODE" = "401" ] && echo true || echo false)" "AUTH-011: LND proxy without auth → $LND_CODE"

# --- Authenticated access should work ---
echo ""
echo "--- Authenticated Access (should work) ---"

DID_RESP=$(curl -s -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -H "Cookie: session=$COOKIE" \
  -d '{"method":"node.did","params":{}}')
DID_OK=$(echo "$DID_RESP" | grep -q '"did":' && echo true || echo false)
check "$DID_OK" "AUTH-002: node.did with valid session returns data"

# --- Rate limiting ---
echo ""
echo "--- Rate Limiting ---"

# Burn through rate limit window
for i in $(seq 1 5); do
  curl -s -o /dev/null -X POST "$BACKEND/rpc/v1" \
    -H 'Content-Type: application/json' \
    -d "{\"method\":\"auth.login\",\"params\":{\"password\":\"wrong$i\"}}"
done
RATE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -d '{"method":"auth.login","params":{"password":"wrong6"}}')
check "$([ "$RATE_CODE" = "429" ] && echo true || echo false)" "AUTH-003: 6th login attempt → $RATE_CODE (expect 429)"

# --- Input validation ---
echo ""
echo "--- Input Validation ---"

TRAVERSAL=$(curl -s -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -H "Cookie: session=$COOKIE" \
  -d '{"method":"package.uninstall","params":{"id":"../../tmp/evil"}}')
TRAVERSAL_BLOCKED=$(echo "$TRAVERSAL" | grep -qi "invalid" && echo true || echo false)
check "$TRAVERSAL_BLOCKED" "INJ-002: Path traversal rejected"

REGISTRY=$(curl -s -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -H "Cookie: session=$COOKIE" \
  -d '{"method":"package.install","params":{"id":"test","dockerImage":"evil.com/rootkit:latest"}}')
REGISTRY_BLOCKED=$(echo "$REGISTRY" | grep -qi "invalid" && echo true || echo false)
check "$REGISTRY_BLOCKED" "SSRF-004: Untrusted registry rejected"

PUBKEY=$(curl -s -X POST "$BACKEND/archipelago/node-message" \
  -H 'Content-Type: application/json' \
  -d '{"from_pubkey":"SPOOFED","message":"injected"}')
PUBKEY_BLOCKED=$(echo "$PUBKEY" | grep -qi "invalid" && echo true || echo false)
check "$PUBKEY_BLOCKED" "AUTH-008: Spoofed pubkey rejected"

# --- CORS ---
echo ""
echo "--- CORS ---"

CORS_HEADER=$(curl -s -D- -X POST "$BACKEND/archipelago/node-message" \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://evil.com' \
  -d '{"from_pubkey":"aaaa","message":"test"}' 2>&1 | grep -i "access-control-allow-origin" || true)
CORS_OK=$([ -z "$CORS_HEADER" ] && echo true || echo false)
check "$CORS_OK" "AUTH-009: No CORS header for evil.com origin"

# --- Nginx Security Headers ---
echo ""
echo "--- Nginx Security Headers ---"

HEADERS=$(curl -sI "$NGINX/")
for H in "X-Content-Type-Options" "X-Frame-Options" "Referrer-Policy" "Content-Security-Policy"; do
  FOUND=$(echo "$HEADERS" | grep -qi "$H" && echo true || echo false)
  check "$FOUND" "XSS-004: $H header present"
done

# --- Logout invalidation ---
echo ""
echo "--- Session Lifecycle ---"

curl -s -o /dev/null -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -H "Cookie: session=$COOKIE" \
  -d '{"method":"auth.logout","params":{}}'

POST_LOGOUT=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BACKEND/rpc/v1" \
  -H 'Content-Type: application/json' \
  -H "Cookie: session=$COOKIE" \
  -d '{"method":"node.did","params":{}}')
check "$([ "$POST_LOGOUT" = "401" ] && echo true || echo false)" "AUTH-006: Session invalid after logout → $POST_LOGOUT"

# --- Summary ---
echo ""
echo "============================================"
TOTAL=$((PASS+FAIL))
echo "  Results: $PASS/$TOTAL passed, $FAIL failed"
echo "============================================"

if [ "$FAIL" -gt 0 ]; then
  echo "VERIFICATION FAILED"
  exit 1
else
  echo "ALL CHECKS PASSED"
  exit 0
fi
