import { NextResponse } from 'next/server'; import Imap from 'imap'; import nodemailer from 'nodemailer'; import { parseEmailHeaders } from '@/lib/email-parser'; import { cookies } from 'next/headers'; interface StoredCredentials { email: string; password: string; host: string; port: number; } interface Email { id: string; from: string; subject: string; date: Date; read: boolean; starred: boolean; body: string; } interface ImapBox { messages: { total: number; }; } interface ImapMessage { on: (event: string, callback: (data: any) => void) => void; once: (event: string, callback: (data: any) => void) => void; attributes: { uid: number; flags: string[]; size: number; }; body: { [key: string]: { on: (event: string, callback: (data: any) => void) => void; }; }; } interface ImapConfig { user: string; password: string; host: string; port: number; tls: boolean; authTimeout: number; connTimeout: number; debug?: (info: string) => void; } function getStoredCredentials(): StoredCredentials | null { const cookieStore = cookies(); const email = cookieStore.get('imap_email')?.value; const password = cookieStore.get('imap_password')?.value; const host = cookieStore.get('imap_host')?.value; const port = cookieStore.get('imap_port')?.value; if (!email || !password || !host || !port) { console.log('Missing credentials in cookies'); return null; } return { email, password, host, port: parseInt(port) }; } export async function GET() { try { const credentials = getStoredCredentials(); if (!credentials) { return NextResponse.json( { error: 'No stored credentials found' }, { status: 401 } ); } const imapConfig: ImapConfig = { user: credentials.email, password: credentials.password, host: credentials.host, port: credentials.port, tls: true, authTimeout: 10000, connTimeout: 10000, debug: (info: string) => console.log('IMAP Debug:', info) }; console.log('IMAP Config:', { ...imapConfig, password: '***' }); const imap = new Imap(imapConfig); const connectPromise = new Promise((resolve, reject) => { imap.once('ready', () => resolve(true)); imap.once('error', (err: Error) => reject(err)); imap.connect(); }); await connectPromise; const openBoxPromise = new Promise((resolve, reject) => { imap.openBox('INBOX', false, (err: Error | null, box: ImapBox) => { if (err) reject(err); else resolve(box); }); }); const box = await openBoxPromise; const fetchPromise = (imap: Imap, seqno: number): Promise => { return new Promise((resolve, reject) => { const f = imap.fetch(seqno, { bodies: ['HEADER', 'TEXT'] }); f.on('message', (msg: ImapMessage) => { resolve(msg); }); f.once('error', reject); }); }; const processMessage = (msg: ImapMessage): Promise => { return new Promise((resolve, reject) => { let body = ''; msg.body['TEXT'].on('data', (chunk: Buffer) => { body += chunk.toString('utf8'); }); msg.body['TEXT'].on('end', () => { const headers = parseEmailHeaders(body); resolve({ uid: msg.attributes.uid, flags: msg.attributes.flags, size: msg.attributes.size, ...headers }); }); msg.body['TEXT'].on('error', reject); }); }; const messages: any[] = []; for (let seqno = 1; seqno <= 10; seqno++) { const msg = await fetchPromise(imap, seqno); const processedMsg = await processMessage(msg); messages.push(processedMsg); } imap.end(); const emails: Email[] = messages.map((msg) => { return { id: msg.uid.toString(), from: msg.from, subject: msg.subject, date: msg.date, read: !msg.flags?.includes('\\Unseen'), starred: msg.flags?.includes('\\Flagged') || false, body: msg.body }; }); return NextResponse.json(emails); } catch (error) { console.error('Error fetching emails:', error); const status = error instanceof Error && error.message.includes('Invalid login') ? 401 : 500; return NextResponse.json( { error: error instanceof Error ? error.message : 'Failed to fetch emails' }, { status } ); } } export async function POST(request: Request) { try { const credentials = getStoredCredentials(); if (!credentials) { return NextResponse.json( { error: 'No stored credentials found' }, { status: 401 } ); } let body; try { body = await request.json(); } catch (error) { return NextResponse.json( { error: 'Invalid JSON in request body' }, { status: 400 } ); } const { to, subject, body: emailBody, attachments } = body; if (!to || !subject || !emailBody) { return NextResponse.json( { error: 'Missing required fields: to, subject, or body' }, { status: 400 } ); } const transporter = nodemailer.createTransport({ host: credentials.host, port: credentials.port, secure: true, auth: { user: credentials.email, pass: credentials.password, }, }); const mailOptions = { from: credentials.email, to, subject, text: emailBody, attachments: attachments || [], }; const info = await transporter.sendMail(mailOptions); console.log('Email sent:', info.messageId); return NextResponse.json({ success: true, messageId: info.messageId, message: 'Email sent successfully' }); } catch (error) { console.error('Error sending email:', error); return NextResponse.json( { error: error instanceof Error ? error.message : 'Failed to send email', details: error instanceof Error ? error.stack : undefined }, { status: 500 } ); } }