diff --git a/app/api/courrier/send/route.ts b/app/api/courrier/send/route.ts new file mode 100644 index 00000000..494c52c0 --- /dev/null +++ b/app/api/courrier/send/route.ts @@ -0,0 +1,81 @@ +import { NextResponse } from 'next/server'; +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; +import { prisma } from '@/lib/prisma'; +import nodemailer from 'nodemailer'; + +export async function POST(request: Request) { + try { + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); + } + + // Get credentials 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 } + ); + } + + // Get the email data from the request + const { to, cc, bcc, subject, body, attachments } = await request.json(); + + if (!to) { + return NextResponse.json( + { error: 'Recipient is required' }, + { status: 400 } + ); + } + + // Create SMTP transporter + const transporter = nodemailer.createTransport({ + host: credentials.host, + port: credentials.port, + secure: true, + auth: { + user: credentials.email, + pass: credentials.password, + }, + tls: { + rejectUnauthorized: false + } + }); + + // Prepare email options + const mailOptions = { + from: credentials.email, + to: to, + cc: cc || undefined, + bcc: bcc || undefined, + subject: subject || '(No subject)', + html: body, + attachments: attachments?.map((file: any) => ({ + filename: file.name, + content: file.content, + contentType: file.type + })) || [] + }; + + // Send the email + await transporter.sendMail(mailOptions); + + return NextResponse.json({ success: true }); + } catch (error) { + console.error('Error sending email:', error); + return NextResponse.json( + { error: 'Failed to send email' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/lib/imap.ts b/lib/imap.ts index 84fd2f6b..1f15788e 100644 --- a/lib/imap.ts +++ b/lib/imap.ts @@ -19,7 +19,7 @@ export async function getImapClient() { throw new Error('No mail credentials found. Please configure your email account.'); } - const client = new ImapFlow({ + return new ImapFlow({ host: credentials.host, port: credentials.port, secure: true, @@ -32,9 +32,6 @@ export async function getImapClient() { rejectUnauthorized: false } }); - - await client.connect(); - return client; } export async function moveEmails(emailIds: number[], targetFolder: string) { @@ -44,7 +41,8 @@ export async function moveEmails(emailIds: number[], targetFolder: string) { for (const id of emailIds) { const message = await imap.fetchOne(id.toString(), { uid: true }); if (message) { - await imap.messageMove(message.uid, targetFolder); + const uid = typeof message.uid === 'number' ? message.uid.toString() : message.uid; + await imap.messageMove(uid, targetFolder); } } } finally { @@ -52,17 +50,24 @@ export async function moveEmails(emailIds: number[], targetFolder: string) { } } -export async function markAsRead(emailIds: number[], isRead: boolean) { +export async function markAsRead(emailIds: (string | number)[], isRead: boolean) { const imap = await getImapClient(); - const lock = await imap.getMailboxLock('INBOX'); try { - for (const id of emailIds) { - const message = await imap.fetchOne(id.toString(), { uid: true }); - if (message) { - await imap.messageFlagsAdd(message.uid, isRead ? ['\\Seen'] : [], { uid: true }); + await imap.connect(); + const lock = await imap.getMailboxLock('INBOX'); + try { + for (const id of emailIds) { + const stringId = typeof id === 'number' ? id.toString() : id; + const message = await imap.fetchOne(stringId, { uid: true }); + if (message) { + const uid = typeof message.uid === 'number' ? message.uid.toString() : message.uid; + await imap.messageFlagsAdd(uid, isRead ? ['\\Seen'] : [], { uid: true }); + } } + } finally { + lock.release(); } } finally { - lock.release(); + await imap.logout(); } } \ No newline at end of file