From 0e91e8b11cb7bb5242709dab919985c4c6f60555 Mon Sep 17 00:00:00 2001 From: Rene Fichtmueller Date: Sat, 18 Apr 2026 08:03:39 +0200 Subject: [PATCH] fix: add missing auth header to blog generate fetches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both generateBlog() and generateBlogManual() were calling POST /api/blog/generate without an Authorization: Bearer header. The requireAuth middleware correctly returned 401, which appeared as 'Unauthorized — please log in' toast in the dashboard. Fix: read loadToken() before each fetch and include the token in the Authorization header. Also add r.status===401 guard to redirect to login page when token expires, instead of showing error toast. --- packages/dashboard/index.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/dashboard/index.html b/packages/dashboard/index.html index a6c1ec4..ac63871 100644 --- a/packages/dashboard/index.html +++ b/packages/dashboard/index.html @@ -4645,17 +4645,18 @@ function copyLinkedInPost(id) { function generateBlog(topic, speed) { var body = { topic: topic }; if (speed) body.speed = speed; + var token = window.loadToken ? window.loadToken() : ''; fetch(API + '/api/blog/generate', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify(body) - }).then(function(r) { return r.json(); }).then(function(data) { + }).then(function(r) { if (r.status === 401) { handleAuthError(401); throw new Error('Unauthorized'); } return r.json(); }).then(function(data) { if (data.success) { showToast('⚙️ Generating…', data.draft.title + ' — pipeline running (~10 min)'); loadBlogDrafts(); pollBlogLlm(data.draft.id, 0); } else showToast('Failed', data.error || 'Unknown error', true); - }).catch(function(err) { showToast('Network error', err.message, true); }); + }).catch(function(err) { if (err.message !== 'Unauthorized') showToast('Network error', err.message, true); }); } function toggleBlogReviewed(id, starEl) { @@ -4701,12 +4702,13 @@ function generateBlogManual() { if (customTitle) body.custom_title = customTitle; if (additionalContext) body.additional_context = additionalContext; + var token = window.loadToken ? window.loadToken() : ''; showToast('⚙️ Gestartet', (customTitle || 'Artikel') + ' — Pipeline läuft (~10 min)'); fetch(API + '/api/blog/generate', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify(body) - }).then(function(r) { return r.json(); }).then(function(data) { + }).then(function(r) { if (r.status === 401) { handleAuthError(401); throw new Error('Unauthorized'); } return r.json(); }).then(function(data) { if (data.success) { showToast('✓ Pipeline gestartet', data.draft.title + ' — wird in ~10 min fertig'); document.getElementById('blog-custom-title').value = ''; @@ -4714,7 +4716,7 @@ function generateBlogManual() { loadBlogDrafts(); pollBlogLlm(data.draft.id, 0); } else showToast('Fehler', data.error || 'Unbekannter Fehler', true); - }).catch(function(err) { showToast('Netzwerkfehler', err.message, true); }); + }).catch(function(err) { if (err.message !== 'Unauthorized') showToast('Netzwerkfehler', err.message, true); }); } function pollBlogLlm(id, attempt) {