Pre-launch: security + health + a11y hardening & offline Ask MSOS assistant #10

Merged
popovskik merged 8 commits from kristijan-dev into develop 2026-08-04 00:02:42 +00:00
13 changed files with 75 additions and 22777 deletions
Showing only changes of commit 168e4ce378 - Show all commits

View File

@ -23,6 +23,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 }}

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.venv/
images/original/
.playwright-mcp/
code_export.txt

View File

@ -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.)
<FilesMatch "(?i)(^code_export\.txt$|\.(sh|py|php|bak|old|log|ini|sql|yml|yaml)$)">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order allow,deny
Deny from all
</IfModule>
</FilesMatch>
# Block internal folders and VCS/CI dirs.
RewriteRule (^|/)\.(git|gitea)(/|$) - [F,L]
RewriteRule ^(docs|templates|tools)(/|$) - [F,L]
# ============================================================
@ -52,6 +72,15 @@ Options -Indexes
</IfModule>
<IfModule mod_headers.c>
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"
<FilesMatch "\.html$">
Header set Cache-Control "no-cache, must-revalidate"
</FilesMatch>

File diff suppressed because it is too large Load Diff

View File

@ -211,8 +211,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:kristijan.popovski@msosorg.com" aria-label="Email Kristijan Popovski"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" aria-label="LinkedIn profile of Kristijan Popovski"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" aria-label="Instagram profile of Kristijan Popovski"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" rel="noopener" aria-label="LinkedIn profile of Kristijan Popovski"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" rel="noopener" aria-label="Instagram profile of Kristijan Popovski"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Kristijan Popovski</h4>
@ -225,8 +225,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:lea.janackovska@msosorg.com" aria-label="Email Lea Janachkovska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" aria-label="LinkedIn profile of Lea Janachkovska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" aria-label="Instagram profile of Lea Janachkovska"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" rel="noopener" aria-label="LinkedIn profile of Lea Janachkovska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" rel="noopener" aria-label="Instagram profile of Lea Janachkovska"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Lea Janachkovska</h4>
@ -239,8 +239,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marko.arsov@msosorg.com" aria-label="Email Marko Arsov"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" aria-label="LinkedIn profile of Marko Arsov"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" aria-label="Instagram profile of Marko Arsov"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" rel="noopener" aria-label="LinkedIn profile of Marko Arsov"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" rel="noopener" aria-label="Instagram profile of Marko Arsov"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marko Arsov</h4>
@ -253,8 +253,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marija.koshtrevska@msosorg.com" aria-label="Email Marija Koshtrevska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" aria-label="LinkedIn profile of Marija Koshtrevska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" aria-label="Instagram profile of Marija Koshtrevska"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" rel="noopener" aria-label="LinkedIn profile of Marija Koshtrevska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" rel="noopener" aria-label="Instagram profile of Marija Koshtrevska"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marija Koshtrevska</h4>
@ -267,8 +267,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:monika.velinova@msosorg.com" aria-label="Email Monika Velinova"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" aria-label="LinkedIn profile of Monika Velinova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" aria-label="Instagram profile of Monika Velinova"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" rel="noopener" aria-label="LinkedIn profile of Monika Velinova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" rel="noopener" aria-label="Instagram profile of Monika Velinova"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Monika Velinova</h4>

View File

@ -295,7 +295,7 @@
<p>We know that not everyone managed to attend the NLB Gallery, but we therefore provided a high-quality livestream. The event was broadcast live and is now available for re-watching. If you want to feel the atmosphere and hear the honest stories from the panel, you can watch the entire event here 👇</p>
<div class="video-responsive">
<iframe src="https://www.youtube.com/embed/DJD02mQIE98" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<iframe src="https://www.youtube-nocookie.com/embed/DJD02mQIE98" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<figure class="article-inline-image">

View File

@ -240,7 +240,7 @@
<p>To capture the spirit of the night, we created an aftermovie, which you can watch below.</p>
<div class="video-responsive">
<iframe src="https://www.youtube.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<iframe src="https://www.youtube-nocookie.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<figure class="article-inline-image">

0
l.php
View File

View File

