diff --git a/README.adoc b/README.adoc index 184a87f..0543a19 100644 --- a/README.adoc +++ b/README.adoc @@ -190,7 +190,6 @@ Toutes ces sources sont modifiables dans `includes/config.local.php` (voir < - diff --git a/includes/security.php b/includes/security.php index dd9e98b..59ddafe 100644 --- a/includes/security.php +++ b/includes/security.php @@ -309,19 +309,32 @@ function setSecurityHeaders() { /** * Valide l'origine de la requête pour les requêtes AJAX - * + * + * Accepte le header Origin, ou à défaut un Referer same-origin + * (certains navigateurs n'envoient pas Origin sur les requêtes same-origin). + * * @return bool True si l'origine est valide */ function validateAjaxOrigin() { - $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; $host = $_SERVER['HTTP_HOST'] ?? ''; - - if (empty($origin) || empty($host)) { + if (empty($host)) { return false; } - - $expectedOrigin = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $host; - - return $origin === $expectedOrigin; + + $scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'); + $expectedOrigin = $scheme . '://' . $host; + + $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; + if (!empty($origin)) { + return $origin === $expectedOrigin; + } + + // Fallback : vérifier le referer si Origin est absent + $referer = $_SERVER['HTTP_REFERER'] ?? ''; + if (!empty($referer)) { + return strpos($referer, $expectedOrigin) === 0; + } + + return false; } ?> \ No newline at end of file diff --git a/js/categories.js b/js/categories.js deleted file mode 100644 index eeff00d..0000000 --- a/js/categories.js +++ /dev/null @@ -1,97 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - // Gestion des clics sur les vidéos - const videoCards = document.querySelectorAll(".video-card"); - - for (const videoCard of videoCards) { - videoCard.addEventListener("click", function () { - const videoId = this.dataset.videoId; - if (videoId) { - window.location.href = `video.php?id=${videoId}`; - } - }); - } - // Gestion du bouton "Voir plus" - const viewMoreBtn = document.querySelector(".view-more"); - if (viewMoreBtn) { - viewMoreBtn.addEventListener("click", function () { - const page = Number.parseInt(this.dataset.page); - const categoryId = - document.querySelector(".video-section").dataset.categoryId; - - // Changer le texte du bouton pendant le chargement - this.textContent = "Chargement..."; - this.disabled = true; - - // Préparer les données avec token CSRF - const formData = new FormData(); - formData.append('csrf_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content')); - - // Faire la requête AJAX - fetch( - `ajax/load-more-videos.php?type=category&page=${page}&category=${categoryId}`, - { - method: 'POST', - headers: { - "X-Requested-With": "XMLHttpRequest", - }, - body: formData - } - ) - .then((response) => response.json()) - .then((data) => { - if (data.success) { - // Ajouter les nouvelles vidéos à la grille - const videoGrid = document.querySelector(".video-grid"); - const tempDiv = document.createElement("div"); - tempDiv.innerHTML = data.html; - - // Ajouter chaque vidéo à la grille - while (tempDiv.firstChild) { - videoGrid.appendChild(tempDiv.firstChild); - } - - // Mettre à jour le numéro de page - this.dataset.page = data.page + 1; - - // Réinitialiser le texte du bouton - this.textContent = "Voir plus"; - this.disabled = false; - - // Si plus de vidéos à charger, masquer le bouton - if (!data.hasMore) { - this.style.display = "none"; - } - - // Initialiser les clics sur les nouvelles vidéos - const cards = document.querySelectorAll(".video-card:not([data-click-initialized])") - - for (const card of cards) { - card.setAttribute("data-click-initialized", "true"); - card.addEventListener("click", function () { - const videoId = this.dataset.videoId; - if (videoId) { - window.location.href = `video.php?id=${videoId}`; - } - }); - - } - } else { - // Gérer l'erreur - this.textContent = "Erreur lors du chargement"; - setTimeout(() => { - this.textContent = "Voir plus"; - this.disabled = false; - }, 2000); - } - }) - .catch((error) => { - console.error("Erreur:", error); - this.textContent = "Erreur lors du chargement"; - setTimeout(() => { - this.textContent = "Voir plus"; - this.disabled = false; - }, 2000); - }); - }); - } -}); diff --git a/js/main.js b/js/main.js index 069bac3..c1de33d 100644 --- a/js/main.js +++ b/js/main.js @@ -502,16 +502,24 @@ document.addEventListener('DOMContentLoaded', function() { // Initialiser le lazy loading pour les nouvelles images initLazyLoading(); } else { - // En cas d'erreur, afficher un message et réactiver le bouton + // En cas d'erreur, afficher un message temporaire et réactiver le bouton console.error('Erreur lors du chargement des vidéos:', data.error); - button.textContent = 'Voir plus'; + const originalText = 'Voir plus'; + button.textContent = 'Erreur de chargement'; button.disabled = false; + setTimeout(() => { + button.textContent = originalText; + }, 2000); } }) .catch(error => { console.error('Erreur lors de la requête AJAX:', error); - button.textContent = 'Voir plus'; + const originalText = 'Voir plus'; + button.textContent = 'Erreur de chargement'; button.disabled = false; + setTimeout(() => { + button.textContent = originalText; + }, 2000); }); }); }); diff --git a/sw.js b/sw.js index 9c71b8c..f6ce4bf 100644 --- a/sw.js +++ b/sw.js @@ -15,7 +15,6 @@ const STATIC_ASSETS = [ '/css/video-page.css', '/css/mastodon-timeline.min.css', '/js/main.js', - '/js/categories.js', '/js/search.js', '/js/mastodon-timeline.umd.js', '/img/logo.png',