JavaScript Promises not passing right value in Chain - javascript

I have a random generated string that I set as a value for a property in my database table. On a successful update to my record I then send an email containing that same token that was used in the database record. Unfortunately the token parameter in my then statement does not contain the token and instead is replaced with a value of 1. Why is this happening and does it have something to do with how promises functionality works?
This is an example console log and SQL update that appears in my code:
This is the token: 78a4543cdd4cfd9d8c7fbad89aed9f902e07c372
Executing (default): UPDATE `user` SET `reset_password_token`='78a4543cdd4cfd9d8c7fbad89aed9f902e07c372',`reset_password_expires`='2016-04-02 14:46:13',`updatedAt`='2016-04-02 13:46:13' WHERE `email` = 'tester#gmail.com'
Then this token: 1
POST Method:
.post(function(req, res){
async.waterfall([
function(done){
crypto.randomBytes(20, function(err, buf){
var resetToken = buf.toString('hex');
done(err, resetToken);
});
}, (function(token, done){
console.log('This is the token: ' + token);
models.User.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 3600000
}, {
where: { email: req.body.email }
}).then(function(token, user, done){
console.log('Then this token: ' + token);
var transporter = nodemailer.createTransport(sgTransport(options));
var mailOptions = {
from: '"Test Email" <test#mywebsite.com',
to: 'tester#gmail.com',
subject: 'Password Rest Confirmation',
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged.\n'
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
res.redirect('/');
//res.redirect('/password-reset-confirmation') Make a confirmation page with information or just send a flash message
})
})], function(error){
if(error){
console.log(error);
}
})
});

The token receives the value 1 because the update() operation returns the number of affected records. In this case, there was a single record updated.

Related

how to solve email sending issue " Internal Server Error " using nodeMailer in node js

I want to send a confirmation email using nodemailer, but in production it says internet server error when I allow insecure apps for Gmail accounts, even though it works locally.
How can I fix this?
router.post("/forgotPass", (req, res, next)=>{
async.waterfall([
function(done){
crypto.randomBytes(20, (err, buf)=>{
var token = buf.toString('hex');
done(err, token);
})
},
function(token, done){
user.findOne({email : req.body.email}, (err, user)=>{
if(!user){
req.flash("error", "No account with this email address exists!");
console.log("now account with this email exists !")
return res.redirect("back");
}
user.resetPasswordToken = token;
user.resetPasswordDuration = Date.now() + 3600000; //1 hour
user.save((err)=>{
done(err, token, user);
console.log("the error is " + err);
});
})
},
function(token, user, done){
var smtpTransport = nodeMailer.createTransport({
service : 'Gmail',
auth:{
user:'abedkhan.noori10#gmail.com',
pass : process.env.GMAIL_PW
}
});
var mailOptions = {
to : user.email,
from : 'abedkhan.noori10#gmail.com',
subject : 'passwor Reset!',
text : "you are receiving this email because you want to reset you password in mY App ." +
"please click the link below to complete the process. " +
"http://" + req.headers.host + "/resetPass/" + token + "\n\n" +
"if you did not request this, please ignore this email and your password will be untouched."
};
smtpTransport.sendMail(mailOptions, (err)=>{
console.log('mail sent!');
req.flash("success", "an email has sent to " + user.email + " with further instructions");
done(err, 'done');
});
}
], function(err){
if(err){
return next(err);
} res.redirect("/forgotPass");
});
});
You will need to enable less secure app access for your account - Google does not allow you to use your account through a program without that enabled. However, you can enable 2-factor auth in GMail and use an app password as your password.

SQL inserting empty records in database - using JavaScript

I am trying to insert data gathered from a form filled out on my website, and storing that data in a database on phpMyAdmin.
Everything is working correctly, I am getting the message "Connected to Database." and "Records Inserted Successfully!", meaning that the communication between the website and the database is working.
However, when I check the database, there are empty records (the records are being inserted, but there are no values).
Not sure if this might help, but the parameters for the function 'db' say "unused".
var name = request.body.FirstName;
var surname = request.body.LastName;
var email = request.body.Email;
var message = request.body.Message;
console.log(name + " " + surname);
console.log(email); console.log(message);
var emailMessage = "New message from " + name + " " + surname + "(" + email + ") " + message;
function mail(emailMessage){
var nodemailer = require("nodemailer");
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'XXX', // add your username
pass: 'XXX' // add your password
}
});
var mailOptions = {
from: 'XXX', // add sender email (your email)
to: 'XXX', // add recipient email (maybe a friend)
subject: 'Message from Node.js app',
html: '<p>' + emailMessage + '</p>'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
}
mail(emailMessage);
function db(name, surname, email, message){
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'db4free.net',
user: 'XXX',
password: 'XXX',
database: 'feedback_db'
});
connection.connect(function(err) {
if (err) throw err;
console.log("Connected to Database.");
var sql = "INSERT INTO messages (Name, Surname, Email, Message) VALUES (name, surname, email, message)";
connection.query(sql, function (err, result) {
if (err) throw err;
console.log("Records Inserted Successfully!");
});
}); }
db(name, surname, email, message);
response.sendFile(__dirname + '/success.html'); });
Variables aren't evaluated inside strings. When you put VALUES (name, surname, email, message) in the query, it doesn't use the variables. You should put placeholders there, and supply the values as a parameter.
var sql = "INSERT INTO messages (Name, Surname, Email, Message) VALUES (?, ?, ?, ?)";
connection.query(sql, [name, surname, email, message], function(err, result) {
if (err) throw err;
console.log("Records Inserted Successfully!");
});
I can't explain why you're getting empty records -- you should be getting an error due to the invalid values in the query.

