Nodemailer - redirecting to success page - javascript

Trying to get my page to redirect from a node.js and express.js page after sending an email. The message gets sent and I am getting the console.log() in my terminal (using morgan for logging) but it's not redirecting me to the success page and I'm not getting a console.log error in the browser. It just stalls and then i get a localhost didn't send any data error. Never used nodemailer before but I managed to get the message sent, I'm just having a problem redirecting to a new page.
Thanks!!
//Success html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
// Form Box
<form action="/contact" id="contact-form" method="post" role="form">
<fieldset>
<label for="name">Name *</label>
<input id="name" name="name" type="text" placeholder="Your name" required="required">
<label for="email">Email *</label>
<input id="email" name="email" type="text" placeholder="Your email" required="required">
<label for="message">Message *</label>
<textarea id="message" name="message" placeholder="Enter your message here" rows="3" required="required"></textarea>
<button type="submit">Submit</button>
</fieldset>
</form>
// Success HTML route
app.get('/success', function(req,res){
res.sendFile(__dirname + '/views' + '/success.html');
});
//nodemailer
// POST route from contact form
app.post('/contact', function (req, res) {
let mailOpts, smtpTrans;
smtpTrans = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_PASS
}
});
mailOpts = {
from: req.body.name + ' <' + req.body.email + '>',
to: process.env.GMAIL_USER,
subject: 'New message from Portfolio site',
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`
};
smtpTrans.sendMail(mailOpts, function (error, res) {
if (error) {
return console.log(error);
}
else {
console.log('success');
res.redirect('/success');
}
});
});

wondering if you still stuck on the issue but in case, below worked for me.
app.post('/contact', function (req, res) {
let mailOpts, smtpTrans;
smtpTrans = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_PASS
}
});
mailOpts = {
from: req.body.name + ' <' + req.body.email + '>',
to: process.env.GMAIL_USER,
subject: 'New message from Portfolio site',
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`
};
smtpTrans.sendMail(mailOpts, function (error, res) {
if (error) {
return console.log(error);
}
else {
console.log('success');
// NOT HERE res.redirect('/success');
}
});
res.redirect('/success'); // I MOVED THE REDIRECTING CODE HERE AND WORKED
});

Related

sending email with nodemailer

I'm trying to create a simple node server that sends emails with nodemailer
let app = require('express')();
app.use(require('body-parser').urlencoded());
const CONTACT_ADDRESS = 'email#email.com';
var mailer = require('nodemailer').createTransport({
service: 'mail.ee',
auth: {
user: 'test#test.com',
pass: 'password',
}
});
app.post('/contact', function(req, res) {
mailer.sendMail({
from: req.body.from,
to: '[CONTACT_ADDRESS]',
subject: req.body.subject || '[No subject]',
html: req.body.message || '[No message]',
}, function(err, info) {
if (err) return res.status(500).send(err);
res.json({success: true});
})
});
//Service is listening to port 3000
app.listen(3000, function(){
console.log("Service is running on port 3000...");
});
and the contact form is as follows:
<form method="post" action="http://localhost:3000/contact">
<label>Your e-mail</label>
<input type="text" name="from">
<label>Subject</label>
<input type="text" name="subject">
<label>Message</label>
<textarea name="body"></textarea>
<input type="submit" value="Submit">
</form>
When ever I press on submit button I get:
JSON.stringify(value); TypeError: Converting circular structure to
JSON
What does it mean? How can I overcome it?
res.send method trying to stringify your err object, but your err object cant be stringified, because not a standard error object. Try to output this err object to see and decide how to handle it.
For example you can use
if (err) return res.status(500).send(err.reason);
istead
if (err) return res.status(500).send(err);

Nodemailer application sends email on page refresh

