Reputation: 139
I'm following this tutorial: and I when I enter an email address, I get an email and I click the link and go to this page. [![enter image description here][2]][2]
As you can see, the id and token are being passed in url correctly and when I click Reset Password, I get [![enter image description here][3]][3]
It shows n:1
as if it updated database password successfully, but the password value never updates in the database and I'm not sure why.
I added some console.logs to help track the output and API calls. I appreciate any help.
Here's my code
app.js
//Forgot Password Form
app.get("/api/users/forgotpassword", function(req, res) {
res.send(
'<form action="/api/users/passwordreset" method="POST">' +
'<input type="email" name="email" value="" placeholder="Enter your email address..." />' +
'<input type="submit" value="Reset Password" />' +
"</form>"
);
});
//Forgot password form calls this api to send email
app.post("/api/users/passwordreset", function(req, res) {
console.log("req.body.email");
console.log(req.body.email);
let emailValue = req.body.email;
if (req.body.email !== undefined) {
User.findOne({ email: req.body.email }).then(user => {
if (user) {
console.log("fetchedUser");
console.log(user._id);
var payload = {
id: user._id,
email: user.email
};
var secret = user.password + "-" + user.passwordCreated;
var token = jwt.sign(payload, secret);
console.log("payload");
console.log(payload);
var ses_mail = "From: 'Auction Site' <" + emailValue + ">\n";
ses_mail = ses_mail + "To: " + emailValue + "\n";
ses_mail = ses_mail + "Subject: Password Reset Request\n";
ses_mail = ses_mail + "MIME-Version: 1.0\n";
ses_mail =
ses_mail + 'Content-Type: multipart/mixed; boundary="NextPart"\n\n';
ses_mail = ses_mail + "--NextPart\n";
ses_mail = ses_mail + "Content-Type: text/html; charset=us-ascii\n\n";
ses_mail =
ses_mail +
'<a href="http://localhost:3000/resetpassword/' +
payload.id +
"/" +
token +
'">Click here to reset password</a>';
// /:id/:token
var params = {
RawMessage: { Data: new Buffer.from(ses_mail) },
Destinations: [emailValue],
Source: "'AWS Tutorial Series' <" + emailValue + ">'"
};
ses.sendRawEmail(params, function(err, data) {
if (err) {
res.send(err);
console.log(err);
} else {
res.send(data);
}
});
}
if (!user) {
return res.status(401).json({
message: "Auth failed"
});
}
});
} else {
res.send("Email address is missing.");
}
});
//URL Link that lets you change pw
app.get("/resetpassword/:id/:token", function(req, res) {
console.log("Outputs");
console.log(req.params.id);
console.log(req.params.token);
User.findOne({ _id: req.params.id }).then(user => {
var secret = user.password + "-" + user.passwordCreated.getTime();
var payload = jwt.decode(req.params.token, secret);
if (!user) {
return res.status(401).json({
message: "Auth failed"
});
}
console.log("USER FOUND");
console.log(user);
fetchedUser = user;
instagramName = user.instagramName;
// return bcrypt.compare(req.body.password, user.password);
res.send(
'<form action="/resetpassword" method="POST">' +
'<input type="hidden" name="id" value="' +
payload.id +
'" />' +
'<input type="hidden" name="token" value="' +
req.params.token +
'" />' +
'<input type="password" name="password" value="" placeholder="Enter your new password..." />' +
'<input type="submit" value="Reset Password" />' +
"</form>"
);
});
});
//POST API CALL THAT UPDATES PW
app.post("/resetpassword", function(req, res) {
console.log("MADE IT");
// TODO: Fetch user from database using
User.findById(req.body.id).then(user => {
console.log("USER BELOW");
console.log(user);
var secret = user.password + "-" + user.passwordCreated.getTime();
console.log("SECRET");
console.log(secret);
var payload = jwt.decode(req.body.token, secret);
bcrypt.hash(req.body.password, 10, function(err, hash) {
if (err) {
console.log(err);
}
newPasswordHash = hash;
// res.sendStatus(401);
console.log(newPasswordHash);
console.log(newPasswordHash);
User.updateOne({ password: newPasswordHash })
.then(user => {
console.log(user);
res.json(user);
})
.catch(err => console.log(err));
});
console.log("PAYLOAD");
console.log(payload);
});
});
Output
Connected to Database!
req.body.email
[email protected]
fetchedUser
5df11e3f1868b0316c073760
payload
{ id: 5df11e3f1868b0316c073760,
email: '[email protected]' }
Outputs
5df11e3f1868b0316c073760
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkZjExZTNmMTg2OGIwMzE2YzA3Mzc2MCIsImVtYWlsIjoiYXVjdGlvbnNpdGUzMDAwQGdtYWlsLmNvbSIsImlhdCI6MTU3NjA5OTgzMn0.GSmidGtGn4gZM07ab8AgaL7-NaKcs4T02GoQuIPLoQs
USER FOUND
{ _id: 5df11e3f1868b0316c073760,
email: '[email protected]',
password:
'$2b$10$Do56McP/9h/rLp5VCcEorenZQcGnViam7Y0WX5TGB1y2/sbSfM/Ti',
instagramName: 'auciotnsite',
over21: 'Yes',
role: 'Artist',
fullName: 'Not Added Yet',
address1: 'none',
address2: 'none',
city: 'none',
state: 'none',
zip: 'none',
passwordCreated: 2019-12-11T16:50:07.304Z,
__v: 0 }
MADE IT
USER BELOW
{ _id: 5df11e3f1868b0316c073760,
email: '[email protected]',
password:
'$2b$10$Do56McP/9h/rLp5VCcEorenZQcGnViam7Y0WX5TGB1y2/sbSfM/Ti',
instagramName: 'auciotnsite',
over21: 'Yes',
role: 'Artist',
fullName: 'Not Added Yet',
address1: 'none',
address2: 'none',
city: 'none',
state: 'none',
zip: 'none',
passwordCreated: 2019-12-11T16:50:07.304Z,
__v: 0 }
SECRET
$2b$10$Do56McP/9h/rLp5VCcEorenZQcGnViam7Y0WX5TGB1y2/sbSfM/Ti-1576083007304
$2b$10$duRLuptSeL1jyroSiV22cuLonrZojN.zsuTkrsGw5umx.jd78ySQW
$2b$10$duRLuptSeL1jyroSiV22cuLonrZojN.zsuTkrsGw5umx.jd78ySQW
PAYLOAD
{ id: '5df11e3f1868b0316c073760',
email: '[email protected]',
iat: 1576099832 }```
Upvotes: 0
Views: 173
Reputation: 8603
The issue is, the code is not waiting for user.updateOne
promise to resolve. try this code:
app.post("/resetpassword", async function(req, res) {
console.log("MADE IT");
// TODO: Fetch user from database using
const user = await User.findById(req.body.id);
console.log("USER BELOW");
console.log(user);
var secret = user.password + "-" + user.passwordCreated.getTime();
console.log("SECRET");
console.log(secret);
var payload = jwt.decode(req.body.token, secret);
try {
const updatedResult = await new Promise((resolve, reject) => {
bcrypt.hash(req.body.password, 10, async function(error, hash) {
if (error) {
console.log(error);
reject(error);
}
newPasswordHash = hash;
// res.sendStatus(401);
console.log(newPasswordHash);
console.log(newPasswordHash);
try {
const updated = await user.updateOne({ password: newPasswordHash })
resolve(updated);
} catch(err) {
console.log(err)
reject(err)
}
});
})
res.json(updatedResult)
} catch(err) {
console.log(err);
// TODO: send a response here
}
console.log("PAYLOAD");
console.log(payload);
});
Upvotes: 1