feat(quick-260917-gyd): Ruecksprung nach Anmeldung auf urspruenglich angeforderte Seite

- safe-next.ts: buildNextParam()/sanitizeNextPath() als reine, getestete Funktionen (Open-Redirect-Schutz)
- middleware.ts: haengt next-Parameter an beide Login-Umleitungen (fehlendes Cookie, ungueltige Signatur)
- login/page.tsx: springt nach erfolgreicher Anmeldung auf den bereinigten next-Wert

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 12:26:14 +02:00
parent 4778824c73
commit 4b279eac70
4 changed files with 98 additions and 3 deletions
+18 -2
View File
@@ -1,5 +1,6 @@
import { NextRequest, NextResponse } from 'next/server';
import { jwtVerify } from 'jose';
import { buildNextParam } from '@/lib/safe-next';
/**
* Next.js middleware for frontend route protection (Pattern 4).
@@ -11,6 +12,21 @@ import { jwtVerify } from 'jose';
const publicRoutes = ['/login', '/reset-password'];
/**
* Umleitung zur Anmeldeseite mit `next`-Parameter (quick-260917-gyd): Pfad
* + Query der urspruenglich angeforderten Seite wandern mit, damit die
* Anmeldeseite nach erfolgreichem Login dorthin zurueckspringen kann
* (Ausloeser: Link "Update herunterladen" der Desktop-App).
*/
function redirectToLogin(req: NextRequest): NextResponse {
const url = new URL('/login', req.nextUrl);
const next = buildNextParam(req.nextUrl.pathname, req.nextUrl.search);
if (next !== null) {
url.searchParams.set('next', next);
}
return NextResponse.redirect(url);
}
function getSecret() {
const secret = process.env.JWT_SECRET || process.env.SESSION_SECRET;
if (!secret) {
@@ -43,7 +59,7 @@ export async function middleware(req: NextRequest) {
const session = req.cookies.get('session')?.value;
if (!session) {
return NextResponse.redirect(new URL('/login', req.nextUrl));
return redirectToLogin(req);
}
try {
@@ -62,7 +78,7 @@ export async function middleware(req: NextRequest) {
return NextResponse.next();
} catch {
// JWT verification failed -- clear stale cookie and redirect to login
const response = NextResponse.redirect(new URL('/login', req.nextUrl));
const response = redirectToLogin(req);
response.cookies.delete('session');
return response;
}