security(headers): ajoute les en-têtes HTTP de sécurité et refactorise les scripts inline pour CSP

- Ajoute .htaccess avec HSTS, CSP, X-Frame-Options, X-Content-Type-Options,
  Referrer-Policy et Permissions-Policy
- Déplace les scripts inline (thème, redirection de langue) vers des fichiers JS externes
- Remplace les onclick inline par des écouteurs d'événements dans main.js
- Configure Eleventy pour copier .htaccess à la racine du site
This commit is contained in:
2026-07-07 23:56:56 +04:00
parent 8dac00d692
commit 36d1e307bd
9 changed files with 89 additions and 43 deletions
+15
View File
@@ -0,0 +1,15 @@
(function() {
// Redirection automatique selon la langue du navigateur, sauf choix explicite déjà mémorisé
var pref = localStorage.getItem('oki-lang-pref');
if (pref) return;
var browserLang = (navigator.language || navigator.userLanguage || '').toLowerCase();
var wantsEnglish = browserLang.indexOf('en') === 0;
var currentLocale = document.documentElement.dataset.locale || 'fr';
if (wantsEnglish && currentLocale !== 'en') {
window.location.replace('/en/' + window.location.hash);
} else if (!wantsEnglish && currentLocale === 'en') {
window.location.replace('/' + window.location.hash);
}
})();
+27
View File
@@ -67,6 +67,18 @@
// Ajouter l'événement au bouton
themeToggle?.addEventListener('click', toggleTheme);
// Language switcher links
document.querySelectorAll('.lang-switch').forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
var lang = this.dataset.lang;
if (lang) {
localStorage.setItem('oki-lang-pref', lang);
switchLanguage(lang);
}
});
});
})();
// Language switch with page mapping
@@ -377,3 +389,18 @@ function handleCustomDonation(type) {
window.location.href = stripeUrl;
}
// FAQ accordion toggle
document.querySelectorAll('.faq-question').forEach(button => {
button.addEventListener('click', () => {
button.parentElement.classList.toggle('active');
});
});
// Custom donation buttons
document.querySelectorAll('.custom-donation-btn').forEach(button => {
button.addEventListener('click', () => {
const type = button.dataset.donationType;
if (type) handleCustomDonation(type);
});
});
+17
View File
@@ -0,0 +1,17 @@
(function() {
// Récupérer le thème stocké ou détecter le thème système
const storedTheme = localStorage.getItem('oki-theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
let theme = storedTheme;
// Si pas de préférence stockée, utiliser le thème système
if (!storedTheme) {
theme = systemPrefersDark ? 'dark' : 'light';
}
// Appliquer le thème immédiatement
if (theme === 'light') {
document.documentElement.classList.add('light-theme');
}
})();