import nodemailer from 'nodemailer'; import { getCredentialsFromSession, decryptCredentials } from '~/server/utils/encryption'; import { uploadFile } from '~/server/utils/minio'; export default defineEventHandler(async (event) => { const xTagHeader = getRequestHeader(event, "x-tag"); if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) { throw createError({ statusCode: 401, statusMessage: "unauthenticated" }); } try { const body = await readBody(event); const { to, subject, body: emailBody, interestId, sessionId, includeSignature = true, signatureConfig } = body; if (!to || !subject || !emailBody || !sessionId) { throw createError({ statusCode: 400, statusMessage: "To, subject, body, and sessionId are required" }); } // Get encrypted credentials from session const encryptedCredentials = getCredentialsFromSession(sessionId); if (!encryptedCredentials) { throw createError({ statusCode: 401, statusMessage: "Email credentials not found. Please reconnect." }); } // Decrypt credentials const { email, password } = decryptCredentials(encryptedCredentials); // Get user info for signature const defaultName = email.split('@')[0].replace('.', ' ').replace(/\b\w/g, l => l.toUpperCase()); // Build email signature with customizable fields const sig = signatureConfig || {}; const contactLines = sig.contactInfo ? sig.contactInfo.split('\n').filter((line: string) => line.trim()).join('
') : ''; const signature = includeSignature ? `

${sig.name || defaultName}
${sig.title || 'Sales & Marketing Director'}
${sig.company || 'Port Nimara'}
${contactLines ? contactLines + '
' : ''} ${sig.email || email}

Port Nimara
The information in this message is confidential and may be privileged.
It is intended for the addressee alone.
If you are not the intended recipient it is prohibited to disclose, use or copy this information.
Please contact the Sender immediately should this message have been transmitted incorrectly.
` : ''; // Convert plain text body to HTML with line breaks const htmlBody = emailBody.replace(/\n/g, '
') + signature; // Configure SMTP transport const transporter = nodemailer.createTransport({ host: process.env.NUXT_EMAIL_SMTP_HOST || 'mail.portnimara.com', port: parseInt(process.env.NUXT_EMAIL_SMTP_PORT || '587'), secure: false, // false for STARTTLS auth: { user: email, pass: password }, tls: { rejectUnauthorized: false // Allow self-signed certificates } }); // Send email const fromName = sig.name || defaultName; const info = await transporter.sendMail({ from: `"${fromName}" <${email}>`, to: to, subject: subject, text: emailBody, // Plain text version html: htmlBody // HTML version with signature }); // Store email in MinIO for thread history if (interestId) { try { const emailData = { id: info.messageId, from: email, to: to, subject: subject, body: emailBody, html: htmlBody, timestamp: new Date().toISOString(), direction: 'sent', interestId: interestId }; const objectName = `client-emails/interest-${interestId}/${Date.now()}-sent.json`; const buffer = Buffer.from(JSON.stringify(emailData, null, 2)); await uploadFile( objectName, buffer, 'application/json' ); } catch (storageError) { console.error('Failed to store email in MinIO:', storageError); // Continue even if storage fails } } return { success: true, message: "Email sent successfully", messageId: info.messageId }; } catch (error) { console.error('Failed to send email:', error); if (error instanceof Error) { throw createError({ statusCode: 500, statusMessage: `Failed to send email: ${error.message}` }); } else { throw createError({ statusCode: 500, statusMessage: "An unexpected error occurred", }); } } });