Newer
Older
express-blog / src / utils / sendContactMail.js
// src/utils/sendContactMail.js
const transporter = require("./transporter");
const path = require("path");
const fs = require("fs").promises;
const { validateAndSanitizeEmail } = require("../utils/emailValidator");
const { winstonLogger } = require("../utils/logging");
const { mail } = require("../config/loader");

// Fixed sanitizeInput function
function sanitizeInput(input) {
  // Handle null, undefined, and non-string inputs safely
  if (input === undefined) {
    return "undefined";
  }
  if (input == null) {
    return "null";
  }
  // if (input == "null") {
  //   return "";
  // }

  try {
    return String(input)
      .replace(/[\r\n<>]/g, "")
      .trim();
  } catch (error) {
    // If String() conversion fails, return empty string
    return "";
  }
}

const HttpError = require("./HttpError");

async function sendContactMail({ name, email, subject, message }) {
  const cleanName = sanitizeInput(name);
  const cleanSubject = sanitizeInput(subject || DEFAULT_SUBJECT);
  const cleanMessage = sanitizeInput(message);

  const {
    valid,
    email: sanitizedEmail,
    message: errorMessage,
  } = validateAndSanitizeEmail(email);

  if (!valid) throw new HttpError(errorMessage, 400);

  const mailData = {
    from: `"Contact Form" <no-reply@${mail.domain}>`,
    to: mail.user,
    replyTo: `"${cleanName}" <${sanitizedEmail}>`,
    subject: cleanSubject,
    text: cleanMessage,
  };
  const emailLogEntry = {
    timestamp: new Date().toISOString(),
    name: cleanName,
    email: sanitizedEmail,
    subject: cleanSubject,
    message: cleanMessage,
  };
  try {
    const data = await fs.readFile(EMAIL_LOG_PATH, "utf-8");
    const logs = JSON.parse(data);
    logs.push(emailLogEntry);
    await fs.writeFile(EMAIL_LOG_PATH, JSON.stringify(logs, null, 2));
  } catch (err) {
    winstonLogger.error("Failed to log email to file:", err);
    throw err;
  }

  return transporter.sendMail(mailData);
}

module.exports.sendContactMail = sendContactMail;
module.exports.sanitizeInput = sanitizeInput;