fix(web): /login leitet angemeldete Benutzer aufs Dashboard (bzw. sicheres next)
Nur bei gueltiger Signatur und ohne ausstehenden Kennwortwechsel; next ueber sanitizeNextPath, /login als Ziel -> Dashboard. Gesperrte Konten: API lehnt ab, Oberflaeche loescht das Cookie serverseitig, keine Schleife. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { type NextRequest, NextResponse } from 'next/server';
|
||||
import { jwtVerify } from 'jose';
|
||||
import { buildNextParam } from '@/lib/safe-next';
|
||||
import { type NextRequest, NextResponse } from 'next/server';
|
||||
import { buildNextParam, sanitizeNextPath } from '@/lib/safe-next';
|
||||
|
||||
/**
|
||||
* Next.js middleware for frontend route protection (Pattern 4).
|
||||
@@ -113,6 +113,28 @@ function getSecret() {
|
||||
export async function middleware(req: NextRequest) {
|
||||
const path = req.nextUrl.pathname;
|
||||
|
||||
// Bereits angemeldet und /login aufgerufen (quick-260930, Wunsch des
|
||||
// Nutzers): statt der Anmeldeseite direkt zum Ziel — `next`, sofern ein
|
||||
// sicherer relativer Pfad, sonst das Dashboard. Nur bei gueltiger
|
||||
// Signatur; ist das Konto inzwischen gesperrt, lehnt die API die Sitzung
|
||||
// ab, die Oberflaeche loescht das Cookie serverseitig und schickt zur
|
||||
// Anmeldung zurueck — dann ohne Cookie, also keine Schleife.
|
||||
if (path === '/login' || path.startsWith('/login/')) {
|
||||
const existing = req.cookies.get('session')?.value;
|
||||
if (existing) {
|
||||
try {
|
||||
const { payload } = await jwtVerify(existing, getSecret(), { algorithms: ['HS256'] });
|
||||
if (payload.mustChangePassword !== true) {
|
||||
const next = sanitizeNextPath(req.nextUrl.searchParams.get('next'));
|
||||
const target = next.startsWith('/login') ? '/' : next;
|
||||
return withDesktopCookie(req, NextResponse.redirect(new URL(target, req.nextUrl)));
|
||||
}
|
||||
} catch {
|
||||
// ungueltiges Cookie: Anmeldeseite wie gewohnt zeigen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow public routes without authentication
|
||||
if (publicRoutes.some((route) => path.startsWith(route))) {
|
||||
return withDesktopCookie(req, NextResponse.next());
|
||||
@@ -141,10 +163,7 @@ export async function middleware(req: NextRequest) {
|
||||
});
|
||||
|
||||
// D-06: Force password change redirect
|
||||
if (
|
||||
payload.mustChangePassword === true &&
|
||||
!path.startsWith('/change-password')
|
||||
) {
|
||||
if (payload.mustChangePassword === true && !path.startsWith('/change-password')) {
|
||||
return withDesktopCookie(
|
||||
req,
|
||||
NextResponse.redirect(new URL('/change-password', req.nextUrl)),
|
||||
|
||||
Reference in New Issue
Block a user