diff --git a/app/api/mail/mark-read/route.ts b/app/api/mail/mark-read/route.ts index c91b6ca9..2527400d 100644 --- a/app/api/mail/mark-read/route.ts +++ b/app/api/mail/mark-read/route.ts @@ -1,35 +1,20 @@ import { NextResponse } from 'next/server'; -import { cookies } from 'next/headers'; -import Imap from 'imap'; - -interface StoredCredentials { - email: string; - password: string; - host: string; - port: number; -} - -function getStoredCredentials(): StoredCredentials | null { - const cookieStore = cookies(); - const credentialsCookie = cookieStore.get('imap_credentials'); - - if (!credentialsCookie?.value) { - return null; - } - - try { - const credentials = JSON.parse(credentialsCookie.value); - if (!credentials.email || !credentials.password || !credentials.host || !credentials.port) { - return null; - } - return credentials; - } catch (error) { - return null; - } -} +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; +import { getImapClient } from '@/lib/imap'; +import { ImapFlow } from 'imapflow'; export async function POST(request: Request) { + let client: ImapFlow | null = null; try { + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + const { emailId, isRead } = await request.json(); if (!emailId || typeof isRead !== 'boolean') { @@ -43,108 +28,41 @@ export async function POST(request: Request) { const url = new URL(request.url); const folder = url.searchParams.get('folder') || 'INBOX'; - // Get stored credentials - const credentials = getStoredCredentials(); - if (!credentials) { - return NextResponse.json( - { error: 'No stored credentials found' }, - { status: 401 } - ); + try { + client = await getImapClient(); + await client.connect(); + await client.mailboxOpen(folder); + + // Fetch the email to get its UID + const message = await client.fetchOne(emailId.toString(), { + uid: true, + flags: true + }); + + if (!message) { + return NextResponse.json( + { error: 'Email not found' }, + { status: 404 } + ); + } + + // Update the flags + if (isRead) { + await client.messageFlagsAdd(message.uid.toString(), ['\\Seen'], { uid: true }); + } else { + await client.messageFlagsRemove(message.uid.toString(), ['\\Seen'], { uid: true }); + } + + return NextResponse.json({ success: true }); + } finally { + if (client) { + try { + await client.logout(); + } catch (e) { + console.error('Error during logout:', e); + } + } } - - return new Promise((resolve) => { - const imap = new Imap({ - user: credentials.email, - password: credentials.password, - host: credentials.host, - port: credentials.port, - tls: true, - tlsOptions: { rejectUnauthorized: false }, - authTimeout: 30000, - connTimeout: 30000 - }); - - const timeout = setTimeout(() => { - console.error('IMAP connection timeout'); - imap.end(); - resolve(NextResponse.json({ error: 'Connection timeout' })); - }, 30000); - - imap.once('error', (err: Error) => { - console.error('IMAP error:', err); - clearTimeout(timeout); - resolve(NextResponse.json({ error: 'IMAP connection error' })); - }); - - imap.once('ready', () => { - imap.openBox(folder, false, (err, box) => { - if (err) { - console.error(`Error opening box ${folder}:`, err); - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ error: `Failed to open folder ${folder}` })); - return; - } - - // Convert string ID to number - const numericId = parseInt(emailId, 10); - - const fetch = imap.fetch(numericId.toString(), { - bodies: '', - struct: true - }); - - fetch.on('message', (msg) => { - msg.once('attributes', (attrs) => { - const uid = attrs.uid; - if (!uid) { - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ error: 'No UID found for email' })); - return; - } - - if (isRead) { - imap.addFlags(uid, ['\\Seen'], (err) => { - if (err) { - console.error('Error marking as read:', err); - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ error: 'Failed to mark as read' })); - return; - } - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ success: true })); - }); - } else { - imap.removeFlags(uid, ['\\Seen'], (err) => { - if (err) { - console.error('Error marking as unread:', err); - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ error: 'Failed to mark as unread' })); - return; - } - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ success: true })); - }); - } - }); - }); - - fetch.on('error', (err) => { - console.error('Error fetching email:', err); - clearTimeout(timeout); - imap.end(); - resolve(NextResponse.json({ error: 'Failed to fetch email' })); - }); - }); - }); - - imap.connect(); - }); } catch (error) { console.error('Error marking email as read:', error); return NextResponse.json(