Fix drag-and-drop reorder: CSRF token was never readable by JS

NetBox sets CSRF_COOKIE_HTTPONLY = True, so document.cookie can never
see the csrftoken cookie - elevation.js's reorder POST always sent an
empty X-CSRFToken header, Django's CSRF middleware rejected every
request with 403 before it reached the view, and the JS's failure
path (removeAttribute('transform') + a small status message) made a
dragged device silently snap back to its old position on every single
attempt, not just occasionally.

Render {% csrf_token %} on the concept detail page and read the token
from that hidden input instead of the cookie - the standard approach
for a plain fetch() POST outside of a form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 12:24:58 +02:00
co-authored by Claude Sonnet 5
parent d500a7b184
commit 27d915c45e
2 changed files with 8 additions and 2 deletions
@@ -76,8 +76,10 @@
const statusEl = document.getElementById('concept-elevation-status'); const statusEl = document.getElementById('concept-elevation-status');
function csrfToken() { function csrfToken() {
const match = document.cookie.match(/(^|;)\s*csrftoken\s*=\s*([^;]+)/); // NetBox sets CSRF_COOKIE_HTTPONLY, so the cookie itself is invisible to
return match ? decodeURIComponent(match[2]) : ''; // JavaScript - read the value from the hidden {% csrf_token %} input instead.
const input = document.querySelector('input[name="csrfmiddlewaretoken"]');
return input ? input.value : '';
} }
function setStatus(message, isError) { function setStatus(message, isError) {
@@ -143,6 +143,10 @@
</div> </div>
</div> </div>
<div class="card-body"> <div class="card-body">
{# CSRF_COOKIE_HTTPONLY is on in NetBox, so the elevation.js reorder POST can't
read the csrftoken cookie via document.cookie - it reads this hidden input's
value instead, the standard Django way to CSRF-protect a plain fetch(). #}
{% csrf_token %}
<div class="d-flex justify-content-around flex-wrap" <div class="d-flex justify-content-around flex-wrap"
id="concept-elevations" id="concept-elevations"
data-reorder-url="{% url 'plugins:netbox_rack_concept:rackconcept_reorder' pk=object.pk %}" data-reorder-url="{% url 'plugins:netbox_rack_concept:rackconcept_reorder' pk=object.pk %}"