From 203b7d2b08efd1d478217cad22cf956682517d32 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 20 Mar 2026 11:01:31 +0100 Subject: [PATCH] fix(auth): proxy document file requests server-side to prevent Basic Auth popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Client-side fetch('/api/documents/{id}/file') bypassed the handleFetch hook that injects the Authorization header, causing the browser to receive a 401 with WWW-Authenticate: Basic and show a native auth dialog. Added a SvelteKit server route at /api/documents/[id]/file that proxies the request through the server, where handleFetch injects the auth cookie correctly. Also fixed E2E default password (admin → admin123) to match application.yaml. Co-Authored-By: Claude Sonnet 4.6 --- frontend/e2e/auth.setup.ts | 4 ++-- frontend/e2e/helpers/auth.ts | 2 +- .../routes/api/documents/[id]/file/+server.ts | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 frontend/src/routes/api/documents/[id]/file/+server.ts diff --git a/frontend/e2e/auth.setup.ts b/frontend/e2e/auth.setup.ts index ba836ed3..4d185e0f 100644 --- a/frontend/e2e/auth.setup.ts +++ b/frontend/e2e/auth.setup.ts @@ -9,11 +9,11 @@ const authFile = path.join(__dirname, '.auth/user.json'); * Logs in once and saves the session cookie so all E2E tests can reuse it. * Configure credentials via environment variables: * E2E_USERNAME (default: admin) - * E2E_PASSWORD (default: admin) + * E2E_PASSWORD (default: admin123) */ setup('authenticate', async ({ page }) => { const username = process.env.E2E_USERNAME ?? 'admin'; - const password = process.env.E2E_PASSWORD ?? 'admin'; + const password = process.env.E2E_PASSWORD ?? 'admin123'; await page.goto('/login'); await page.getByLabel('Benutzername').fill(username); diff --git a/frontend/e2e/helpers/auth.ts b/frontend/e2e/helpers/auth.ts index f8dc8583..54847336 100644 --- a/frontend/e2e/helpers/auth.ts +++ b/frontend/e2e/helpers/auth.ts @@ -3,7 +3,7 @@ import type { Page } from '@playwright/test'; export async function login( page: Page, username = process.env.E2E_USERNAME ?? 'admin', - password = process.env.E2E_PASSWORD ?? 'admin' + password = process.env.E2E_PASSWORD ?? 'admin123' ) { await page.goto('/login'); await page.getByLabel('Benutzername').fill(username); diff --git a/frontend/src/routes/api/documents/[id]/file/+server.ts b/frontend/src/routes/api/documents/[id]/file/+server.ts new file mode 100644 index 00000000..fedaa656 --- /dev/null +++ b/frontend/src/routes/api/documents/[id]/file/+server.ts @@ -0,0 +1,19 @@ +import type { RequestHandler } from './$types'; +import { env } from 'process'; + +export const GET: RequestHandler = async ({ params, fetch }) => { + const backendUrl = `${env.API_INTERNAL_URL || 'http://localhost:8080'}/api/documents/${params.id}/file`; + + const response = await fetch(backendUrl); + + if (!response.ok) { + return new Response(null, { status: response.status }); + } + + return new Response(response.body, { + headers: { + 'Content-Type': response.headers.get('Content-Type') ?? 'application/octet-stream', + 'Content-Disposition': response.headers.get('Content-Disposition') ?? '' + } + }); +};