import nodemailer from "nodemailer"; import { NextResponse } from "next/server"; import dns from "dns/promises"; import { isEmail, escape } from "validator"; const CONTACT_MESSAGE_FIELDS = { name: "Name", email: "Email", message: "Message" }; export const transporter = nodemailer.createTransport({ host: process.env.EMAIL_SERVER, port: parseInt(process.env.EMAIL_PORT ? process.env.EMAIL_PORT : "25"), secure: Boolean(process.env.EMAIL_SECURE ? process.env.EMAIL_SECURE : false), auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_PASS } }); const generateEmailContent = (data) => { const stringData = Object.entries(data).reduce( (str, [key, val]) => str + (key == "captchaToken" ? "" : `${CONTACT_MESSAGE_FIELDS[key] || key}: ${val.replace(/\n/g, "\n")} \n\n`), "" ); const htmlData = Object.entries(data).reduce( (str, [key, val]) => str + (key == "captchaToken" ? "" : `

${escape( CONTACT_MESSAGE_FIELDS[key] || key )}

${escape(val).replace( /\n/g, "
" )}

`), "" ); return { text: stringData, html: ` Contact Email

New Contact Message

${htmlData}
` }; }; export async function POST(req) { if (req.method !== "POST") { return NextResponse.json( { message: "Method Not Allowed" }, { status: 405 } ); } try { const data = await req.json(); console.log(data); // Verify hCaptcha token const hcaptchaResponse = await fetch( `https://api.hcaptcha.com/siteverify`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: `secret=${process.env.HCAPTCHA_SECRET}&response=${data.captchaToken}` } ); const hcaptchaData = await hcaptchaResponse.json(); if (!hcaptchaData.success) { return NextResponse.json( { message: "Captcha verification failed." }, { status: 400 } ); } // Check email address if (!isEmail(data.email)) { return NextResponse.json( { message: "Invalid email address" }, { status: 400 } ); } // Check email host const emailDomainMatch = data.email.match(/@([^@]+)/); const emailDomain = emailDomainMatch ? emailDomainMatch[1] : ""; let isEmailHostValid = false; try { const mxRecords = await dns.resolveMx(emailDomain); if (mxRecords.length > 0) { for (let i = 0; i < mxRecords.length; i++) { try { const aRecords = await dns.resolve4(mxRecords[i].exchange); if (aRecords.length > 0) { isEmailHostValid = true; break; } } catch (err) {} try { const aaaaRecords = await dns.resolve6(mxRecords[i].exchange); if (aaaaRecords.length > 0) { isEmailHostValid = true; break; } } catch (err) {} } } } catch (err) {} if (!isEmailHostValid) { return NextResponse.json( { message: "Email domain is misconfigured" }, { status: 400 } ); } await transporter.sendMail({ from: process.env.EMAIL_CONTACT_ADDRESS, to: process.env.EMAIL_CONTACT_DEST, subject: "Contact Email", ...generateEmailContent(data) }); return NextResponse.json( { message: "Email sent successfully" }, { status: 200 } ); } catch (error) { console.error("Error sending email:", error); return NextResponse.json( { message: "Internal Server Error" }, { status: 500 } ); } }