Neah/app/api/auth/session-cleanup/route.ts
2025-05-02 12:48:01 +02:00

85 lines
2.8 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/[...nextauth]/route';
import { getRedisClient } from '@/lib/redis';
import { closeUserImapConnections } from '@/lib/services/email-service';
/**
* API endpoint to clean up user sessions and invalidate cached data
* Called during logout to ensure proper cleanup of all connections
*/
export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions);
const userId = session?.user?.id;
if (!userId) {
return NextResponse.json({ success: false, error: "No authenticated user found" }, { status: 401 });
}
await cleanupUserSessions(userId, false);
return NextResponse.json({ success: true, userId, message: "Session cleaned up" });
}
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const userId = body.userId;
const preserveSso = !!body.preserveSso;
if (!userId) {
return NextResponse.json({ success: false, error: "No user ID provided" }, { status: 400 });
}
await cleanupUserSessions(userId, preserveSso);
return NextResponse.json({
success: true,
userId,
preserveSso,
message: `Session cleaned up${preserveSso ? ' (SSO preserved)' : ''}`
});
} catch (error) {
console.error("Error in session-cleanup POST:", error);
return NextResponse.json({ success: false, error: "Failed to parse request" }, { status: 400 });
}
}
async function cleanupUserSessions(userId: string, preserveSso: boolean) {
try {
const redis = await getRedisClient();
if (!redis) {
console.error("Redis client not available for session cleanup");
return;
}
console.log(`Cleaning up sessions for user ${userId}${preserveSso ? ' (preserving SSO)' : ''}`);
// Find all keys for this user
const userKeys = await redis.keys(`*:${userId}*`);
if (userKeys.length > 0) {
console.log(`Found ${userKeys.length} keys for user ${userId}:`, userKeys);
// If preserving SSO, only delete application-specific keys
const keysToDelete = preserveSso
? userKeys.filter(key => !key.includes('keycloak') && !key.includes('sso'))
: userKeys;
if (keysToDelete.length > 0) {
await redis.del(keysToDelete);
console.log(`Deleted ${keysToDelete.length} keys for user ${userId}`);
} else {
console.log(`No application keys to delete while preserving SSO`);
}
} else {
console.log(`No keys found for user ${userId}`);
}
// Close any active IMAP connections
await closeUserImapConnections(userId);
} catch (error) {
console.error(`Error cleaning up sessions for user ${userId}:`, error);
}
}