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; } } export async function POST(request: Request) { try { const { emailId, isRead } = await request.json(); if (!emailId || typeof isRead !== 'boolean') { 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'; // Get stored credentials const credentials = getStoredCredentials(); if (!credentials) { return NextResponse.json( { error: 'No stored credentials found' }, { status: 401 } ); } 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( { error: 'Failed to mark email as read' }, { status: 500 } ); } }