diff --git a/openresty/nginx.conf b/openresty/nginx.conf index 243e284..a536d7b 100644 --- a/openresty/nginx.conf +++ b/openresty/nginx.conf @@ -789,6 +789,87 @@ http { add_header Cache-Control "no-store, no-cache" always; } + # Public pyramid endpoints - no authentication required for canvas loading + location ~ ^/api/pyramid/(state|colors)$ { + limit_req zone=api_limit burst=20 nodelay; + + # CORS headers + add_header Access-Control-Allow-Origin $cors_origin always; + add_header Access-Control-Allow-Methods "GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "Content-Type" always; + add_header Access-Control-Allow-Credentials "true" always; + + if ($request_method = 'OPTIONS') { + add_header Content-Length 0; + add_header Content-Type text/plain; + return 204; + } + + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Short cache for pyramid state + expires 5s; + add_header Cache-Control "public, max-age=5" always; + } + + # Public pyramid face endpoints + location ~ ^/api/pyramid/face/[0-4]$ { + limit_req zone=api_limit burst=20 nodelay; + + # CORS headers + add_header Access-Control-Allow-Origin $cors_origin always; + add_header Access-Control-Allow-Methods "GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "Content-Type" always; + add_header Access-Control-Allow-Credentials "true" always; + + if ($request_method = 'OPTIONS') { + add_header Content-Length 0; + add_header Content-Type text/plain; + return 204; + } + + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Short cache for face data + expires 5s; + add_header Cache-Control "public, max-age=5" always; + } + + # Public pyramid pixel info endpoint + location ~ ^/api/pyramid/pixel/[0-4]/[0-9]+/[0-9]+$ { + limit_req zone=api_limit burst=20 nodelay; + + # CORS headers + add_header Access-Control-Allow-Origin $cors_origin always; + add_header Access-Control-Allow-Methods "GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "Content-Type" always; + add_header Access-Control-Allow-Credentials "true" always; + + if ($request_method = 'OPTIONS') { + add_header Content-Length 0; + add_header Content-Type text/plain; + return 204; + } + + proxy_pass http://backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # No cache for pixel info + expires -1; + add_header Cache-Control "no-store, no-cache" always; + } + # Other API endpoints (authenticated) location /api/ { limit_req zone=api_limit burst=20 nodelay;