fix: CSRF token manquant dans les fetch() POST du board et card detail
- board.html: ajout X-CSRF-Token header sur fetch /api/move et /api/issues - card_detail.html: ajout helper getCsrf() + header sur tous les fetch POST/PATCH - Sans ce fix, drag & drop, création issue, checklists échouent en production
This commit is contained in:
@@ -244,7 +244,11 @@
|
|||||||
title: '', status: 'todo',
|
title: '', status: 'todo',
|
||||||
create() {
|
create() {
|
||||||
if (!this.title.trim()) return;
|
if (!this.title.trim()) return;
|
||||||
fetch(`/api/issues/${owner}/${repo}?title=${encodeURIComponent(this.title)}&labels=${this.status}`, { method: 'POST' })
|
const csrf = document.cookie.match(/csrf_token=([^;]+)/);
|
||||||
|
fetch(`/api/issues/${owner}/${repo}?title=${encodeURIComponent(this.title)}&labels=${this.status}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-CSRF-Token': csrf ? csrf[1] : '' }
|
||||||
|
})
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.title = '';
|
this.title = '';
|
||||||
@@ -277,7 +281,11 @@
|
|||||||
onEnd: function(evt) {
|
onEnd: function(evt) {
|
||||||
const cardId = evt.item.dataset.cardId;
|
const cardId = evt.item.dataset.cardId;
|
||||||
const toStatus = evt.to.dataset.status;
|
const toStatus = evt.to.dataset.status;
|
||||||
fetch(`/api/move?owner=${owner}&repo=${repo}&issue_id=${cardId}&column=${toStatus}`, { method: 'POST' })
|
const csrf = document.cookie.match(/csrf_token=([^;]+)/);
|
||||||
|
fetch(`/api/move?owner=${owner}&repo=${repo}&issue_id=${cardId}&column=${toStatus}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-CSRF-Token': csrf ? csrf[1] : '' }
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// ponytail: refresh current view after move
|
// ponytail: refresh current view after move
|
||||||
const activeTab = document.querySelector('.view-tab.active');
|
const activeTab = document.querySelector('.view-tab.active');
|
||||||
|
|||||||
@@ -99,6 +99,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// ponytail: CSRF helper
|
||||||
|
function getCsrf() {
|
||||||
|
const m = document.cookie.match(/csrf_token=([^;]+)/);
|
||||||
|
return m ? m[1] : '';
|
||||||
|
}
|
||||||
|
|
||||||
function cardDetail() {
|
function cardDetail() {
|
||||||
return {
|
return {
|
||||||
updateField(field, value) {
|
updateField(field, value) {
|
||||||
@@ -109,18 +115,27 @@
|
|||||||
console.log('Toggle status');
|
console.log('Toggle status');
|
||||||
},
|
},
|
||||||
toggleChecklistItem(id, checked) {
|
toggleChecklistItem(id, checked) {
|
||||||
fetch(`/api/checklist-items/${id}?checked=${checked}`, { method: 'PATCH' });
|
fetch(`/api/checklist-items/${id}?checked=${checked}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'X-CSRF-Token': getCsrf() }
|
||||||
|
});
|
||||||
},
|
},
|
||||||
addChecklistItem(clId) {
|
addChecklistItem(clId) {
|
||||||
const content = prompt('Item name:');
|
const content = prompt('Item name:');
|
||||||
if (content) {
|
if (content) {
|
||||||
fetch(`/api/checklist-items/${owner}/${repo}/${issue_id}/${clId}?content=${encodeURIComponent(content)}`, { method: 'POST' })
|
fetch(`/api/checklist-items/${owner}/${repo}/${issue_id}/${clId}?content=${encodeURIComponent(content)}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-CSRF-Token': getCsrf() }
|
||||||
|
})
|
||||||
.then(() => htmx.ajax('GET', `/api/issues/${owner}/${repo}/${issue_id}?format=html`, { target: '#card-modal-content', swap: 'innerHTML' }));
|
.then(() => htmx.ajax('GET', `/api/issues/${owner}/${repo}/${issue_id}?format=html`, { target: '#card-modal-content', swap: 'innerHTML' }));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addChecklist() {
|
addChecklist() {
|
||||||
const title = prompt('Checklist name:') || 'Checklist';
|
const title = prompt('Checklist name:') || 'Checklist';
|
||||||
fetch(`/api/checklists/${owner}/${repo}/${issue_id}?title=${encodeURIComponent(title)}`, { method: 'POST' })
|
fetch(`/api/checklists/${owner}/${repo}/${issue_id}?title=${encodeURIComponent(title)}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-CSRF-Token': getCsrf() }
|
||||||
|
})
|
||||||
.then(() => htmx.ajax('GET', `/api/issues/${owner}/${repo}/${issue_id}?format=html`, { target: '#card-modal-content', swap: 'innerHTML' }));
|
.then(() => htmx.ajax('GET', `/api/issues/${owner}/${repo}/${issue_id}?format=html`, { target: '#card-modal-content', swap: 'innerHTML' }));
|
||||||
},
|
},
|
||||||
addComment(body) {
|
addComment(body) {
|
||||||
|
|||||||
Reference in New Issue
Block a user