learning code
learning code

Reputation: 21

Password reset link using jwt and nodejs

This code is not working

          router.put('/requestpass',function(req,res){
               console.log('inside password');
               async.waterfall([
                 function(done) {
                 user.findOne({
                  email: req.query.useremail
                 }).exec(function(err, user) {
                          if (user) {
                    done(err, user);
                         } else {
                   done('User not found.');
            }
              });
},
function(user, done) {

create token

            var token= user.generateJwt();
             done(err, user, token);

},

// updates user object with new token and expiration date

             function(user, token, done) {

  user.findOneAndUpdate({ email : req.query.useremail }, { token: token, reset_password_expires: Date.now() + 86400000 }, { upsert: true, new: true }).exec(function(err, new_user) {
    if(err){console.log('error hain')}
    done(err, token, new_user);
  });
},

//configuring email

        function(token, user, done) {

  ejs.renderFile(__dirname + "../templates/url.ejs", { url: 'http://localhost:3000/auth/reset_password?token=' + token }, function (err, data) {
    if (err) {
        console.log(err);
    } else {
        var mainOptions = {
            from: '[email protected]',
            to: "[email protected]",
            subject: 'Password Reset',
            html: data
        };
        console.log("html data >", mainOptions.html);
        transporter.sendMail(mainOptions, function (err, info) {
            if (err) {
                console.log(err);
            } else {
                console.log('Message sent: ' + info.response);
                }
                     });
                   }

                    });
                }
           ], function(err) {
     return res.status(422).json({ message: err });
        });
     });

I have made this function which will send reset password link to the user but it is not working it is showing error on user.findOneandupdate and then in email configuration below is function generating token

                 userSchema.methods.generateJwt = function() {
var expiry = new Date();
expiry.setDate(expiry.getDate() + 7);

return jwt.sign({
  _id: this._id,
  email: this.email,
  name: this.name,
  exp: parseInt(expiry.getTime() / 1000),
        }, "MY_SECRET"); // 
         };

             that's how I have configured email 

               var transporter = nodemailer.createTransport({
               service: 'gmail',
                    auth: {
                  user: '**',
                    pass: '****'
                     }
                     });

Upvotes: 0

Views: 3744

Answers (1)

Sonu Mishra
Sonu Mishra

Reputation: 441

Try this code
    // request to send smtp email containing jwt token in the URL
    router.post('/forgot', function(req, res, next){
    async.waterfall([
        function(done){
            Usermodel.findOne({email: req.body.email}, function(err, user){
                if(!user){
                    return res.status(422).send({errors: [{title: 'Invalid email!', detail: 'User does not exist'}]});
                }

                const token = jwt.sign({
                    userId: user.id,
                    username: user.username,
                    resetPasswordToken: user.resetPasswordToken
                  }, config.SECRET, { expiresIn: '1h' });

                user.resetPasswordToken = token;
                user.resetPasswordExpires = Date.now() + 3600000; // 1 hour

                user.save(function(err){
                    done(err, token, user);
                });
            });
        },

        function(token, user, done){
            const smtpTransport = nodemailer.createTransport({
                service: 'Gmail',
                auth: {
                    user: 'XXXX',
                    pass: 'XXXX'
                }
            });

            const mailOptions = {
                to: user.email,
                from: '[email protected]',
                subject: 'Nodejs password reset',
                text: 'You are receiving this email. Please click on the email for password reset ' +
                      'http://' + req.headers.host + '/reset/' + token + '\n\n' + 
                      'If you did not request this, please ignore this email'
            };
            smtpTransport.sendMail(mailOptions, function(err){
                console.log('mail sent');
                done(err, 'done');
            });
        }
    ], function(err){
        if(err) return next(err);
    });
});

// request to get and verify if the token has expired or user is invalid
router.get('/reset/:token', function(req, res){
    Usermodel.findOne({resetPasswordToken: req.params.token, resetPasswordExpires: {$gt: Date.now() } }, function(err, user){
        if(!user) {
            return res.status(422).send({errors: [{title: 'Invalid token!', detail: 'User does not exist'}]});
        }   
        res.json('reset', {token: req.params.token});
    });
});

// request to update the password in database if password and confirm password is matching. Also send email to user regarding successful password change
router.post('/reset/:token', function(req, res){
    async.waterfall([
        function(done) {
            Usermodel.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user){
                if(!user){`enter code here`
                    return res.status(422).send({errors: [{title: 'error', detail: 'Password reset token is invalid or has expired'}]});
                }

                if(req.body.password === req.body.confirm){
                    user.setPassword(req.body.password, function(err){
                        user.resetPasswordToken = undefined;
                        user.resetPasswordExpires = undefined;

                        user.save(function(err){
                            req.logIn(user, function(err) {
                                done(err, user);
                            });
                        });
                    });
                } else {
                    return res.status(422).send({errors: [{title: 'error', detail: 'Password do not match'}]});
                }
            });
        },
        function(user, done){
            var smtpTransport = nodemailer.createTransport({
                service: 'Gmail',
                auth: {
                    user: 'XXXX',
                    pass: 'XXXX'
                }
            });

            var mailOptions = {
                to: user.email,
                from: '[email protected]',
                subject: 'Your password has been changed',
                text: 'Hello,\n\n' + 
                    'This is a confirmation that the password for your account ' + user.email + ' has just changed'
            };
            smtpTransport.sendMail(mailOptions, function(err){
                done(err);
            });
        }
    ],   function(err){
        res.redirect('/');
    });
});

Upvotes: 1

Related Questions