From 0e2f728cebdcf1a43e9194786f0abc0c03da33a7 Mon Sep 17 00:00:00 2001 From: alma Date: Sun, 27 Apr 2025 20:05:40 +0200 Subject: [PATCH] courrier multi account restore compose --- app/api/courrier/recache/route.ts | 49 ++++++++++++++ lib/services/email-service.ts | 104 +++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 app/api/courrier/recache/route.ts diff --git a/app/api/courrier/recache/route.ts b/app/api/courrier/recache/route.ts new file mode 100644 index 00000000..89e36f67 --- /dev/null +++ b/app/api/courrier/recache/route.ts @@ -0,0 +1,49 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { getServerSession } from 'next-auth/next'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { forceRecacheUserCredentials } from '@/lib/services/email-service'; + +export async function GET(request: NextRequest) { + try { + // Get session to ensure user is authenticated + const session = await getServerSession(authOptions); + + if (!session || !session.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + const userId = session.user.id; + + // Force recache credentials + const success = await forceRecacheUserCredentials(userId); + + if (success) { + return NextResponse.json({ + success: true, + message: 'Credentials recached successfully', + userId + }); + } else { + return NextResponse.json( + { + success: false, + error: 'Failed to recache credentials. Check server logs for details.', + userId + }, + { status: 500 } + ); + } + } catch (error) { + console.error('Recache API error:', error); + return NextResponse.json( + { + success: false, + error: error instanceof Error ? error.message : 'Unknown error' + }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/lib/services/email-service.ts b/lib/services/email-service.ts index fc0175bb..7e9134cd 100644 --- a/lib/services/email-service.ts +++ b/lib/services/email-service.ts @@ -814,4 +814,106 @@ export async function testImapConnection(credentials: EmailCredentials): Promise } // Email formatting functions have been moved to lib/utils/email-formatter.ts -// Use those functions instead of the ones previously defined here \ No newline at end of file +// Use those functions instead of the ones previously defined here + +/** + * Force recaching of user credentials from database + * This is a helper function to fix issues with missing credentials in Redis + */ +export async function forceRecacheUserCredentials(userId: string): Promise { + try { + console.log(`[CREDENTIAL FIX] Attempting to force recache credentials for user ${userId}`); + + // Get credentials directly from database + const dbCredentials = await prisma.mailCredentials.findUnique({ + where: { userId }, + select: { + email: true, + password: true, + host: true, + port: true, + secure: true, + smtp_host: true, + smtp_port: true, + smtp_secure: true, + display_name: true, + color: true + } + }); + + if (!dbCredentials) { + console.error(`[CREDENTIAL FIX] No credentials found in database for user ${userId}`); + return false; + } + + // Log what we found (without revealing the actual password) + console.log(`[CREDENTIAL FIX] Found database credentials for user ${userId}:`, { + email: dbCredentials.email, + hasPassword: !!dbCredentials.password, + passwordLength: dbCredentials.password?.length || 0, + host: dbCredentials.host, + port: dbCredentials.port + }); + + if (!dbCredentials.password) { + console.error(`[CREDENTIAL FIX] Password is empty in database for user ${userId}`); + return false; + } + + // Try to directly encrypt the password to see if encryption works + try { + const { encryptData } = await import('@/lib/redis'); + const encryptedPassword = encryptData(dbCredentials.password); + console.log(`[CREDENTIAL FIX] Successfully test-encrypted password for user ${userId}`); + + // If we got here, encryption works + } catch (encryptError) { + console.error(`[CREDENTIAL FIX] Encryption test failed for user ${userId}:`, encryptError); + return false; + } + + // Format credentials for caching + const credentials = { + email: dbCredentials.email, + password: dbCredentials.password, + host: dbCredentials.host, + port: dbCredentials.port, + ...(dbCredentials.secure !== undefined && { secure: dbCredentials.secure }), + ...(dbCredentials.smtp_host && { smtp_host: dbCredentials.smtp_host }), + ...(dbCredentials.smtp_port && { smtp_port: dbCredentials.smtp_port }), + ...(dbCredentials.smtp_secure !== undefined && { smtp_secure: dbCredentials.smtp_secure }), + ...(dbCredentials.display_name && { display_name: dbCredentials.display_name }), + ...(dbCredentials.color && { color: dbCredentials.color }) + }; + + // Try to cache the credentials + try { + const { cacheEmailCredentials } = await import('@/lib/redis'); + await cacheEmailCredentials(userId, credentials); + console.log(`[CREDENTIAL FIX] Successfully cached credentials for user ${userId}`); + + // Now verify the credentials were cached correctly + const { getEmailCredentials } = await import('@/lib/redis'); + const cachedCreds = await getEmailCredentials(userId); + + if (!cachedCreds) { + console.error(`[CREDENTIAL FIX] Failed to verify cached credentials for user ${userId}`); + return false; + } + + if (!cachedCreds.password) { + console.error(`[CREDENTIAL FIX] Cached credentials missing password for user ${userId}`); + return false; + } + + console.log(`[CREDENTIAL FIX] Verified cached credentials for user ${userId}`); + return true; + } catch (cacheError) { + console.error(`[CREDENTIAL FIX] Failed to cache credentials for user ${userId}:`, cacheError); + return false; + } + } catch (error) { + console.error(`[CREDENTIAL FIX] Error in force recache process for user ${userId}:`, error); + return false; + } +} \ No newline at end of file