diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..4f05b9d --- /dev/null +++ b/config.yaml @@ -0,0 +1,10 @@ +debug: true +port: 8080 +state_dir: ./data +signing_key: "test-signing-key-for-development-only" +whitelist_hosts: + - "*.example.com" + - "images.unsplash.com" + - "picsum.photos" + - "s3.sneak.cloud" +allow_http: false diff --git a/scripts/manual-test.sh b/scripts/manual-test.sh new file mode 100755 index 0000000..86dddfb --- /dev/null +++ b/scripts/manual-test.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# +# Manual test script for pixa server +# Requires: server running on localhost:8080 +# +set -e + +BASE_URL="${BASE_URL:-http://localhost:8080}" +SIGNING_KEY="${SIGNING_KEY:-test-signing-key-for-development-only}" +TEST_IMAGE_URL="https://s3.sneak.cloud/sneak-public/2021/2021-04-18.untitled.a7r4.07723.jpg" +COOKIE_JAR=$(mktemp) + +cleanup() { + rm -f "$COOKIE_JAR" +} +trap cleanup EXIT + +pass() { + echo "✓ PASS: $1" +} + +fail() { + echo "✗ FAIL: $1" + exit 1 +} + +echo "=== Pixa Manual Test Suite ===" +echo "Base URL: $BASE_URL" +echo "" + +# Test 1: Healthcheck +echo "--- Test 1: Healthcheck endpoint ---" +HEALTH=$(curl -sf "$BASE_URL/.well-known/healthcheck.json") +if echo "$HEALTH" | grep -q '"status"'; then + pass "Healthcheck returns status" +else + fail "Healthcheck did not return expected response" +fi + +# Test 2: Login page displays +echo "--- Test 2: Login page (GET /) ---" +LOGIN_PAGE=$(curl -sf "$BASE_URL/") +if echo "$LOGIN_PAGE" | grep -qi "password\|login\|sign"; then + pass "Login page displays password form" +else + fail "Login page did not display expected content" +fi + +# Test 3: Wrong password shows error +echo "--- Test 3: Login with wrong password ---" +WRONG_LOGIN=$(curl -sf -X POST "$BASE_URL/" -d "password=wrong-key" -c "$COOKIE_JAR") +if echo "$WRONG_LOGIN" | grep -qi "invalid\|error\|incorrect\|wrong"; then + pass "Wrong password shows error message" +else + fail "Wrong password did not show error" +fi + +# Test 4: Correct password redirects to generator +echo "--- Test 4: Login with correct signing key ---" +curl -sf -X POST "$BASE_URL/" -d "password=$SIGNING_KEY" -c "$COOKIE_JAR" -b "$COOKIE_JAR" -L -o /dev/null +GENERATOR_PAGE=$(curl -sf "$BASE_URL/" -b "$COOKIE_JAR") +if echo "$GENERATOR_PAGE" | grep -qi "generate\|url\|source\|logout"; then + pass "Correct password shows generator page" +else + fail "Generator page not displayed after login" +fi + +# Test 5: Generate encrypted URL +echo "--- Test 5: Generate encrypted URL ---" +GEN_RESULT=$(curl -sf -X POST "$BASE_URL/generate" -b "$COOKIE_JAR" \ + -d "source_url=$TEST_IMAGE_URL" \ + -d "width=800" \ + -d "height=600" \ + -d "format=jpeg" \ + -d "quality=85" \ + -d "fit_mode=cover" \ + -d "ttl=3600") +if echo "$GEN_RESULT" | grep -q "/v1/e/"; then + pass "Encrypted URL generated" + # Extract the encrypted URL + ENC_URL=$(echo "$GEN_RESULT" | grep -o '/v1/e/[^"<]*' | head -1) + echo " Generated URL: $ENC_URL" +else + fail "Failed to generate encrypted URL" +fi + +# Test 6: Fetch image via encrypted URL +echo "--- Test 6: Fetch image via encrypted URL ---" +if [ -n "$ENC_URL" ]; then + HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" "$BASE_URL$ENC_URL") + if [ "$HTTP_CODE" = "200" ]; then + pass "Encrypted URL returns image (HTTP 200)" + else + fail "Encrypted URL returned HTTP $HTTP_CODE" + fi +else + fail "No encrypted URL to test" +fi + +# Test 7: Fetch image via whitelisted host (direct proxy) +echo "--- Test 7: Fetch image via direct proxy (whitelisted host) ---" +# URL format: /v1/image///. +PROXY_PATH="/v1/image/s3.sneak.cloud/sneak-public/2021/2021-04-18.untitled.a7r4.07723.jpg/400x300.jpeg" +HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" "$BASE_URL$PROXY_PATH") +if [ "$HTTP_CODE" = "200" ]; then + pass "Direct proxy returns image (HTTP 200)" +else + fail "Direct proxy returned HTTP $HTTP_CODE" +fi + +# Test 8: Logout +echo "--- Test 8: Logout ---" +curl -sf "$BASE_URL/logout" -b "$COOKIE_JAR" -c "$COOKIE_JAR" -L -o /dev/null +AFTER_LOGOUT=$(curl -sf "$BASE_URL/" -b "$COOKIE_JAR") +if echo "$AFTER_LOGOUT" | grep -qi "password\|login"; then + pass "Logout redirects to login page" +else + fail "Logout did not redirect to login" +fi + +# Test 9: Generate short-TTL URL and verify expiration +echo "--- Test 9: Expired URL returns 410 ---" +# Login again +curl -sf -X POST "$BASE_URL/" -d "password=$SIGNING_KEY" -c "$COOKIE_JAR" -b "$COOKIE_JAR" -L -o /dev/null +# Generate URL with 1 second TTL +GEN_RESULT=$(curl -sf -X POST "$BASE_URL/generate" -b "$COOKIE_JAR" \ + -d "source_url=$TEST_IMAGE_URL" \ + -d "width=100" \ + -d "height=100" \ + -d "format=jpeg" \ + -d "ttl=1") +SHORT_URL=$(echo "$GEN_RESULT" | grep -o '/v1/e/[^"<]*' | head -1) +if [ -n "$SHORT_URL" ]; then + echo " Waiting 2 seconds for URL to expire..." + sleep 2 + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL$SHORT_URL") + if [ "$HTTP_CODE" = "410" ]; then + pass "Expired URL returns 410 Gone" + else + fail "Expired URL returned HTTP $HTTP_CODE (expected 410)" + fi +else + fail "Could not generate short-TTL URL" +fi + +echo "" +echo "=== All tests passed! ==="