diff --git a/app/api/courrier/accounts/route.ts b/app/api/courrier/accounts/route.ts new file mode 100644 index 0000000..787cbf3 --- /dev/null +++ b/app/api/courrier/accounts/route.ts @@ -0,0 +1,45 @@ +import { NextResponse } from 'next/server'; +import { getServerSession } from 'next-auth'; +import { authOptions } from "@/app/api/auth/options"; +import { prisma } from '@/lib/prisma'; + +export async function GET(request: Request) { + try { + // Authenticate user + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + // Get all email accounts for this user + const accounts = await prisma.mailCredentials.findMany({ + where: { userId: session.user.id }, + select: { + id: true, + email: true, + display_name: true, + color: true, + host: true, + use_oauth: true, + } + }); + + // Never return passwords + return NextResponse.json({ + success: true, + accounts + }); + } catch (error) { + console.error('Error fetching email accounts:', error); + return NextResponse.json( + { + error: 'Failed to fetch email accounts', + details: error instanceof Error ? error.message : 'Unknown error' + }, + { status: 500 } + ); + } +} diff --git a/app/api/courrier/session/route.ts b/app/api/courrier/session/route.ts index d63d9fe..88f9c7c 100644 --- a/app/api/courrier/session/route.ts +++ b/app/api/courrier/session/route.ts @@ -3,10 +3,11 @@ import { getServerSession } from 'next-auth'; import { authOptions } from "@/app/api/auth/options"; import { getMailboxes } from '@/lib/services/email-service'; import { getRedisClient } from '@/lib/redis'; -import { getImapConnection } from '@/lib/services/email-service'; +import { getImapConnection, shouldUseGraphAPI } from '@/lib/services/email-service'; import { prisma } from '@/lib/prisma'; import { logger } from '@/lib/logger'; import bcrypt from 'bcryptjs'; +import { fetchGraphMailFolders } from '@/lib/services/microsoft-graph-mail'; // Define extended MailCredentials type interface MailCredentials { @@ -207,29 +208,52 @@ export async function GET() { }; } - // If not in cache, fetch from IMAP - logger.debug('[COURRIER_SESSION] Fetching folders from IMAP for account', { - email: account.email, - }); - const client = await getImapConnection(user.id, account.id); - if (!client) { - logger.warn('[COURRIER_SESSION] Failed to get IMAP connection for account', { + // Check if this is a Microsoft account that should use Graph API + const graphCheck = await shouldUseGraphAPI(user.id, account.id); + + let folders: string[]; + + if (graphCheck.useGraph && graphCheck.mailCredentialId) { + // Use Microsoft Graph API for Microsoft accounts + logger.debug('[COURRIER_SESSION] Fetching folders from Graph API for account', { + email: account.email, + mailCredentialId: graphCheck.mailCredentialId, + }); + + try { + const graphFolders = await fetchGraphMailFolders(graphCheck.mailCredentialId); + folders = graphFolders.map(f => f.displayName); + logger.debug('[COURRIER_SESSION] Fetched folders from Graph API for account', { + email: account.email, + count: folders.length, + }); + } catch (error) { + logger.error('[COURRIER_SESSION] Error fetching folders from Graph API', { + email: account.email, + error: error instanceof Error ? error.message : String(error), + }); + // Fallback to default folders + folders = ['Inbox', 'SentItems', 'Drafts', 'DeletedItems', 'JunkEmail']; + } + } else { + // Use IMAP for non-Microsoft accounts + logger.debug('[COURRIER_SESSION] Fetching folders from IMAP for account', { email: account.email, }); - return { - id: account.id, - email: account.email, - display_name: account.display_name, - color: account.color, - folders: ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'] - }; + const client = await getImapConnection(user.id, account.id); + if (!client) { + logger.warn('[COURRIER_SESSION] Failed to get IMAP connection for account', { + email: account.email, + }); + folders = ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk']; + } else { + folders = await getMailboxes(client); + logger.debug('[COURRIER_SESSION] Fetched folders from IMAP for account', { + email: account.email, + count: folders.length, + }); + } } - - const folders = await getMailboxes(client); - logger.debug('[COURRIER_SESSION] Fetched folders for account', { - email: account.email, - count: folders.length, - }); // Cache the folders in Redis await redis.set(