From e61e24dfe8997d4904bd52f1f63dd7b68f896fd6 Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Sun, 26 Jul 2026 21:20:00 +0200 Subject: [PATCH] fix scroller tagging invalid csrf token --- public/s/js/scroller.js | 28 ++++++++++++++++++++-------- src/inc/routes/apiv2/tags.mjs | 5 +++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/public/s/js/scroller.js b/public/s/js/scroller.js index e26972f..0cfe672 100644 --- a/public/s/js/scroller.js +++ b/public/s/js/scroller.js @@ -1000,9 +1000,10 @@ e.stopPropagation(); const itemId = slide.dataset.id; try { + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; const resp = await fetch(`/api/v2/tags/${itemId}/${encodeURIComponent(tag)}`, { method: 'DELETE', - headers: { 'x-csrf-token': window.scrollerCsrf || '' } + headers: { ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) } }); const data = await resp.json(); if (data.success) pill.remove(); @@ -1157,10 +1158,14 @@ if (nowFaved) flashFav(slide); } try { + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; const resp = await fetch('/api/v2/togglefav', { method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: `postid=${id}` + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) + }, + body: `postid=${id}${csrfToken ? `&csrf_token=${encodeURIComponent(csrfToken)}` : ''}` }); const data = await resp.json(); // Sync count to server truth (handles race conditions) @@ -1582,9 +1587,10 @@ e.stopPropagation(); const itemId = slide.dataset.id; try { + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; const resp = await fetch(`/api/v2/tags/${itemId}/${encodeURIComponent(t)}`, { method: 'DELETE', - headers: { 'x-csrf-token': window.scrollerCsrf || '' } + headers: { ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) } }); const data = await resp.json(); if (data.success) pill.remove(); @@ -1850,11 +1856,12 @@ else if (item.external_board === 'gif') rating = 'nsfw'; try { + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; const resp = await fetch('/api/v2/scroller/rehost', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', - 'x-csrf-token': window.scrollerCsrf || '' + ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) }, body: new URLSearchParams({ url: item.external_media_url || item.dest, @@ -1966,9 +1973,10 @@ showShareToast(info.toast); } + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; fetch(`/api/v2/tags/${id}/cycle-rating`, { method: 'PUT', - headers: { 'x-csrf-token': window.scrollerCsrf || '' } + headers: { ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) } }) .then(r => r.json()) .then(data => { @@ -2909,10 +2917,14 @@ if (addTagSendBtn) addTagSendBtn.disabled = true; closeSugg(); try { + const csrfToken = window.f0ckSession?.csrf_token || window.scrollerCsrf || ''; const resp = await fetch(`/api/v2/tags/${targetId}`, { method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: `tagname=${encodeURIComponent(tag)}` + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + ...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}) + }, + body: `tagname=${encodeURIComponent(tag)}${csrfToken ? `&csrf_token=${encodeURIComponent(csrfToken)}` : ''}` }); const data = await resp.json(); if (data.success) { diff --git a/src/inc/routes/apiv2/tags.mjs b/src/inc/routes/apiv2/tags.mjs index 2403abe..3992059 100644 --- a/src/inc/routes/apiv2/tags.mjs +++ b/src/inc/routes/apiv2/tags.mjs @@ -25,7 +25,8 @@ export default router => { group.post(/$/, lib.loggedin, async (req, res) => { // assign and/or create tag - if (!req.params.postid || !req.post.tagname) { + const rawTagname = req.post?.tagname || req.body?.tagname; + if (!req.params.postid || !rawTagname) { return res.json({ success: false, msg: 'missing postid or tag' @@ -33,7 +34,7 @@ export default router => { } const postid = +req.params.postid; - const tagname = req.post.tagname?.trim(); + const tagname = rawTagname.trim(); const protectedTags = ['sfw', 'nsfw', 'nsfl']; if (protectedTags.includes(tagname.toLowerCase())) {