c9f1437860
CI / backend (pull_request) Has been cancelled
CI / frontend (pull_request) Has been cancelled
CI / format (pull_request) Has been cancelled
CI / db-tests (pull_request) Has been cancelled
Security / secrets (pull_request) Successful in 6s
Security / dependencies (pull_request) Successful in 1m12s
Security / sast (pull_request) Failing after 5s
The SPA nginx overwrote the reverse proxy's X-Forwarded-Proto with $scheme (http on the traefik->frontend hop), so the API built http:// OAuth redirects that Google rejects. Map the incoming proto through (fallback to $scheme for direct access). Needed for login via https://inboxintel.cesnimda.uk behind traefik. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.2 KiB
Nginx Configuration File
54 lines
2.2 KiB
Nginx Configuration File
# Honor a reverse proxy's X-Forwarded-Proto (e.g. traefik terminating TLS) so the API sees
|
|
# https and builds https OAuth redirects; fall back to the connection scheme for direct access.
|
|
map $http_x_forwarded_proto $fwd_proto {
|
|
default $scheme;
|
|
https https;
|
|
http http;
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# AUDIT M-2: security headers on the SPA. script-src 'self' works because the theme
|
|
# bootstrap lives in /theme-init.js (no inline scripts); style-src needs 'unsafe-inline'
|
|
# for React/Chart.js/grid-layout inline style attributes (low risk with script-src locked).
|
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-Frame-Options "DENY" always;
|
|
add_header Referrer-Policy "no-referrer" always;
|
|
|
|
# Compress the SPA bundle (AUDIT perf note: ~680 KB JS).
|
|
gzip on;
|
|
gzip_types text/css application/javascript application/json image/svg+xml;
|
|
gzip_min_length 1024;
|
|
|
|
# SPA fallback.
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Proxy API + auth calls to the backend container.
|
|
location /api/ {
|
|
proxy_pass http://api:8080;
|
|
proxy_set_header Host $http_host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $fwd_proto;
|
|
proxy_set_header X-Forwarded-Host $http_host;
|
|
proxy_set_header Cookie $http_cookie;
|
|
}
|
|
|
|
# Google OAuth2 callback + sign-out land here (not under /api) and must
|
|
# reach the backend so the cookie session is established same-origin.
|
|
location ~ ^/(signin-google|signout-google) {
|
|
proxy_pass http://api:8080;
|
|
proxy_set_header Host $http_host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $fwd_proto;
|
|
proxy_set_header X-Forwarded-Host $http_host;
|
|
proxy_set_header Cookie $http_cookie;
|
|
}
|
|
}
|