# SPDX-FileCopyrightText: 2026 Progmasoft # SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.0 server { listen 443 ssl; listen [::]:443 ssl; server_name xsharp-lang.xyz docs.xsharp-lang.xyz spec.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; # Registry pages are built in the same static artifact but belong only to # viget.progmasoft.com. The language host must never expose auth surfaces. location = /repo { return 404; } location ^~ /repo/ { return 404; } location / { try_files $uri $uri/ =404; } location ~ /\. { deny all; } } server { listen 80; listen [::]:80; server_name viget.progmasoft.com; server_tokens off; location ^~ /.well-known/acme-challenge/ { root /var/lib/letsencrypt; default_type text/plain; } location / { return 301 https://viget.progmasoft.com$request_uri; } } 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.progmasoft.com; root /srv/xsharp/website/current/frontend/repo; index index.html; server_tokens off; ssl_certificate /etc/letsencrypt/live/progmasoft.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/progmasoft.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; include /etc/nginx/snippets/repository-security-headers.conf; location = /login { return 308 https://account.progmasoft.com/login$is_args$args; } location = /login/ { return 308 https://account.progmasoft.com/login$is_args$args; } location = /register { return 308 https://account.progmasoft.com/register$is_args$args; } location = /register/ { return 308 https://account.progmasoft.com/register$is_args$args; } location = /recover { return 308 https://account.progmasoft.com/recover$is_args$args; } location = /recover/ { return 308 https://account.progmasoft.com/recover$is_args$args; } location = /dashboard { return 308 https://account.progmasoft.com/$is_args$args; } location = /dashboard/ { return 308 https://account.progmasoft.com/$is_args$args; } location = /api/v1/status { proxy_http_version 1.1; proxy_pass http://127.0.0.1:5080; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Real-IP $remote_addr; } # Account registration and registry-token ownership use the canonical # Progmasoft Account service. ViGet does not expose its retired auth API. location ^~ /api/ { return 404; } location /_astro/ { alias /srv/xsharp/website/current/frontend/_astro/; include /etc/nginx/snippets/repository-security-headers.conf; add_header Cache-Control "public, max-age=31536000, immutable"; } location /fonts/ { alias /srv/xsharp/website/current/frontend/fonts/; include /etc/nginx/snippets/repository-security-headers.conf; add_header Cache-Control "public, max-age=31536000, immutable"; } location /scripts/ { alias /srv/xsharp/website/current/frontend/scripts/; include /etc/nginx/snippets/repository-security-headers.conf; add_header Cache-Control "public, max-age=3600"; } location = /xsharp-logo.png { alias /srv/xsharp/website/current/frontend/xsharp-logo.png; } location = /xsharp-logo.webp { alias /srv/xsharp/website/current/frontend/xsharp-logo.webp; } location = /progmasoft-mark.svg { alias /srv/xsharp/website/current/frontend/progmasoft-mark.svg; } location / { include /etc/nginx/snippets/repository-security-headers.conf; add_header Cache-Control "private, no-store"; try_files $uri $uri/ =404; } location ~ /\. { deny all; } } 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; 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; }