From da457002d69e8b0697a013f5653e408e7c200250 Mon Sep 17 00:00:00 2001 From: maziggy Date: Tue, 3 Feb 2026 06:22:08 +0100 Subject: [PATCH] Fix authentication for download endpoints (fixes #231) Add missing Authorization header to fetch() calls that bypass the request() helper. These endpoints returned 401 when auth was enabled because the JWT token wasn't being sent with the request. Affected functions in frontend/src/api/client.ts: - downloadSupportBundle (support bundle download) - downloadPrinterFilesAsZip (printer file downloads) - exportArchives (archive CSV/XLSX export) - exportStats (statistics CSV/XLSX export) Closes #231 --- frontend/src/api/client.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 33a59a0bd..b0b7d9701 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -2062,9 +2062,13 @@ export const api = { getPrinterFileDownloadUrl: (printerId: number, path: string) => `${API_BASE}/printers/${printerId}/files/download?path=${encodeURIComponent(path)}`, downloadPrinterFilesAsZip: async (printerId: number, paths: string[]): Promise => { + const headers: Record = { 'Content-Type': 'application/json' }; + if (authToken) { + headers['Authorization'] = `Bearer ${authToken}`; + } const response = await fetch(`${API_BASE}/printers/${printerId}/files/download-zip`, { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers, body: JSON.stringify({ paths }), }); if (!response.ok) { @@ -2173,7 +2177,11 @@ export const api = { if (options?.dateTo) params.set('date_to', options.dateTo); if (options?.search) params.set('search', options.search); - const response = await fetch(`${API_BASE}/archives/export?${params}`); + const headers: Record = {}; + if (authToken) { + headers['Authorization'] = `Bearer ${authToken}`; + } + const response = await fetch(`${API_BASE}/archives/export?${params}`, { headers }); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.detail || `HTTP ${response.status}`); @@ -2201,7 +2209,11 @@ export const api = { if (options?.printerId) params.set('printer_id', String(options.printerId)); if (options?.projectId) params.set('project_id', String(options.projectId)); - const response = await fetch(`${API_BASE}/archives/stats/export?${params}`); + const headers: Record = {}; + if (authToken) { + headers['Authorization'] = `Bearer ${authToken}`; + } + const response = await fetch(`${API_BASE}/archives/stats/export?${params}`, { headers }); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.detail || `HTTP ${response.status}`); @@ -3961,7 +3973,11 @@ export const supportApi = { }), downloadSupportBundle: async () => { - const response = await fetch(`${API_BASE}/support/bundle`); + const headers: Record = {}; + if (authToken) { + headers['Authorization'] = `Bearer ${authToken}`; + } + const response = await fetch(`${API_BASE}/support/bundle`, { headers }); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.detail || `HTTP ${response.status}`);