diff --git a/src/animaltrack/web/templates/base.py b/src/animaltrack/web/templates/base.py index 26afa50..435d534 100644 --- a/src/animaltrack/web/templates/base.py +++ b/src/animaltrack/web/templates/base.py @@ -105,15 +105,16 @@ def EventSlideOverScript(): # noqa: N802 def CsrfHeaderScript(): # noqa: N802 - """JavaScript to inject CSRF token into HTMX requests. + """JavaScript to inject CSRF token into HTMX requests and provide global helper. - Reads the csrf_token cookie and adds it as x-csrf-token header - to all HTMX requests. This is required for POST/PUT/DELETE - requests to pass CSRF validation. + Provides a global getCsrfToken() function that reads the csrf_token cookie. + This function is used both by HTMX (via htmx:configRequest) and by any + vanilla fetch() calls that need CSRF protection. """ return Script(""" - // Read CSRF token from cookie - function getCsrfToken() { + // Global function to read CSRF token from cookie + // Used by HTMX config and available for vanilla fetch() calls + window.getCsrfToken = function() { var name = 'csrf_token='; var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { @@ -123,7 +124,7 @@ def CsrfHeaderScript(): # noqa: N802 } } return ''; - } + }; // Configure HTMX to send CSRF token with all requests document.body.addEventListener('htmx:configRequest', function(event) { diff --git a/src/animaltrack/web/templates/event_detail.py b/src/animaltrack/web/templates/event_detail.py index 1880b02..e498551 100644 --- a/src/animaltrack/web/templates/event_detail.py +++ b/src/animaltrack/web/templates/event_detail.py @@ -535,6 +535,7 @@ def delete_script() -> Script: method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', + 'x-csrf-token': getCsrfToken(), }, body: 'reason=Deleted via UI' });