Cthulhu's Rage
Cthulhu's Rage

Reputation: 1

I can't fetch resources from localhost:5000

I want to create a Nodemailer frontend-backend app to send fully customizable email templates. I try to fetch the resource from:

'use client'
import React, { useState } from "react";

export default function Compose() {
  const [emailData, setEmailData] = useState({
    from: '',
    to: '',
    subject: '',
    message: '',
    attachments: [],
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setEmailData({ ...emailData, [name]: value });
  };

  const handleFileChange = (e: { target: { files: any; }; }) => {
    setEmailData({ ...emailData, attachments: [...e.target.files] });
  };

  const sendEmail = async () => {
    try {
      const formData = new FormData();
      formData.append('from', emailData.from);
      formData.append('to', emailData.to);
      formData.append('subject', emailData.subject);
      formData.append('message', emailData.message);
      emailData.attachments.forEach((file) => formData.append("attachments", file));

      console.log("Sending data:", formData);

      const response = await fetch('http://localhost:5000/send-email', {
        method: 'POST',
        body: formData,
      });

      if (response.ok) {
        alert("Email sent successfully");
      } else {
        alert('Failed to send the email');
      }
    } catch (error) {
      console.error('Error sending email', error);
    }
  };

  return (
    <div className="w-full bg-gray-100 py-2 px-4 absolute top-20 left-1 rounded-lg shadow-lg">
      <p className="text-lg font-semibold">New Message</p>
      <div className="border-b-2 border-gray-300 my-2"></div>
      <input
        className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
        placeholder="From"
        name='from'
        value={emailData.from}
        onChange={handleChange}
      />
      <input
        className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
        placeholder="To"
        name='to'
        value={emailData.to}
        onChange={handleChange}
      />
      <input
        className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
        placeholder="Subject"
        name='subject'
        value={emailData.subject}
        onChange={handleChange}
      />
      <textarea
        placeholder="Compose your email..."
        className="w-full h-40 p-2 mt-2 border rounded-md outline-none resize-none"
        name='message'
        value={emailData.message}
        onChange={handleChange}
      ></textarea>
      <div className="p-4 flex justify-end">
        <button className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700" onClick={sendEmail}>
          Send
        </button>
      </div>
    </div>
  );
}

As you can see I try to fetch the resource from (const response = await fetch('http://localhost:5000/send-email',) but it return a error in the the nodemailer app "Error: Missing credentials for "PLAIN" and I can't fetch the resource from my nodemailer.js. What you guys can recommend me to do?

import express from "express";
import multer from "multer";
import nodemailer from "nodemailer";
import cors from "cors";
import dotenv from "dotenv";

dotenv.config(); // Load environment variables

const app = express();
app.use(express.urlencoded({ extended: true })); // To parse URL-encoded bodies

// CORS setup to allow requests from your frontend
app.use(cors({
  origin: 'http://192.168.1.6:3000', // Allow this origin (adjust to match your client URL)
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

const upload = multer(); // Memory storage (adjust as needed)

app.post("/send-email", upload.array("attachments"), async (req, res) => {
  const { from, to, subject, message } = req.body;
  const attachments = req.files.map((file) => ({
    filename: file.originalname,
    content: file.buffer, // Use buffer instead of path
  }));

  const transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 587, // Port for STARTTLS
    secure: false,  // Use false for STARTTLS
    auth: {
      user: process.env.SMTP_USER,
      pass: process.env.SMTP_PASSWORD, // Ensure app password here if using 2FA
    },
    tls: {
      rejectUnauthorized: false,  // Disable certificate validation (useful for dev)
    },
  });

  const mailOptions = {
    from: from,          // Dynamic 'from' field from the request body
    to: to,              // Dynamic 'to' field from the request body
    subject: subject,    // Dynamic 'subject' field from the request body
    text: message,       // Dynamic 'message' field from the request body
    attachments: attachments,  // Attachments if provided
  };

  try {
    await transporter.sendMail(mailOptions);
    res.status(200).send("Email Sent!");
  } catch (error) {
    console.error(error);
    res.status(500).send("Error sending email");
  }
});

app.listen(5000, () => console.log("Server running on port 5000"));

Upvotes: -1

Views: 35

Answers (0)

Related Questions