ploughshares/test_headers.sh

140 lines
4.1 KiB
Bash
Executable File

#!/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