#!/bin/bash set -Eeuo pipefail # Colors for better readability GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[0;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color FAILURES=0 fail() { echo -e "${RED}✗ $1${NC}" FAILURES=$((FAILURES+1)) } pass() { echo -e "${GREEN}✓ $1${NC}" } require_header() { local headers=$1 local name=$2 local pattern=${3:-} if ! echo "$headers" | grep -qi "^$name:"; then fail "$name header not found" return fi if [ -n "$pattern" ]; then if ! echo "$headers" | grep -i "^$name:" | grep -qiE "$pattern"; then fail "$name does not match expected pattern: $pattern" return fi fi pass "$name present" } require_header_absent() { local headers=$1 local name=$2 if echo "$headers" | grep -qi "^$name:"; then fail "$name should be absent" else pass "$name absent as expected" fi } assert_http_status() { local url=$1 local expected=$2 local code code=$(curl -s -o /dev/null -w "%{http_code}" -I "$url") if [ "$code" != "$expected" ]; then fail "HTTP status for $url expected $expected, got $code" else pass "HTTP $expected for $url" fi } # Base URLs to test DEV_URL="http://localhost:5005" PROD_URL="https://ploughshares.nixc.us" # Default to development URL unless specified URL=${1:-$DEV_URL} echo -e "${BLUE}Testing headers for ${URL}${NC}" echo "==================================================" test_headers() { local endpoint=$1 local description=$2 local full_url="${URL}${endpoint}" echo -e "\n${YELLOW}Testing headers for ${description} (${endpoint})${NC}" echo "------------------------------------------------" assert_http_status "$full_url" 200 headers=$(curl -s -I "$full_url") echo -e "${BLUE}All Headers:${NC}" echo "$headers" | grep -v "Date:" | grep -v "Server:" # Common expectations require_header "$headers" "Content-Security-Policy" require_header "$headers" "Referrer-Policy" require_header "$headers" "X-Frame-Options" require_header "$headers" "X-Content-Type-Options" if [[ "$endpoint" == "/api/"* ]]; then # API expectations (CORS enabled, CORP cross-origin, COEP absent) require_header "$headers" "Access-Control-Allow-Origin" "\*" require_header "$headers" "Access-Control-Allow-Methods" require_header "$headers" "Access-Control-Allow-Headers" require_header "$headers" "Cross-Origin-Resource-Policy" "cross-origin" require_header_absent "$headers" "Cross-Origin-Embedder-Policy" else # UI expectations (no CORS headers, CORP same-origin, COEP unsafe-none) require_header "$headers" "Cross-Origin-Resource-Policy" "same-origin" require_header "$headers" "Cross-Origin-Embedder-Policy" "unsafe-none" if echo "$headers" | grep -qi "^Access-Control-Allow-Origin:"; then fail "Access-Control-Allow-Origin should not be present on UI routes" else pass "No CORS headers on UI routes" fi fi echo "------------------------------------------------" } # Test UI endpoint test_headers "/" "Main UI page" # Test API endpoint test_headers "/api/test" "API test endpoint" # OPTIONS preflight check echo -e "\n${YELLOW}Testing OPTIONS request for CORS preflight${NC}" echo "------------------------------------------------" preflight_code=$(curl -s -o /dev/null -w "%{http_code}" -X OPTIONS -I "${URL}/api/test") if [ "$preflight_code" != "200" ]; then fail "OPTIONS /api/test expected 200, got $preflight_code" else pass "OPTIONS /api/test returns 200" fi preflight_headers=$(curl -s -X OPTIONS -I "${URL}/api/test") require_header "$preflight_headers" "Access-Control-Allow-Origin" "\*" require_header "$preflight_headers" "Access-Control-Allow-Methods" require_header "$preflight_headers" "Access-Control-Allow-Headers" echo "------------------------------------------------" if [ "$FAILURES" -gt 0 ]; then echo -e "${RED}Header tests failed: $FAILURES issue(s).${NC}" exit 1 else echo -e "${GREEN}All header tests passed.${NC}" fi