80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import type { NextRequest } from 'next/server';
|
|
|
|
// Maximum cookie size in bytes (even more conservative to prevent chunking issues)
|
|
const MAX_COOKIE_SIZE = 3500;
|
|
|
|
// This middleware runs before any request
|
|
export function middleware(request: NextRequest) {
|
|
// Force NextAuth environment variables at runtime to prevent cookie chunking
|
|
process.env.NEXTAUTH_COOKIE_SIZE_LIMIT = MAX_COOKIE_SIZE.toString();
|
|
|
|
// Disable cookie callbacks which can increase cookie size
|
|
process.env.NEXTAUTH_CALLBACK = 'false';
|
|
process.env.NEXTAUTH_SESSION_STORE_SESSION_TOKEN = 'false';
|
|
process.env.NEXTAUTH_JWT_STORE_RAW_TOKEN = 'false';
|
|
|
|
// Check if this is a logout-related request
|
|
const url = request.nextUrl.pathname;
|
|
const isLogoutPath = url.includes('/signout') || url.includes('/loggedout');
|
|
const isSigninPath = url.includes('/signin');
|
|
const hasForceLogoutParam = request.nextUrl.searchParams.has('forceLogout');
|
|
|
|
if (isLogoutPath || hasForceLogoutParam) {
|
|
// On logout pages, we want to ensure cookies are cleaned up
|
|
const response = NextResponse.next();
|
|
|
|
// List of authentication-related cookies to clear on logout
|
|
const authCookies = [
|
|
'next-auth.session-token',
|
|
'next-auth.callback-url',
|
|
'next-auth.csrf-token',
|
|
'next-auth.pkce.code-verifier',
|
|
'__Secure-next-auth.session-token',
|
|
'__Host-next-auth.csrf-token'
|
|
];
|
|
|
|
// Clear each cookie with appropriate settings
|
|
authCookies.forEach(cookieName => {
|
|
// Try to detect and clear chunked cookies too
|
|
for (let i = 0; i < 5; i++) {
|
|
const chunkName = i > 0 ? `${cookieName}.${i}` : cookieName;
|
|
|
|
// Clear with domain
|
|
if (process.env.NEXTAUTH_COOKIE_DOMAIN) {
|
|
response.cookies.delete({
|
|
name: chunkName,
|
|
domain: process.env.NEXTAUTH_COOKIE_DOMAIN,
|
|
path: '/'
|
|
});
|
|
}
|
|
|
|
// Also clear without domain
|
|
response.cookies.delete({
|
|
name: chunkName,
|
|
path: '/'
|
|
});
|
|
}
|
|
});
|
|
|
|
return response;
|
|
}
|
|
|
|
// For the signin page with fresh=true param, pass a header indicating fresh login
|
|
if (isSigninPath && request.nextUrl.searchParams.get('fresh') === 'true') {
|
|
const response = NextResponse.next();
|
|
response.headers.set('X-Force-Fresh-Login', 'true');
|
|
return response;
|
|
}
|
|
|
|
// Continue with the request for all other paths
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// Configure the middleware to run on specific paths
|
|
export const config = {
|
|
matcher: [
|
|
// Apply to all routes except static files
|
|
'/((?!_next/static|_next/image|favicon.ico|public).*)',
|
|
],
|
|
};
|