/** * MYP Platform - Globaler CSRF-Token-Fix * Automatisches Hinzufügen von CSRF-Token zu allen AJAX-Anfragen */ (function() { 'use strict'; // CSRF-Token aus verschiedenen Quellen abrufen function getCSRFToken() { // Methode 1: Meta-Tag (bevorzugt) const metaToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); if (metaToken && metaToken.trim()) { console.log('🔒 CSRF-Token aus Meta-Tag geladen'); return metaToken.trim(); } // Methode 2: Hidden Input const hiddenInput = document.querySelector('input[name="csrf_token"]')?.value; if (hiddenInput && hiddenInput.trim()) { console.log('🔒 CSRF-Token aus Hidden Input geladen'); return hiddenInput.trim(); } // Methode 3: Cookie (falls verfügbar) const cookieMatch = document.cookie.match(/csrf_token=([^;]+)/); if (cookieMatch && cookieMatch[1]) { console.log('🔒 CSRF-Token aus Cookie geladen'); return cookieMatch[1]; } console.error('❌ CSRF-Token konnte nicht gefunden werden!'); return null; } // Token beim Laden der Seite abrufen let csrfToken = getCSRFToken(); // Token regelmäßig aktualisieren (alle 30 Minuten) setInterval(() => { const newToken = getCSRFToken(); if (newToken && newToken !== csrfToken) { csrfToken = newToken; console.log('🔄 CSRF-Token aktualisiert'); } }, 30 * 60 * 1000); // Globale Funktion für andere Scripts window.getCSRFToken = function() { return csrfToken || getCSRFToken(); }; // Fetch API abfangen und CSRF-Token hinzufügen const originalFetch = window.fetch; window.fetch = function(url, options = {}) { // Nur für POST, PUT, DELETE, PATCH Anfragen const method = (options.method || 'GET').toUpperCase(); const needsCSRF = ['POST', 'PUT', 'DELETE', 'PATCH'].includes(method); if (needsCSRF) { const token = window.getCSRFToken(); if (token) { // Headers initialisieren falls nicht vorhanden options.headers = options.headers || {}; // CSRF-Token hinzufügen (mehrere Methoden für Kompatibilität) options.headers['X-CSRFToken'] = token; options.headers['X-CSRF-Token'] = token; // Für FormData: Token als Feld hinzufügen if (options.body instanceof FormData) { options.body.append('csrf_token', token); } // Für JSON: Token in Headers (bereits oben gemacht) else if (options.headers['Content-Type']?.includes('application/json')) { // Token ist bereits in Headers } // Für URL-encoded: Token hinzufügen else if (typeof options.body === 'string' && options.headers['Content-Type']?.includes('application/x-www-form-urlencoded')) { options.body += (options.body ? '&' : '') + 'csrf_token=' + encodeURIComponent(token); } console.log(`🔒 CSRF-Token zu ${method} ${url} hinzugefügt`); } else { console.warn(`⚠️ Kein CSRF-Token für ${method} ${url} verfügbar`); } } return originalFetch.call(this, url, options); }; // XMLHttpRequest abfangen (für ältere AJAX-Bibliotheken) const originalXHROpen = XMLHttpRequest.prototype.open; const originalXHRSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function(method, url, async, user, password) { this._method = method.toUpperCase(); this._url = url; return originalXHROpen.call(this, method, url, async, user, password); }; XMLHttpRequest.prototype.send = function(data) { const needsCSRF = ['POST', 'PUT', 'DELETE', 'PATCH'].includes(this._method); if (needsCSRF) { const token = window.getCSRFToken(); if (token) { // Header hinzufügen this.setRequestHeader('X-CSRFToken', token); this.setRequestHeader('X-CSRF-Token', token); // Für FormData: Token hinzufügen if (data instanceof FormData) { data.append('csrf_token', token); } // Für String-Data: Token hinzufügen else if (typeof data === 'string' && !this.getResponseHeader('Content-Type')?.includes('application/json')) { data += (data ? '&' : '') + 'csrf_token=' + encodeURIComponent(token); } console.log(`🔒 CSRF-Token zu XHR ${this._method} ${this._url} hinzugefügt`); } else { console.warn(`⚠️ Kein CSRF-Token für XHR ${this._method} ${this._url} verfügbar`); } } return originalXHRSend.call(this, data); }; // jQuery AJAX Setup (falls jQuery verwendet wird) document.addEventListener('DOMContentLoaded', function() { if (window.jQuery) { jQuery.ajaxSetup({ beforeSend: function(xhr, settings) { const needsCSRF = ['POST', 'PUT', 'DELETE', 'PATCH'].includes(settings.type?.toUpperCase()); if (needsCSRF && !this.crossDomain) { const token = window.getCSRFToken(); if (token) { xhr.setRequestHeader('X-CSRFToken', token); xhr.setRequestHeader('X-CSRF-Token', token); console.log(`🔒 CSRF-Token zu jQuery ${settings.type} ${settings.url} hinzugefügt`); } } } }); } }); // Debug-Funktion für Entwicklung window.debugCSRF = function() { console.log('🔍 CSRF Debug Info:'); console.log('Meta-Tag:', document.querySelector('meta[name="csrf-token"]')?.getAttribute('content')); console.log('Hidden Input:', document.querySelector('input[name="csrf_token"]')?.value); console.log('Current Token:', window.getCSRFToken()); console.log('Cookie:', document.cookie); }; console.log('🔒 CSRF-Fix geladen - automatisches Token-Management aktiv'); })();