From d738352c904da0f788af69bfc04e7be8eac41a4e Mon Sep 17 00:00:00 2001 From: Koala <6156589+Shik3i@users.noreply.github.com> Date: Mon, 1 Jun 2026 00:21:29 +0200 Subject: [PATCH] feat(website): implement Clean URLs and split Caddy configurations - Removed all .html file extension suffixes from website and invite links (impressum, datenschutz, join). - Updated app.js dynamic localizer and path switching to target Clean URLs ('./', '../', etc.). - Refactored Caddyfile.example into simple (lightweight try_files) and advanced (hardened production) options. - Split Caddy configs into Caddyfile (Simple) and Caddyfile (Advanced) tabs on the landing page. --- Caddyfile.example | 75 +++++++++++++++++++++++++++--------- website/app.js | 14 +++---- website/datenschutz.html | 8 ++-- website/impressum.html | 8 ++-- website/join.html | 10 ++--- website/template.html | 55 +++++++++++++++++++++----- website/www/app.js | 14 +++---- website/www/datenschutz.html | 8 ++-- website/www/de/index.html | 55 +++++++++++++++++++++----- website/www/es/index.html | 55 +++++++++++++++++++++----- website/www/fr/index.html | 55 +++++++++++++++++++++----- website/www/impressum.html | 8 ++-- website/www/index.html | 55 +++++++++++++++++++++----- website/www/join.html | 10 ++--- website/www/pt-BR/index.html | 55 +++++++++++++++++++++----- website/www/ru/index.html | 55 +++++++++++++++++++++----- 16 files changed, 411 insertions(+), 129 deletions(-) diff --git a/Caddyfile.example b/Caddyfile.example index 9b45c3d..e7395eb 100644 --- a/Caddyfile.example +++ b/Caddyfile.example @@ -1,11 +1,44 @@ +# ============================================================================== # KoalaSync - Production Caddy Configuration Example -# Replace domains and paths with your actual setup. +# ============================================================================== +# This file provides examples of both a lightweight "Simple" configuration +# and a production-hardened "Advanced" configuration. +# Replace domains, reverse proxy locations, and directories with your actual setup. + +# ------------------------------------------------------------------------------ +# OPTION A: Simple Configuration +# ------------------------------------------------------------------------------ +# Minimal configuration that serves the static website, enables gzip compression, +# supports extension-less Clean URLs, and reverse proxies the relay server. + +# sync.koalastuff.net { +# root * /var/www/koalasync/website/www +# encode zstd gzip +# +# # Clean URLs support (resolves /join to join.html, etc.) +# try_files {path} {path}.html {path}/ +# file_server +# } +# +# syncserver.koalastuff.net { +# reverse_proxy localhost:3000 +# } + + +# ------------------------------------------------------------------------------ +# OPTION B: Advanced Configuration (Production-Hardened) +# ------------------------------------------------------------------------------ +# Highly secure, optimized configuration using advanced HTTP security headers, +# aggressive static assets caching, server signature concealment, and strict +# hardware permission access policies. -# 1. Marketing Website & Invitation Bridge sync.koalastuff.net { - root * /var/www/koalasync/website/www - file_server encode zstd gzip + root * /var/www/koalasync/website/www + + # Clean URLs: Resolves paths without .html in the URL + try_files {path} {path}.html {path}/ + file_server # Static Caching for high-performance PageSpeed (1 year with validation) @static { @@ -16,31 +49,35 @@ sync.koalastuff.net { # Security Headers & Content Security Policy (CSP) header { - # Strict Content Security Policy (restricts scripts and connections to self, forbids frames) - Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none';" - # Prevent FLoC tracking - Permissions-Policy interest-cohort=() - # Security best practices + # CSP hardened with base-uri and form-action limits + Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" + + # Strict Transport Security (HSTS) Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - X-Content-Type-Options nosniff - X-Frame-Options DENY - Referrer-Policy no-referrer-when-downgrade + + # Security best practices + X-Frame-Options "DENY" + X-Content-Type-Options "nosniff" + Referrer-Policy "strict-origin-when-cross-origin" + + # Modern Permissions Policy (blocks browser hardware access for enhanced privacy) + Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" + + # Remove Caddy's server stamp signature + -Server } } -# 2. Relay Server (Socket.IO / WebSocket) syncserver.koalastuff.net { reverse_proxy localhost:3000 { - # Ensure WebSocket support is explicitly handled if needed - # (Caddy usually handles this automatically) header_up Host {host} header_up X-Real-IP {remote_host} } - # Security Headers for the relay header { - X-Content-Type-Options nosniff - X-Frame-Options DENY - Referrer-Policy no-referrer + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + Referrer-Policy "strict-origin-when-cross-origin" + -Server } } diff --git a/website/app.js b/website/app.js index b52f9ae..7c0d11d 100644 --- a/website/app.js +++ b/website/app.js @@ -194,7 +194,7 @@ document.addEventListener('DOMContentLoaded', () => { inviteSpan.appendChild(document.createTextNode(' detected!')); const joinLink = document.createElement('a'); - joinLink.href = 'join.html' + window.location.hash; + joinLink.href = 'join' + window.location.hash; joinLink.className = 'btn-banner'; joinLink.textContent = 'OPEN JOIN PAGE'; @@ -454,9 +454,9 @@ document.addEventListener('DOMContentLoaded', () => { // Only need to do this dynamic rewrite if we are NOT already inside a localized subdirectory if (!isSubdir) { - const homeLinks = document.querySelectorAll('a[href="index.html"], a[href="de/index.html"], a[href="fr/index.html"], a[href="es/index.html"], a[href="pt-BR/index.html"], a[href="ru/index.html"]'); + const homeLinks = document.querySelectorAll('a[href="./"], a[href="de/"], a[href="fr/"], a[href="es/"], a[href="pt-BR/"], a[href="ru/"]'); homeLinks.forEach(link => { - link.href = (activeLang === 'en') ? 'index.html' : `${activeLang}/index.html`; + link.href = (activeLang === 'en') ? './' : `${activeLang}/`; }); } }; @@ -482,17 +482,17 @@ document.addEventListener('DOMContentLoaded', () => { let targetPath; if (newLang === 'en') { if (isSubdir) { - targetPath = '../index.html'; + targetPath = '../'; } else { - targetPath = 'index.html'; + targetPath = './'; } } else { if (isSubdir) { // Switching from one language subdirectory to another (e.g., /de/ to /fr/) - targetPath = '../' + newLang + '/index.html'; + targetPath = '../' + newLang + '/'; } else { // Switching from root (English) to a language subdirectory (e.g., / to /fr/) - targetPath = newLang + '/index.html'; + targetPath = newLang + '/'; } } diff --git a/website/datenschutz.html b/website/datenschutz.html index 1792381..ec1d53d 100644 --- a/website/datenschutz.html +++ b/website/datenschutz.html @@ -25,13 +25,13 @@