import { NextResponse } from 'next/server'; import Imap from 'imap'; import { simpleParser } from 'mailparser'; // IMAP configuration const imapConfig = { user: 'contact@governance-labs.org', password: 'K!376c$6H#kMknM', host: 'mail.infomaniak.com', port: 993, tls: true, tlsOptions: { rejectUnauthorized: false } }; interface ImapMessage { header: { from?: string[]; to?: string[]; subject?: string[]; date?: string[]; [key: string]: string[] | undefined; }; body: string; attributes: { flags: string[]; }; } // Helper function to create a promise-based IMAP connection function createImapConnection() { return new Promise((resolve, reject) => { const imap = new Imap(imapConfig); imap.once('ready', () => resolve(imap)); imap.once('error', (err: Error) => reject(err)); imap.connect(); }); } // Helper function to promisify the message fetching function fetchMessages(imap: Imap, box: string): Promise { return new Promise((resolve, reject) => { imap.openBox(box, false, (err, mailbox) => { if (err) { reject(err); return; } // Search for all messages imap.search(['ALL'], (err, results) => { if (err) { reject(err); return; } // No messages found if (!results || !results.length) { resolve([]); return; } const fetch = imap.fetch(results, { bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE)', 'TEXT'], struct: true }); const messages: ImapMessage[] = []; fetch.on('message', (msg) => { const message: Partial = {}; msg.on('body', (stream, info) => { let buffer = ''; stream.on('data', (chunk) => { buffer += chunk.toString('utf8'); }); stream.once('end', () => { if (info.which === 'TEXT') { message.body = buffer; } else { message.header = Imap.parseHeader(buffer); } }); }); msg.once('attributes', (attrs) => { message.attributes = attrs; }); msg.once('end', () => { messages.push(message as ImapMessage); }); }); fetch.once('error', (err) => { reject(err); }); fetch.once('end', () => { resolve(messages); }); }); }); }); } export async function GET(request: Request) { try { const imap = await createImapConnection() as Imap; const messages = await fetchMessages(imap, 'INBOX'); // Process messages into the format expected by the frontend const processedMessages = messages.map((msg: ImapMessage, index: number) => ({ id: index + 1, accountId: 1, from: msg.header.from?.[0] || '', fromName: (msg.header.from?.[0] || '').split('<')[0].trim(), to: msg.header.to?.[0] || '', subject: msg.header.subject?.[0] || '', body: msg.body || '', date: msg.header.date?.[0] || new Date().toISOString(), read: !(msg.attributes.flags.indexOf('\\Seen') < 0), starred: !(msg.attributes.flags.indexOf('\\Flagged') < 0), category: 'inbox' })); imap.end(); return NextResponse.json({ messages: processedMessages }); } catch (error) { console.error('Error fetching emails:', error); return NextResponse.json({ error: 'Failed to fetch emails' }, { status: 500 }); } } // Add endpoint to get mailboxes export async function POST(request: Request) { try { const imap = await createImapConnection() as Imap; const mailboxes = await new Promise((resolve, reject) => { imap.getBoxes((err, boxes) => { if (err) reject(err); resolve(boxes); }); }); imap.end(); return NextResponse.json({ mailboxes }); } catch (error) { console.error('Error fetching mailboxes:', error); return NextResponse.json({ error: 'Failed to fetch mailboxes' }, { status: 500 }); } }