#!/bin/bash # # cors-probe.sh # Zyquo Cloud Web # # Author: Simon-Pierre Boucher # Mail: contact@spboucher.ai # # Phase 0.A — empirical CORS probe for all 12 providers. # For each provider: (1) OPTIONS preflight as a browser would send it, # (2) a real minimal POST with an Origin header, checking the # Access-Control-Allow-* response headers. Keys are read from # .keys.local.json (gitignored) and never printed. # set -u KEYS_FILE="$(dirname "$0")/../.keys.local.json" ORIGIN="https://www.zyquo.cloud" OUT_DIR="${1:-/tmp/zyquo-cors}" mkdir -p "$OUT_DIR" key() { python3 -c "import json,sys; print(json.load(open('$KEYS_FILE'))['$1'])"; } probe() { local name="$1" url="$2" auth_header="$3" model="$4" extra_header="${5:-}" local out="$OUT_DIR/$name.txt" { echo "=== $name — $url ===" echo "--- PREFLIGHT (OPTIONS) ---" local req_headers="authorization,content-type" [ "$name" = "anthropic" ] && req_headers="x-api-key,anthropic-version,anthropic-dangerous-direct-browser-access,content-type" curl -sS -o /dev/null -D - -X OPTIONS "$url" \ -H "Origin: $ORIGIN" \ -H "Access-Control-Request-Method: POST" \ -H "Access-Control-Request-Headers: $req_headers" \ --max-time 30 2>&1 | grep -iE "^(HTTP|access-control|allow)" || echo "(no CORS headers in preflight)" echo "--- POST with Origin ---" local body='{"model":"'"$model"'","messages":[{"role":"user","content":"Say OK"}],"max_tokens":8}' [ "$name" = "anthropic" ] && body='{"model":"'"$model"'","max_tokens":8,"messages":[{"role":"user","content":"Say OK"}]}' curl -sS -o "$OUT_DIR/$name.body.json" -D - -X POST "$url" \ -H "Origin: $ORIGIN" \ -H "Content-Type: application/json" \ -H "$auth_header" \ ${extra_header:+-H "$extra_header"} \ -d "$body" \ --max-time 60 2>&1 | grep -iE "^(HTTP|access-control)" || echo "(no CORS headers in POST)" echo "--- POST body (first 300 chars) ---" head -c 300 "$OUT_DIR/$name.body.json"; echo } > "$out" 2>&1 echo "done: $name" } probe openai "https://api.openai.com/v1/chat/completions" "Authorization: Bearer $(key openai)" "gpt-4.1-nano" & probe anthropic "https://api.anthropic.com/v1/messages" "x-api-key: $(key anthropic)" "claude-haiku-4-5-20251001" "anthropic-version: 2023-06-01" & probe xai "https://api.x.ai/v1/chat/completions" "Authorization: Bearer $(key xai)" "grok-3-mini" & probe mistral "https://api.mistral.ai/v1/chat/completions" "Authorization: Bearer $(key mistral)" "mistral-small-latest" & probe gemini "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions" "Authorization: Bearer $(key gemini)" "gemini-2.5-flash-lite" & probe qwen "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions" "Authorization: Bearer $(key qwen)" "qwen-turbo" & probe deepseek "https://api.deepseek.com/chat/completions" "Authorization: Bearer $(key deepseek)" "deepseek-chat" & probe kimi "https://api.moonshot.ai/v1/chat/completions" "Authorization: Bearer $(key kimi)" "kimi-k2-0711-preview" & probe perplexity "https://api.perplexity.ai/chat/completions" "Authorization: Bearer $(key perplexity)" "sonar" & probe together "https://api.together.xyz/v1/chat/completions" "Authorization: Bearer $(key together)" "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo" & probe deepinfra "https://api.deepinfra.com/v1/openai/chat/completions" "Authorization: Bearer $(key deepinfra)" "meta-llama/Meta-Llama-3.1-8B-Instruct" & probe cerebras "https://api.cerebras.ai/v1/chat/completions" "Authorization: Bearer $(key cerebras)" "llama3.1-8b" & wait echo "All probes complete → $OUT_DIR"