Trying to get information from postgresql database, based on a parameter

This is my first time working with node and postgre. I am trying to get the email, first name, and last name from my postgre database by passing in a user's email address in a SQL statement:
function getSingleUser(req, response, next){
var UserId = req.params.email.substring(1);
console.log(UserId);
pool.connect(function(err, client, done){
if(err){
return console.error('Error fetching client from pool', err);
}
client.query('SELECT users.email, users.firstname, users.lastname, users.id FROM people.users WHERE users.lastname = Williams', function(err, results){
if(err){
return console.log('error running query', err);
}
// Just returns the raw json data
response.json(results.rows);
client.release();
done();
});
});
};
Whenever I run this though I get the error: error running query { error: column "williams" does not exist. So what can I use to check for a value and not a column? Thank you
Ok I fixed it by adding single quotes around my parameter and double quotes around everything else.
client.query("SELECT users.email, users.firstname, users.lastname, users.id FROM people.users WHERE users.lastname = '" + UserId + "'"

Node JS MySQL Authentication

I am new to node JS. I am working on authenticating users against backend MYSQL.
Here is the code snippet of authentication
function Authenticate(username, password, fn) {
connection.connect();
var user;
connection.query('SELECT * from Users where username = ' +
connection.escape(username) + ' and password =' + connection.escape(password),
function(err, rows) {
user = rows[0].username;
});
if (!user) {
return fn(new Error('cannot find user'));
} else {
return fn(null, user);
}
connection.end();
}
This is my call back function.
app.post('/Login', function(req, res) {
Authenticate(req.body.username, req.body.password, function(err, user) {
if (user) {
req.session.regenerate(function() {
req.session.user = user;
req.session.success = 'Authenticated as ' + user;
res.redirect('Home');
});
} else {
req.session.error = 'Authentication failed, please check your username and password.';
res.redirect('Login');
}
});
})
I am getting an error, which i cannot get my head around.
TypeError: Cannot set property 'error' of undefined
at /...../.../node_modules/app.js:42:23
at Authenticate (/..../..../node_modules/app.js:82:11).
Please share your thoughts!
Takes the else out and see if any other req.session functions properly if not check if middleware is configured correctly for express validator

Implementing password reset with passport.js

I was reading an article on passport.js and I stumbled upon this piece of code and I dont know what it does the article does not do a good job in explaining it. Can you please explain what it does?
app.post('/forgot', function(req, res, next) {
async.waterfall([
function(done) {
crypto.randomBytes(20, function(err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function(token, done) {
User.findOne({ email: req.body.email }, function(err, user) {
if (!user) {
req.flash('error', 'No account with that email address exists.');
return res.redirect('/forgot');
}
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
done(err, token, user);
});
});
},
function(token, user, done) {
var smtpTransport = nodemailer.createTransport('SMTP', {
service: 'SendGrid',
auth: {
user: '!!! YOUR SENDGRID USERNAME !!!',
pass: '!!! YOUR SENDGRID PASSWORD !!!'
}
});
var mailOptions = {
to: user.email,
from: 'passwordreset#demo.com',
subject: 'Node.js Password Reset',
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged.\n'
};
smtpTransport.sendMail(mailOptions, function(err) {
req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
res.redirect('/forgot');
});
});
Any help is appreciated.
This code is attempting to initialize a password reset type thing from a webapp -- although since we can't see the other relevant code, there's no way to know whether or not this is safe to use.
From your other responses, it looks as if you're confused about the async.waterfall and crypto.randomBytes stuff, so I'll attempt to explain those here.
async.waterfall is a helper function in the popular asyncjs library. It basically works by letting you specify a series of functions that will be run one after the other, passing the output of each one into the next function to be run.
crypto.randomBytes is essentially an easy way to generate a random string of characters. It's generating a random string (token) that will be used to generate a link to a 'secure' password reset page in an email to the user, something like:
https://www.example.com/reset_password?token=randomstringhere
This way, when the user clicks that link, you can verify that it is at most a certain amount of time OLD, and guarantee that it has never been reset before.

Categories

Resources