85 lines
2.8 KiB
TypeScript
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);
|
|
}
|
|
}
|