import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; import { prisma } from '@/lib/prisma'; import { ImapFlow } from 'imapflow'; export async function POST(request: Request) { let client: ImapFlow | null = null; try { // Get the session and validate it const session = await getServerSession(authOptions); console.log('Session:', session); if (!session?.user?.id) { console.error('No session or user ID found'); return NextResponse.json( { error: 'Unauthorized' }, { status: 401 } ); } // Get the request body const { emailId, isRead } = await request.json(); console.log('Request body:', { emailId, isRead }); if (!emailId || typeof isRead !== 'boolean') { console.error('Invalid request parameters:', { emailId, isRead }); return NextResponse.json( { error: 'Invalid request parameters' }, { status: 400 } ); } // Get the current folder from the request URL const url = new URL(request.url); const folder = url.searchParams.get('folder') || 'INBOX'; console.log('Folder:', folder); // Get credentials directly from database const credentials = await prisma.mailCredentials.findUnique({ where: { userId: session.user.id } }); if (!credentials) { return NextResponse.json( { error: 'No mail credentials found. Please configure your email account.' }, { status: 401 } ); } // Create IMAP client client = new ImapFlow({ host: credentials.host, port: credentials.port, secure: true, auth: { user: credentials.email, pass: credentials.password, }, logger: false, emitLogs: false, tls: { rejectUnauthorized: false }, disableAutoIdle: true }); try { await client.connect(); // Open the mailbox const mailbox = await client.mailboxOpen(folder); console.log(`Mailbox opened: ${folder}, total messages: ${mailbox.exists}`); // Scan through messages in chunks to find the one with the right UID let foundMessage = false; const chunkSize = 10; for (let i = 1; i <= mailbox.exists; i += chunkSize) { const endIdx = Math.min(i + chunkSize - 1, mailbox.exists); const range = `${i}:${endIdx}`; console.log(`Scanning messages ${range} to find UID ${emailId}`); // Fetch messages in chunks with UID const messages = client.fetch(range, { uid: true, flags: true }); for await (const message of messages) { if (message.uid.toString() === emailId) { console.log(`Found matching message with UID ${emailId}`); // Get the sequence number (i is the start of the range) const seqNum = i + message.seq - 1; console.log(`Message sequence number: ${seqNum}`); // Update the flags based on the isRead parameter if (isRead && !message.flags.has('\\Seen')) { console.log(`Marking message ${emailId} as read`); await client.messageFlagsAdd(seqNum.toString(), ['\\Seen']); } else if (!isRead && message.flags.has('\\Seen')) { console.log(`Marking message ${emailId} as unread`); await client.messageFlagsRemove(seqNum.toString(), ['\\Seen']); } else { console.log(`Message ${emailId} already has the correct read status`); } foundMessage = true; break; } } if (foundMessage) { break; } } if (!foundMessage) { console.error(`Email with UID ${emailId} not found`); return NextResponse.json( { error: 'Email not found' }, { status: 404 } ); } return NextResponse.json({ success: true }); } finally { if (client) { try { await client.logout(); } catch (e) { console.error('Error during logout:', e); } } } } catch (error) { console.error('Error marking email as read:', error); return NextResponse.json( { error: 'Failed to mark email as read' }, { status: 500 } ); } }