Building a simple form to allow users to send me an email. The form properly sends the email on submit. However, I also receive an email when the page is refreshed on my browser. What gives? I'm not sure if the issue is in my server.js file or the index.ejs. Is the submit button being triggered somehow on the page load?
Here's the server.js file:
var express = require('express'),
path = require('path'),
nodeMailer = require('nodemailer'),
bodyParser = require('body-parser');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static(__dirname));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
var port = 3000;
app.get('/', function (req, res) {
res.render('index');
});
app.post('/contact', function (req, res) {
let transporter = nodeMailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: '****#gmail.com',
pass: '****'
}
});
let mailOptions = {
from: req.body.name + ' <' + req.body.email + '>', // sender address
to: '****#gmail.com', // list of receivers
subject: 'New message test', // Subject line
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`, // plain text body
html: '<b>Email Test</b>' // html body
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message %s sent: %s', info.messageId, info.response);
res.render('index');
});
});
app.listen(port, function(){
console.log('Server is running at port: ',port);
});
And the index.ejs:
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<form action="/contact" id="contact-form" method="post" role="form">
<fieldset>
<label for="name">Name *</label>
<input id="name" name="name" type="text" placeholder="Your name" required="required">
<label for="email">Email *</label>
<input id="email" name="email" type="text" placeholder="Your email" required="required">
<label for="message">Message *</label>
<textarea id="message" name="message" placeholder="Enter your message here" rows="3" required="required"></textarea>
<button type="submit">Submit</button>
</fieldset>
</form>
</body>
</html>
If you open the route / it send the email straight away?
This is property of your browser, after submitting <FORM> for first time, every time you will refresh same request will be send.
Why? As your next page is result of what you did in previous page, check your url on browser being changed to localhost:3000/contact, this is not a GET method, but a post, this has occurred as you have rendered a page on POST call. Even though if a different ejs would have rendered, on refresh same call to POST: contact would have been send.
Only solution is to use single-page application.
Example
server.js:
```
var express = require('express'),
path = require('path'),
nodeMailer = require('nodemailer'),
bodyParser = require('body-parser');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static(__dirname));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
var port = 3000;
app.get('/', function (req, res) {
res.render('index');
});
app.post('/contact', function (req, res) {
let transporter = nodeMailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: '****#gmail.com',
pass: '****'
}
});
let mailOptions = {
from: req.body.name + ' <' + req.body.email + '>', // sender address
to: '****#gmail.com', // list of receivers
subject: 'New message test', // Subject line
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`, // plain text body
html: '<b>Email Test</b>' // html body
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
// Send Response back to caller
res.status(400).send(error);
}
console.log('Message %s sent: %s', info.messageId, info.response);
res.status(200).send('Success');
});
});
app.listen(port, function(){
console.log('Server is running at port: ',port);
});
`
HTML/EJS:
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/css/app.css" />
<link rel="icon" href="logo.jpg" />
<title>Send Mail</title>
</head>
<body>
<div class="col-md-6 offset-md-3">
<!-- No need for `form` as will use JavaScript for Single Page Application -->
<div id="sendMail" class="hide">
<div class="col-md-12 form-group">
<label for="email">Email:</label>
<input id="email" class="form-control" type="email">
<span id="emailError" class="hide error">Valid Email Required</span>
</div>
<div class="col-md-12 form-group">
<label for="name">First Name:</label>
<input id="name" class="form-control" type="text">
<span id="nameError" class="hide error">Valid First Name Required</span>
</div>
<div class="col-md-12 form-group">
<label for="message">Message :</label>
<textarea id="message" class="form-control" type="text"></textarea>
<span id="meggageError" class="hide error">Valid Last Name Required</span>
</div>
<div class="col-md-12 form-group">
<p class="btn btn-primary form-control" onclick="sendMail()">Submit</p>
</div>
</div>
</div>
<script type="text/javascript" src="/js/jquery.min.js"></script>
<!-- `login.js` is only used in `login.ejs` -->
<script type="text/javascript" src="/js/sendMail.js"></script>
<script type="text/javascript" src="/js/service.js"></script>
</body>
</html>
sendMail.js:
"use strict";
function sendMail() {
// JavaScript uses `id` to fetch value
let email = $("#email").val(),
name = $("#name").val(),
message = $("#addLname").val();
// Show error `span` when email is invalid
if ( validateEmail(email) ) {
$("#emailError").addClass("hide");
} else {
$("#emailError").removeClass("hide");
return;
}
// Show error `span` when First Name is invalid
if ( validateFname(fName) ) {
$("#nameError").addClass("hide");
} else {
$("#nameError").removeClass("hide");
return;
}
// Show error `span` when Last Name is invalid
if ( message ) {
$("#messageError").addClass("hide");
} else {
$("#messageError").removeClass("hide");
return;
}
// Calling local API to set authentication
// Everything in public is visible for hackers
// Thus to hide auth calling local backend
$.ajax({
"url": "/contact",
"method": "POST",
"data": {email, name, message}
})
.then( result => {
// On success empty all the input fields.
$("#email").val('');
$("#name").val('');
$("#message").val('');
// Message to notify success submition
alert("Successfully Send Mail.");
return;
})
.catch( err => {
// Notify in case some error occured
alert("An error occured.");
return;
});
}
service.js:
"use strict";
/**
* Common services used by all the other scripts
* All these are generic functions
*
*/
// Validate Email based upon pattern
function validateEmail (email) {
if ( email && email.match(/^([A-Za-z0-9]{2,})([#]{1})([A-z]{1,})([.]{1})([A-z.]{1,})*$/) ) {
return true;
}
return false;
}
// Validate First Name based upon pattern
function validateName (name) {
if ( name && name.match(/^([A-Za-z]{2,})*$/) ) {
return true;
}
return false;
}

Passport returning "missing credentials" error

Newbie here... I'm working on a password reset form so I'm only passing an email in my POST form. I'm getting a Missing credentials error msg and I'm not even getting to the strategy I made for this feature so I'm not getting to query against UserModel. What could be causing this error?
My code is as follows:
password_reset_request.html:
<div class="modal fade" id="passwordresetrequest-modal" tabindex="-1" role="dialog" aria-labelledby="passwordresetrequestLabel" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
<div class="signup-modal-container">
<form class="form-signin" action="/password_reset_request" id="password_reset_request_form" method="post">
<h2 class="form-signin-heading">Request Password Reset for BIDS</h2>
<label for="email" class="sr-only">Email address</label>
<input type="email" name="email" id="email" class="form-control" placeholder="Email address" required="" autofocus="">
<button class="btn btn-lg btn-primary btn-block" name="reset_request" type="submit">Send Password Reset Email</button>
</form>
</div>
</div>
</div>
app.js:
var express = require("express");
var bodyParser = require("body-parser");
var passport = require("passport");
...
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
require("./config/passport")(passport);
...
index.js:
app.post("/password_reset_request", function(req, res, next) {
passport.authenticate("local-password-reset-request", function(err, user, info) {
// NOTE: I'm getting a "null" value for my "err" param.
// NOTE: the "info" param is where I'm getting my "message: 'Missing credentials'" message.
if (err) {
return next(err);
}
if (!user) {
req.flash("error", "Reset failed, no such email.");
return res.redirect("/");
}
})(req, res, next);
});
passport.js:
passport.use("local-password-reset-request", new LocalStrategy({
usernameField: "email",
passReqToCallback: true
}, function(req, username, done) {
new UserModel.User({ email: email }).fetch().then(function(user) {
// if no user is found, return the message
if (!user)
return done(null, false, req.flash("loginMessage", "No user found."));
var new_password = randomstring.generate({
length: 12,
charset: 'alphabetic'
});
user
.set('password', UserModel.generateHash(new_password))
.save()
.then(function() {
console.log('new_password: ' + new_password);
// Mailer.sendNewPasswordMail(
// user.get("email"),
// new_password,
// req.headers.host
// );
return done(null, user);
})
;
return done(null, user);
});
}));
Turns out when I use LocalStrategy I need to provide both a usernameField AND a passwordField. Since I'm not actually using that passwordField value I pass any non-blank value and simply ignore it.

Node.JS + mySQL -> How to do the ajax call and access the data on server.js?

So this is my server.js file, where the db is being connected to :
var app = require('express')();
var mysql = require('mysql');
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'user_data',
port: 3306
});
db.connect();
app.get('/', function (req, res) {
res.sendFile(__dirname + "/start.html");
});
app.listen(3000);
So I want to make something like a registration form, where you input your username and password. Then, after you click the submit button, the username and password are supposed to go straight to the mySQL database. So apparently, I need an ajax call which sends the data to that server, but I don't know how to access it on the server.js.
$("button#submit").click(function () {
$.ajax({
'url': 'http://localhost:3000',
'type': 'post',
'data': {
'username': $("#usr").val(),
'password': $("#pwd").val()
},
'success': function (data) {
alert('Data: ' + data);
}
});
})
After I get that data on the server.js, I will obviously want to make a query (to insert the values) but how do I get the data?
This is how I did it for one of my projects:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Contact Form</title>
</head>
<body>
<div id="contact">
<h1>Send an email</h1>
<form action="/myaction" method="post">
<fieldset>
<label for="name">Name:</label>
<input type="text" id="name" name="name" placeholder="Enter your full name" />
<label for="location">Location:</label>
<input type="text" id="location" name="location" placeholder="Enter your location" />
<input type="submit" value="Send message" />
</fieldset>
</form>
</div>
</body>
</html>
Now when user clicks submit /myaction url will hit.
db.connect(function(err,connection){
app.post('/myaction',function(req,res){
console.log(req.body);
var employee={name:req.body.name,location:req.body.location}
db.query('INSERT into employees SET ?',employee,function(err,res){
if(err){
throw err;
}
else{
console.log(res);
}
})
res.send(JSON.stringify(req.body));
})
})
Make sure to include these in your server.js
var express=require('express');
var bodyParser=require('body-parser');
app=express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
So you can see i have defined app.post and I am hitting my url. Then we simply write a sql query to store data.

simple login node.js+mongoDB Cannot POST/ login

I have some problems to get a login for my webpage.
I have a user in my DB with email: peru#hotmail.com and pass 123.
the problem is that when I make the POST method it returns me the next error:
*Cannot POST /login*
this is my app.js:
var mongoose = require('mongoose');
var express = require('express');
var app=express();
var bodyParser = require('body-parser');
mongoose.connect("mongodb://localhost/myDB");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
var userSchema = {
email:String,
pass:String
};
var Usuario = mongoose.model("Usuario",userSchema);
app.use(express.static("public"));
app.get("/",function(solicitud,respuesta){
respuesta.sendFile('.../prueba.html');
});
app.post("/login",function(require,respuesta){
var email = require.body.email;
var pass = require.body.pass;
console.log("post received: %s %s", email, pass);
User.findOne({email: email, pass: pass}, function(err,user){
if(err){
console.log(err);
}
respuesta.sendFile('.../work.html');
});
});
app.listen(3000);
and now this is my prueba.html:
<html>
<head>
<title></title>
</head>
<body>
<!--div class="col-md-5 center-block no float top-pace text-left"-->
<form method="post" action="/login" >
<input type="text" name="email">
<input type="text" name="pass" >
<button type="submit" >login </button>
</form>
</body>
</html>
You created model as Usuario and using User in your POST request, try changing it to Usuario, as follows:
app.post("/login",function(require,respuesta){
var email = require.body.email;
var pass = require.body.pass;
console.log("post received: %s %s", email, pass);
Usuario.findOne({email: email, pass: pass}, function(err,user){
if(err){
console.log(err);
}
respuesta.sendFile('.../work.html');
});
});

Categories

Resources