diff --git a/app/actions/contact.ts b/app/actions/contact.ts index f1ee3c57..73deff12 100644 --- a/app/actions/contact.ts +++ b/app/actions/contact.ts @@ -86,6 +86,7 @@ export async function sendContactFormAction(formData: FormData) { ); if (!isTestSubmission) { + logger.info('Sending internal notification', { recipients: config.mail.recipients }); const notificationResult = await sendEmail({ replyTo: email, subject: notificationSubject, @@ -97,14 +98,18 @@ export async function sendContactFormAction(formData: FormData) { messageId: notificationResult.messageId, }); } else { - logger.error('Notification email FAILED', { + logger.error('Notification email DELIVERY FAILED', { error: notificationResult.error, subject: notificationSubject, - email, + recipients: config.mail.recipients, }); services.errors.captureException( new Error(`Notification email failed: ${notificationResult.error}`), - { action: 'sendContactFormAction_notification', email }, + { + action: 'sendContactFormAction_notification', + email, + recipients: config.mail.recipients + }, ); } } else { @@ -121,6 +126,7 @@ export async function sendContactFormAction(formData: FormData) { ); if (!isTestSubmission) { + logger.info('Sending customer confirmation', { to: email }); const confirmationResult = await sendEmail({ to: email, subject: confirmationSubject, @@ -132,7 +138,7 @@ export async function sendContactFormAction(formData: FormData) { messageId: confirmationResult.messageId, }); } else { - logger.error('Confirmation email FAILED', { + logger.error('Confirmation email DELIVERY FAILED', { error: confirmationResult.error, subject: confirmationSubject, to: email, diff --git a/lib/env.ts b/lib/env.ts index f6a4ed1d..b989cc84 100644 --- a/lib/env.ts +++ b/lib/env.ts @@ -42,7 +42,7 @@ const envExtension = { MAIL_USERNAME: z.string().optional(), MAIL_PASSWORD: z.string().optional(), MAIL_FROM: z.string().optional(), - MAIL_RECIPIENTS: z.string().optional(), + MAIL_RECIPIENTS: z.string().trim().optional(), }; /** diff --git a/lib/mail/mailer.ts b/lib/mail/mailer.ts index ffe8f5d1..d766b7dc 100644 --- a/lib/mail/mailer.ts +++ b/lib/mail/mailer.ts @@ -32,16 +32,27 @@ interface SendEmailOptions { } export async function sendEmail({ to, replyTo, subject, html }: SendEmailOptions) { - const recipients = to || config.mail.recipients; const logger = getServerAppServices().logger.child({ component: 'mailer' }); + + // Resolve recipients: priority to 'to' override, fallback to global MAIL_RECIPIENTS + const resolvedTo = to || config.mail.recipients; + + // Normalize recipients (handle arrays or comma-strings) + const recipients = Array.isArray(resolvedTo) + ? resolvedTo.join(', ') + : (resolvedTo?.toString() || ''); - if (!recipients) { - logger.error('No email recipients configured (MAIL_RECIPIENTS is empty and no "to" provided)', { subject }); + if (!recipients || recipients.trim() === '') { + logger.error('Email delivery ABORTED: No recipients configured', { + subject, + providedTo: to, + configRecipients: config.mail.recipients + }); return { success: false as const, error: 'No recipients configured' }; } if (!config.mail.from) { - logger.error('MAIL_FROM is not configured — cannot send email', { subject, recipients }); + logger.error('Email delivery ABORTED: MAIL_FROM is missing', { subject, recipients }); return { success: false as const, error: 'MAIL_FROM is not configured' }; } @@ -53,14 +64,36 @@ export async function sendEmail({ to, replyTo, subject, html }: SendEmailOptions html, }; - try { - const info = await getTransporter().sendMail(mailOptions); - logger.info('Email sent successfully', { messageId: info.messageId, subject, recipients }); + const transporter = getTransporter(); + logger.info('Attempting to send email via SMTP', { + host: config.mail.host, + subject, + recipients, + hasReplyTo: !!replyTo + }); + + const info = await transporter.sendMail(mailOptions); + + logger.info('Email sent successfully', { + messageId: info.messageId, + subject, + recipients, + response: info.response + }); + return { success: true, messageId: info.messageId }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); - logger.error('Error sending email', { error: errorMsg, subject, recipients }); + logger.error('SMTP Transport failed', { + error: errorMsg, + subject, + recipients, + config: { + host: config.mail.host, + user: config.mail.user ? '***' : 'not set' + } + }); return { success: false, error: errorMsg }; } }