Newer
Older
express-blog / src / controllers / heplers / contactHelpers.js
// src/routes/helpers/contactHelpers.js
const HttpError = require("../../utils/HttpError");
const {
  captureSecurityData,
  logSecurityEvent,
} = require("../../utils/securityForensics");

function isReasonableLength(str, maxLen) {
  return (
    typeof str === "string" && str.trim().length > 0 && str.length <= maxLen
  );
}

function isValidInput(name, subject, message, emailResult) {
  return (
    emailResult.valid &&
    isReasonableLength(name, 100) &&
    isReasonableLength(subject, 150) &&
    isReasonableLength(message, 2000)
  );
}
async function handleInvalidInput(req, next, formData, emailResult) {
  const invalidData = captureSecurityData(req, {
    formData,
    failureReason: emailResult.message || "invalid_input",
    processingStep: "validation",
  });
  await logSecurityEvent(invalidData, "validation_failure");
  next(new HttpError("Invalid input", 400, invalidData));
}

function buildSecurityData(
  req,
  { formData, captchaProvided, clientData, step }
) {
  return captureSecurityData(req, {
    formData,
    captchaProvided,
    clientData,
    processingStep: step,
  });
}

async function logSubmission(securityData, threatAnalysis, formData) {
  await logSecurityEvent(
    {
      ...securityData,
      threatAnalysis,
      formData: {
        name: formData.name,
        email: formData.email,
        hasMessage: !!formData.message,
        hasSubject: !!formData.subject,
      },
    },
    "contact_submission"
  );
}

async function handleCaptchaFailure(
  securityData,
  threatAnalysis,
  next,
  reason
) {
  await logSecurityEvent(
    {
      ...securityData,
      threatAnalysis,
      validationResult: "failed",
      failureReason: reason,
    },
    "validation_failure"
  );
  next(new HttpError("Captcha verification failed", 400));
}

async function blockHighThreat(securityData, threatAnalysis) {
  await logSecurityEvent(
    {
      ...securityData,
      threatAnalysis,
      action: "blocked_high_threat",
    },
    "threat_blocked"
  );
}

function prepareEmail({ name, email, message, subject }, threatAnalysis) {
  const base = { name, email, message, subject };
  if (threatAnalysis.level === "medium") {
    base.securityFlag = `[SECURITY REVIEW REQUIRED - Score: ${threatAnalysis.score}]`;
  }
  return base;
}

async function logSuccess(securityData, threatAnalysis) {
  await logSecurityEvent(
    {
      ...securityData,
      threatAnalysis,
      processingResult: "success",
      emailSent: true,
    },
    "contact_success"
  );
}

async function logUnhandledError(req, err) {
  const errorData = captureSecurityData(req, {
    error: {
      message: err.message,
      stack: err.stack,
      name: err.name,
    },
    processingStep: "error_handling",
  });
  await logSecurityEvent(errorData, "contact_error");
}

module.expors = {
  isValidInput,
  handleInvalidInput,
  buildSecurityData,
  logSubmission,
  handleCaptchaFailure,
  blockHighThreat,
  prepareEmail,
  logSuccess,
  logUnhandledError,
};