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}
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",
});
}
}
});