# /etc/nginx/sites-available/cioclub  (provision-ubuntu.sh fills in __DOMAIN__ and __ROOT__)
limit_req_zone $binary_remote_addr zone=cio_login:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=cio_general:10m rate=20r/s;

server {
    listen 80;
    listen [::]:80;
    server_name __DOMAIN__;
    location /.well-known/acme-challenge/ { root /var/www/letsencrypt; }
    location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name __DOMAIN__;
    root __ROOT__/current/public;
    index index.php;

    ssl_certificate     /etc/letsencrypt/live/__DOMAIN__/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/__DOMAIN__/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;

    server_tokens off;
    client_max_body_size 20M;
    client_body_timeout 30s;
    keepalive_timeout 30s;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Never serve dotfiles or anything outside public/ (config, lib, sql, storage live above the web root).
    location ~ /\.(?!well-known) { deny all; return 404; }

    # Uploads: static only, never executed, never sniffed.
    location ^~ /uploads/ {
        location ~ \.(php|phtml|phar|pl|py|sh|cgi)$ { deny all; return 404; }
        add_header X-Content-Type-Options nosniff always;
        add_header Cache-Control "public, max-age=2592000";
        try_files $uri =404;
    }
    location ^~ /assets/ {
        add_header Cache-Control "public, max-age=2592000, immutable";
        try_files $uri =404;
    }
    location = /sw.js { add_header Cache-Control "no-cache"; try_files $uri =404; }

    location ~ ^/[a-z]{2}/(login|login/2fa|forgot|reset|join)$ {
        limit_req zone=cio_login burst=10 nodelay;
        try_files $uri /index.php?$query_string;
    }
    location / {
        limit_req zone=cio_general burst=60 nodelay;
        try_files $uri /index.php?$query_string;
    }

    # Only the front controller runs PHP.
    location = /index.php {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param HTTPS on;
        fastcgi_pass unix:/run/php/php8.3-fpm-cioclub.sock;
        fastcgi_read_timeout 120s;
    }
    location ~ \.php$ { return 404; }

    access_log /var/log/nginx/cioclub.access.log;
    error_log  /var/log/nginx/cioclub.error.log warn;
}
