From a4b497443179bed21d292fd77d2ad7757b779917 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 20:13:44 +0000 Subject: [PATCH] Selbstheilung: /api/auth/me stellt abgelaufenes/fehlendes preview_session-Cookie neu aus Portal-Session (webklar_portal_session) lebt unabhaengig vom preview_session-JWT. Fehlte das Preview-Cookie (WebView-Datenverlust, Ablauf), liefen alle *.project.webklar.com-Hosts in eine 302-Login-Schleife (schwarze Seite im Kundenportal), obwohl der Nutzer eingeloggt war - Re-Login war der einzige Ausweg. Jetzt heilt jeder Aufruf der Projektuebersicht das Cookie automatisch. Co-Authored-By: Claude Fable 5 --- server/routes/auth.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/server/routes/auth.js b/server/routes/auth.js index 11314b0..9b74ff0 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -297,6 +297,22 @@ router.get('/staff-preview', async (req, res) => { return res.redirect(previewUrl) }) +// Selbstheilung: Portal-Session lebt oft laenger als das preview_session-Cookie +// (bzw. das Cookie fehlt nach WebView-/Browser-Datenverlust). Ohne gueltiges +// Preview-Cookie laufen die *.project.webklar.com-Hosts in eine 302-Schleife. +// Deshalb stellt /me das Preview-Cookie automatisch neu aus, solange die +// Portal-Session gueltig ist. +async function refreshPreviewCookie(req, res, payload) { + try { + const existing = req.cookies?.[PREVIEW_COOKIE_NAME] + if (existing && (await verifyPreviewSessionToken(existing))) return + const token = await createPreviewSessionToken(payload) + res.cookie(PREVIEW_COOKIE_NAME, token, previewSessionCookieOptions()) + } catch (err) { + console.warn('[auth] preview-cookie refresh failed:', err.message) + } +} + router.get('/me', async (req, res) => { const raw = req.signedCookies?.[config.cookieName] if (!raw) { @@ -313,6 +329,15 @@ router.get('/me', async (req, res) => { const doc = await getDocument(config.collections.customers, session.customerId).catch(() => null) if (doc) customer = sanitizeCustomer(doc) } + await refreshPreviewCookie(req, res, { + userId: session.appwriteUserId, + customerId: '', + email: session.adminEmail || session.email || '', + name: session.adminName || session.name || 'Admin', + role: 'admin', + labels: ['admin'], + authSource: 'kundenbereich-admin', + }) return res.json({ authenticated: true, role: 'admin', @@ -348,6 +373,16 @@ router.get('/me', async (req, res) => { customer = await syncCustomerAppwriteUserId(customer, session.appwriteUserId) } + await refreshPreviewCookie(req, res, { + userId: session.appwriteUserId, + customerId: customer.$id, + email: customer.email || session.email || '', + name: customer.name || session.name || '', + role: 'customer', + labels: [], + authSource: 'kundenbereich', + }) + return res.json({ authenticated: true, role: 'customer',