Nodemailer doesn't work correctly Full React &

2019-08-08 09:53发布

问题:

I have a React website that is just plain, informative website for the Homeless community. It also has the contact us form pages with Nodemailer in Nodejs. It's been deployed in Ubuntu 16.04.

But now I want to add Full MERN stack to the website along with those informative web pages.

Its has Login and Register with JWT and Passport. When I logged into the website and trying to use the contact us form, doesn't send the mail. If logout, Nodemailer works perfectly. I don't know if it's something to do with JWT/Passport, CORS, or Port???

Error:

Access to XMLHttpRequest at 'http://lovechangingtheworld.org:8000/sendcontact' from origin 'http://lovechangingtheworld.org' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

Nodemailer code:

let transport = {
  host: "smtp.gmail.com",
  auth: {
    user: creds.USER,
    pass: creds.PASS
  }
};
var transporter = nodemailer.createTransport(transport);
transporter.verify((error, success) => {
    if (error) {
        console.log(error);
    } else {
        console.log('Server is ready to take messages');
    }
});

app.use((request, response, next) => {
  response.header("Access-Control-Allow-Origin", "*");
  response.header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
  response.header("Access-Control-Allow-Headers", "Content-Type");
  next();
});

app.post("/sendcontact", (req, res, next) => {
  console.log("at app.post!!!!!!!!!!!!!!!!!!!")
  var first_name = req.body.first_name;
  var last_name = req.body.last_name;
  var phone = req.body.phone;
  var email = req.body.email;
  var comments = req.body.comments;
  // setup email data with unicode symbols
    let mailOptions = { from: `${first_name} ${last_name}`, to: "info@lovechangingtheworld.org", subject: `LCTW WEBSITE Add ${first_name} ${last_name} to Mailing List!`, text: `Name: ${first_name} ${last_name} \nPhone: ${phone} \nEmail: ${email} \nMessage: ${comments}` };

  // send mail with defined transport object
  transporter.sendMail(mailOptions, (error, data) => {
    console.log("at sendMAIL!!!!!!!!!!!!!!!!!!!");
    if (error) {
        return console.log(error);
    } else {
        console.log("Message sent!")
        res.json({ msg: "success" });
    }
  });
});

React code:

App.js

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import jwt_decode from "jwt-decode";
import setAuthToken from "./utils/setAuthToken";
import { setCurrentUser, logoutUser } from "./actions/authActions";
// import { clearCurrentProfile } from "./actions/profileActions";


import { Provider } from "react-redux";
import store from "./store";

import PrivateRoute from "./components/common/PrivateRoute";

import Login from "./components/auth/Login";

import Register from "./components/auth/Register";
import Users from "./components/auth/Users";
import EventfulForm from "./components/eventfuls/EventfulForm";


import Navbar from "./components/layout/Navbar";
import Footer from "./components/layout/Footer";
import Landing from "./components/layout/Landing";
import OurMission from "./components/pages/OurMission";
import Events from "./components/pages/Events";
import PastEvents from "./components/pages/PastEvents";
import Founder from "./components/pages/Founder";
import Executive from "./components/pages/Executive";
import Donations from "./components/pages/Donations";
import Shop from "./components/pages/Shop";
import Fundraisers from "./components/pages/Fundraisers";
import Programs from "./components/pages/Programs";
import Mailing from "./components/pages/Mailing";
import SponsorForm from "./components/pages/SponsorForm";
import VolunteerForm from "./components/pages/VolunteerForm";
import HomelessForm from "./components/pages/HomelessForm";
import Services from "./components/pages/Services";
import Staff from "./components/pages/Staff";
import Resources from "./components/pages/Resources";
import Membership from "./components/pages/Membership";
import Dashboard from "./components/dashboard/Dashboard";
import Eventful from "./components/eventful/Eventful";

import "./App.css";

// http://www.bgmanteca.org/newpage-1
// https://lovechangingtheworld.weebly.com/


// Check for token
if (localStorage.jwtToken) {
 // Set auth token header auth
 setAuthToken(localStorage.jwtToken);
 // Decode token and get user info and exp
 const decoded = jwt_decode(localStorage.jwtToken);
 // Set user and isAuthenticated
 store.dispatch(setCurrentUser(decoded));

 // Check for expired token
 const currentTime = Date.now() / 1000;
 if (decoded.exp < currentTime) {
   // Logout user
   store.dispatch(logoutUser());
   // Redirect to login
   window.location.href = "/login";
 }
}

class App extends Component {
  render() {
    return <Provider store={store}>
        <Router>
          <div className="App">
            <Navbar />

            <Route exact path="/" component={Landing} />
            <div className="container text-justify">
            <Route exact path="/ourmission" component={OurMission} />
            <Route exact path="/services" component={Services} />
            <Route exact path="/events" component={Events} />
            <Route exact path="/pastevents" component={PastEvents} />
            <Route exact path="/founder" component={Founder} />
            <Route exact path="/executive" component={Executive} />
            <Route exact path="/staff" component={Staff} />
              <Route exact path="/donations" component={Donations} />
              <Route exact path="/shop" component={Shop} />
              <Route exact path="/fundraisers" component={Fundraisers} />
              <Route exact path="/programs" component={Programs} />
              <Route exact path="/mailing" component={Mailing} />
              <Route exact path="/sponsorform" component={SponsorForm} />
              <Route exact path="/volunteerform" component={VolunteerForm} />
              <Route exact path="/homelessform" component={HomelessForm} />
              <Route exact path="/resources" component={Resources} />
              <Route exact path="/membership" component={Membership} />

              <Route exact path="/register" component={Register} />
              <Route exact path="/login" component={Login} />
              <Switch>
                <Route exact path="/dashboard" component={Dashboard} />
            </Switch>
              <Switch>
              <PrivateRoute exact path="/users" component={Users} />
              </Switch>

              <Switch>
              <Route exact path="/eventfuls" component={EventfulForm} />
              </Switch>
              <Switch>
                <PrivateRoute exact path="/eventful/:id" component={Eventful} />
              </Switch>
            </div>
            <Footer />
          </div>
        </Router>
      </Provider>;
  }
}

