104 lines
3.3 KiB
TypeScript
104 lines
3.3 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
const config = {
|
|
matcher: [
|
|
/*
|
|
* Match all paths except for:
|
|
* 1. /api routes
|
|
* 2. /_next (Next.js internals)
|
|
* 3. /_static (inside /public)
|
|
* 4. all root files inside /public (e.g. /favicon.ico)
|
|
*/
|
|
'/((?!api/|_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)',
|
|
],
|
|
};
|
|
|
|
export default async function middleware(req: NextRequest) {
|
|
const url = req.nextUrl;
|
|
const response = NextResponse.next();
|
|
|
|
// Maximum size to prevent cookie chunking
|
|
const MAX_COOKIE_SIZE = 3500; // conservative limit in bytes
|
|
|
|
// Function to set all required nextAuth environment variables
|
|
const setNextAuthEnvVars = () => {
|
|
// Disable callbacks that could increase cookie size
|
|
process.env.NEXTAUTH_DISABLE_CALLBACK = 'true';
|
|
process.env.NEXTAUTH_DISABLE_JWT_CALLBACK = 'true';
|
|
process.env.NEXTAUTH_COOKIE_SIZE_LIMIT = String(MAX_COOKIE_SIZE);
|
|
process.env.NEXTAUTH_COOKIES_CHUNKING = 'true';
|
|
process.env.NEXTAUTH_COOKIES_CHUNKING_SIZE = String(MAX_COOKIE_SIZE);
|
|
process.env.NEXTAUTH_COOKIES_SECURE = 'true';
|
|
process.env.NEXTAUTH_COOKIES_SAMESITE = 'none';
|
|
};
|
|
|
|
// Set environment variables for all routes
|
|
setNextAuthEnvVars();
|
|
|
|
// Special handling for loggedout page to clean up cookies
|
|
if (url.pathname === '/loggedout') {
|
|
// Check if we're preserving SSO or doing a full logout
|
|
const preserveSso = url.searchParams.get('preserveSso') === 'true';
|
|
|
|
console.log(`Middleware detected logout (preserveSso: ${preserveSso})`);
|
|
|
|
if (preserveSso) {
|
|
// Only clean up NextAuth cookies but preserve Keycloak SSO cookies
|
|
const nextAuthCookies = [
|
|
'next-auth.session-token',
|
|
'next-auth.csrf-token',
|
|
'next-auth.callback-url',
|
|
'__Secure-next-auth.session-token',
|
|
'__Host-next-auth.csrf-token'
|
|
];
|
|
|
|
nextAuthCookies.forEach(name => {
|
|
response.cookies.delete(name);
|
|
});
|
|
|
|
// Also delete any chunked cookies
|
|
const cookieNames = Object.keys(req.cookies.getAll());
|
|
const chunkedCookies = cookieNames.filter(name => /next-auth.*\.\d+$/.test(name));
|
|
chunkedCookies.forEach(name => {
|
|
response.cookies.delete(name);
|
|
});
|
|
} else {
|
|
// Full logout - clear all auth-related cookies
|
|
const authCookies = [
|
|
'next-auth.session-token',
|
|
'next-auth.csrf-token',
|
|
'next-auth.callback-url',
|
|
'__Secure-next-auth.session-token',
|
|
'__Host-next-auth.csrf-token',
|
|
'KEYCLOAK_SESSION',
|
|
'KEYCLOAK_IDENTITY',
|
|
'KC_RESTART',
|
|
'JSESSIONID'
|
|
];
|
|
|
|
authCookies.forEach(name => {
|
|
response.cookies.delete(name);
|
|
});
|
|
|
|
// Also delete any chunked cookies
|
|
const cookieNames = Object.keys(req.cookies.getAll());
|
|
const chunkedCookies = cookieNames.filter(name =>
|
|
/next-auth.*\.\d+$/.test(name) ||
|
|
/KEYCLOAK.*/.test(name) ||
|
|
/KC_.*/.test(name)
|
|
);
|
|
chunkedCookies.forEach(name => {
|
|
response.cookies.delete(name);
|
|
});
|
|
}
|
|
}
|
|
|
|
// For sign-in page, add header if fresh login is requested
|
|
if (url.pathname === '/api/auth/signin' && url.searchParams.get('fresh') === 'true') {
|
|
response.headers.set('X-Auth-Fresh-Login', 'true');
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
export { config };
|