diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 7f42553f..aa905ced 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -13,6 +13,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + # Rebuild the assistant search index from the CURRENT content so it is + # always in sync — no manual step needed when pages change. + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Rebuild assistant search index + run: | + python -m pip install --quiet beautifulsoup4 + python tools/build_search_index.py + - name: Deploy to Server via rsync run: | mkdir -p ~/.ssh @@ -23,6 +35,13 @@ jobs: --exclude=".git/" \ --exclude=".gitea/" \ --exclude=".gitignore" \ + --exclude="README.md" \ + --exclude="*.sh" \ + --exclude="*.py" \ + --exclude="code_export.txt" \ + --exclude="docs/" \ + --exclude="templates/" \ + --exclude="tools/" \ -e "ssh -p ${{ secrets.SSH_PORT }} -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \ ./ \ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.TARGET_DIR }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index e74c4c3c..14910d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .venv/ images/original/ .playwright-mcp/ +code_export.txt diff --git a/.htaccess b/.htaccess index 7d74951a..d36aa188 100644 --- a/.htaccess +++ b/.htaccess @@ -1,8 +1,28 @@ RewriteEngine on -RewriteCond %{HTTP_HOST} ^msos\.spletnimojster\.si$ [OR] -RewriteCond %{HTTP_HOST} ^www\.msos\.spletnimojster\.si$ -RewriteRule ^/?$ "https\:\/\/msos\.spletnimojster\.si\/en\/" [R=301,L] + +# ----- Canonical domain + language root ----- +# Migrate the old host to the canonical domain, preserving the path. +RewriteCond %{HTTP_HOST} ^(www\.)?msos\.spletnimojster\.si$ [NC] +RewriteRule ^ https://msosorg.com%{REQUEST_URI} [R=301,L] +# Send the bare root to the default-language homepage. +RewriteRule ^/?$ https://msosorg.com/en/ [R=301,L] + +# ----- Defense-in-depth: block dev/sensitive files if they ever ship ----- +# (The deploy already excludes these; this is a safety net. robots.txt, +# sitemap.xml and site.webmanifest are intentionally NOT blocked.) + + + Require all denied + + + Order allow,deny + Deny from all + + +# Block internal folders and VCS/CI dirs. +RewriteRule (^|/)\.(git|gitea)(/|$) - [F,L] +RewriteRule ^(docs|templates|tools)(/|$) - [F,L] # ============================================================ @@ -52,6 +72,15 @@ Options -Indexes Header set X-Content-Type-Options "nosniff" + # Clickjacking protection — the site should never be framed by other origins. + Header always set X-Frame-Options "SAMEORIGIN" + # Don't leak full page URLs to third parties (analytics, external links). + Header always set Referrer-Policy "strict-origin-when-cross-origin" + # Explicitly disable browser features the site doesn't use. + Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" + # Content-Security-Policy in REPORT-ONLY first so it cannot break styling/scripts. + # Review browser console for violations, tighten, then switch to Content-Security-Policy. + Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com https://region1.google-analytics.com; frame-src https://www.youtube-nocookie.com https://www.youtube.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self' https://docs.google.com" Header set Cache-Control "no-cache, must-revalidate" diff --git a/404.html b/404.html index 0bb6590c..fcb147da 100644 --- a/404.html +++ b/404.html @@ -50,7 +50,7 @@ - + 404 error Page not found The page you're looking for doesn't exist or may have moved. Let's get you back on track. @@ -70,5 +70,7 @@ + +
404 error
The page you're looking for doesn't exist or may have moved. Let's get you back on track.