export default App;

Contact us form JSX

import React, { Component } from "react";
import axios from "axios";
import "../css/Mailing.css";

class Contact extends Component {
  constructor(props) {
    super(props);
    this.state = {
      disabled: false
    };
  }

  handleSubmit = async e => {
    this.setState({
      disabled: true
    });
    e.preventDefault();
    const first_name = document.getElementById("first_name").value;
    const last_name = document.getElementById("last_name").value;
    const phone = document.getElementById("phone").value;
    const email = document.getElementById("email").value;
    const comments = document.getElementById("comments").value;
    var reg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

    // eslint-disable-next-line
    var phoneReg = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;

    if (first_name && last_name && phoneReg.test(phone) && reg.test(email)) {
      var parsedPhone = "";
      for (var i = 0; i < phone.length; i++) {
        if (phone[i] >= 0 && phone[i] <= 9) {
          parsedPhone += phone[i];
        }
      }
      console.log(parsedPhone);
      axios({
        method: "POST",
        url: "http://lovechangingtheworld.org:8000/sendcontact",
        data: {
          first_name: first_name,
          last_name: last_name,
          phone: parsedPhone,
          email: email,
          comments: comments
        }
      })
        .then(response => {
          if (response.data.msg === "success") {
            alert("Message Sent");
            this.resetForm();
            this.setState({
              disabled: false
            });
          } else {
            alert("Message failed to send");
            this.setState({
              disabled: false
            });
          }
        })
        .catch(function(error) {
          console.log(error);
        });
    } else if (
      first_name &&
      last_name &&
      phoneReg.test(phone) &&
      !reg.test(email)
    ) {
      this.setState({
        disabled: false
      });
      alert("Please enter a valid email");
    } else if (
      first_name &&
      last_name &&
      !phoneReg.test(phone) &&
      reg.test(email)
    ) {
      this.setState({
        disabled: false
      });
      alert("Please enter valid phone number");
    } else {
      this.setState({
        disabled: false
      });
      alert("Please fill in the required fields");
    }
  };
  resetForm() {
    document.getElementById("contact-form").reset();
  }

  render() {
    return (
      <div className="contact">
        <h1 className="display-1">Contact Us</h1>
        <p className="lead">
          Please feel free to leave your contact info here so we can keep you
          updated with our upcoming events and much more.
        </p>
        <form
          id="contact-form"
          onSubmit={this.handleSubmit.bind(this)}
          method="POST"
        >
          <div className="form-group">
            <p>Name*</p>
            <div className="row">
              <div className="col">
                <input
                  id="first_name"
                  type="text"
                  className="form-control"
                  placeholder="First"
                  name="first_name"
                />
              </div>
              <div className="col">
                <input
                  id="last_name"
                  type="text"
                  className="form-control"
                  placeholder="Last"
                  name="last_name"
                />
              </div>
            </div>
          </div>
          <div className="form-group">
            <p>Phone*</p>
            <input
              id="phone"
              type="text"
              className="form-control"
              placeholder=""
              name="phone"
            />
          </div>

          <div className="form-group">
            <p>Email*</p>
            <input
              id="email"
              type="text"
              className="form-control"
              placeholder=""
              name="email"
            />
          </div>

          <div className="form-group">
            <p>Comments</p>
            <textarea
              id="comments"
              className="form-control"
              placeholder=""
              rows="3"
              name="comments"
            />
          </div>

          <button
            disabled={this.state.disabled}
            type="submit"
            className="btn btn-primary"
          >
            Submit
          </button>
        </form>
        <p className="lead">*Required</p>

        <iframe
          title="NMCC"
          src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3171.1426987778764!2d-121.82791258487573!3d37.362800243527666!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x808fcd693018f1c5%3A0x85f2b0df85498748!2s3098+Florence+Ave%2C+San+Jose%2C+CA+95127!5e0!3m2!1sen!2sus!4v1533251610484"
          width="100%"
          height="450"
          frameBorder="0"
          allowFullScreen
        />

        <div className="row">
          <div className="col text-left">
            <p className="lead">3098 Florence Ave, San Jose, CA 95127</p>
            <p className="lead">Email: info@lovechangingtheworld.org</p>
            <p className="lead">Phone: 1 (408) 259-1008</p>
          </div>
          <div className="col">
            <form action="https://goo.gl/maps/vkXWFWQsZCy" target="_blank">
              <input
                type="submit"
                className="btn btn-secondary float-right"
                value="Find Us"
              />
            </form>
          </div>
        </div>
      </div>
    );
  }
}

export default Contact;