@ -211,8 +211,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:kristijan.popovski@msosorg.com" aria-label="Испрати е-пошта до Kristijan Popovski"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" aria-label="LinkedIn профил на Kristijan Popovski"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" aria-label="Instagram профил на Kristijan Popovski"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" rel="noopener" aria-label="LinkedIn профил на Kristijan Popovski"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" rel="noopener" aria-label="Instagram профил на Kristijan Popovski"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Kristijan Popovski</h4>
@ -225,8 +225,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:lea.janackovska@msosorg.com" aria-label="Испрати е-пошта до Lea Janachkovska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" aria-label="LinkedIn профил на Lea Janachkovska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" aria-label="Instagram профил на Lea Janachkovska"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" rel="noopener" aria-label="LinkedIn профил на Lea Janachkovska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" rel="noopener" aria-label="Instagram профил на Lea Janachkovska"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Lea Janachkovska</h4>
@ -239,8 +239,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marko.arsov@msosorg.com" aria-label="Испрати е-пошта до Marko Arsov"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" aria-label="LinkedIn профил на Marko Arsov"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" aria-label="Instagram профил на Marko Arsov"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" rel="noopener" aria-label="LinkedIn профил на Marko Arsov"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" rel="noopener" aria-label="Instagram профил на Marko Arsov"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marko Arsov</h4>
@ -253,8 +253,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marija.koshtrevska@msosorg.com" aria-label="Испрати е-пошта до Marija Koshtrevska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" aria-label="LinkedIn профил на Marija Koshtrevska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" aria-label="Instagram профил на Marija Koshtrevska"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" rel="noopener" aria-label="LinkedIn профил на Marija Koshtrevska"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" rel="noopener" aria-label="Instagram профил на Marija Koshtrevska"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marija Koshtrevska</h4>
@ -267,8 +267,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:monika.velinova@msosorg.com" aria-label="Испрати е-пошта до Monika Velinova"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" aria-label="LinkedIn профил на Monika Velinova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" aria-label="Instagram профил на Monika Velinova"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" rel="noopener" aria-label="LinkedIn профил на Monika Velinova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" rel="noopener" aria-label="Instagram профил на Monika Velinova"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Monika Velinova</h4>

View File

@ -240,7 +240,7 @@
<p>За да го доловиме духот на вечерта, создадовме видео, кое можете да го погледнете подолу.</p>
<div class="video-responsive">
<iframe src="https://www.youtube.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<iframe src="https://www.youtube-nocookie.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<figure class="article-inline-image">

View File

@ -28,7 +28,7 @@
var m = new RegExp('[?&]' + name + '=([^&]*)').exec(location.search);
return m ? decodeURIComponent(m[1].replace(/\+/g, ' ')) : '';
}
function esc(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }
function esc(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;'); }
var lang = root.getAttribute('data-lang') || param('lang') || 'en';

View File

@ -211,8 +211,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:kristijan.popovski@msosorg.com" aria-label="E-pošta Kristijan Popovski"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" aria-label="LinkedIn profil Kristijana Popovskega"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" aria-label="Instagram profil Kristijana Popovskega"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/popovski-k" target="_blank" rel="noopener" aria-label="LinkedIn profil Kristijana Popovskega"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/popovski.k/" target="_blank" rel="noopener" aria-label="Instagram profil Kristijana Popovskega"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Kristijan Popovski</h4>
@ -225,8 +225,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:lea.janackovska@msosorg.com" aria-label="E-pošta Lea Janachkovska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" aria-label="LinkedIn profil Lee Janachkovske"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" aria-label="Instagram profil Lee Janachkovske"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/lea-janachkovska-9833b9246/" target="_blank" rel="noopener" aria-label="LinkedIn profil Lee Janachkovske"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/lea_janackovska" target="_blank" rel="noopener" aria-label="Instagram profil Lee Janachkovske"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Lea Janachkovska</h4>
@ -239,8 +239,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marko.arsov@msosorg.com" aria-label="E-pošta Marko Arsov"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" aria-label="LinkedIn profil Marka Arsova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" aria-label="Instagram profil Marka Arsova"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marko-arsov-3313202b9" target="_blank" rel="noopener" aria-label="LinkedIn profil Marka Arsova"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/marko.arsov" target="_blank" rel="noopener" aria-label="Instagram profil Marka Arsova"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marko Arsov</h4>
@ -253,8 +253,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:marija.koshtrevska@msosorg.com" aria-label="E-pošta Marija Koshtrevska"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" aria-label="LinkedIn profil Marije Koshtrevske"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" aria-label="Instagram profil Marije Koshtrevske"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/marija-koshtrevska/" target="_blank" rel="noopener" aria-label="LinkedIn profil Marije Koshtrevske"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/koshtrevska_10" target="_blank" rel="noopener" aria-label="Instagram profil Marije Koshtrevske"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Marija Koshtrevska</h4>
@ -267,8 +267,8 @@
<div class="member-content">
<div class="member-socials">
<a href="mailto:monika.velinova@msosorg.com" aria-label="E-pošta Monika Velinova"><i class="fas fa-envelope"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" aria-label="LinkedIn profil Monike Velinove"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" aria-label="Instagram profil Monike Velinove"><i class="fab fa-instagram"></i></a>
<a href="https://www.linkedin.com/in/monika-velinova-21632517a/" target="_blank" rel="noopener" aria-label="LinkedIn profil Monike Velinove"><i class="fab fa-linkedin-in"></i></a>
<a href="https://www.instagram.com/monivelinova" target="_blank" rel="noopener" aria-label="Instagram profil Monike Velinove"><i class="fab fa-instagram"></i></a>
</div>
<div class="member-info">
<h4>Monika Velinova</h4>

View File

@ -240,7 +240,7 @@
<p>Da bi ujeli duh večera, smo ustvarili videoposnetek, ki si ga lahko ogledate spodaj.</p>
<div class="video-responsive">
<iframe src="https://www.youtube.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<iframe src="https://www.youtube-nocookie.com/embed/xGN3-6hnfE4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<figure class="article-inline-image">