# SPDX-FileCopyrightText: 2026 Progmasoft # SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 server { listen 80 default_server; listen [::]:80 default_server; server_name xsharp-unmatched.invalid; server_tokens off; return 444; } server { listen 80; listen [::]:80; server_name xsharp-lang.xyz www.xsharp-lang.xyz docs.xsharp-lang.xyz spec.xsharp-lang.xyz; server_tokens off; location ^~ /.well-known/acme-challenge/ { root /var/lib/letsencrypt; default_type text/plain; } location / { return 308 https://xsharp-lang.xyz$request_uri; } } server { listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; server_tokens off; ssl_reject_handshake on; } server { listen 443 ssl; listen [::]:443 ssl; server_name xsharp-lang.xyz; root /srv/xsharp/website/current/frontend; index index.html; server_tokens off; ssl_certificate /etc/letsencrypt/live/xsharp-lang.xyz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/xsharp-lang.xyz/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; # Keep retired registry paths closed on the language host. Accounts and # packages belong to separate Progmasoft services, not this Vue artifact. location = /repo { return 404; } location ^~ /repo/ { return 404; } # Only the language site's own public metadata crosses into Spring. # A catch-all /api proxy would accidentally expose legacy registry routes. location = /api/v1/site { proxy_pass http://127.0.0.1:5086/api/v1/site; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 2s; proxy_read_timeout 5s; } location ^~ /api/ { return 404; } location / { # Vue Router uses history URLs; real files still win before the app shell. try_files $uri $uri/ /index.html; } location ~ /\. { deny all; } } server { listen 80; listen [::]:80; server_name viget.xsharp-lang.xyz; server_tokens off; location ^~ /.well-known/acme-challenge/ { root /var/lib/letsencrypt; default_type text/plain; } location / { return 308 https://viget.progmasoft.com$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; server_name viget.xsharp-lang.xyz; server_tokens off; ssl_certificate /etc/letsencrypt/live/xsharp-lang.xyz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/xsharp-lang.xyz/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; return 308 https://viget.progmasoft.com$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name www.xsharp-lang.xyz docs.xsharp-lang.xyz spec.xsharp-lang.xyz; server_tokens off; ssl_certificate /etc/letsencrypt/live/xsharp-lang.xyz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/xsharp-lang.xyz/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; return 308 https://xsharp-lang.xyz$request_uri; }