Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJs :- Getting "missing credentials" error while using local passport

I was trying to implement a functionality where a user can reset a password. I have tried the below code and while I am not getting any error, its not updating the password. The password is the same ie the old password.

my User model file is as follows:-

const mongoose = require('mongoose');
var passportLocalMongoose = require("passport-local-mongoose");

const LoginUserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    unique: true,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  },
    resetPasswordToken: String,
    resetPasswordExpires: Date
});

// The below is used so as to allow passport to reset password
LoginUserSchema.plugin(passportLocalMongoose);

const LoginUser = mongoose.model('LoginUser', LoginUserSchema);

module.exports = LoginUser; 

My routes file is as follows:-

const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
var async = require("async");
// Load User model
const User = require('../models/loginuser');
var nodemailer = require("nodemailer");
var crypto = require("crypto");
// Load Auth from files
const { ensureAuthenticated, forwardAuthenticated } = require('../config/auth');

// Login Page
router.get('/login', forwardAuthenticated, (req, res) => res.render('login'));

// Register Page
router.get('/register', (req, res) =>{
  if(typeof req.user == "undefined"){
    console.log("HERE IT IS");
    res.redirect('/users/login');
  }
  if (req.user.email == "[email protected]"){
  res.render('register')
  }else{
    res.redirect('/users/login');
  }
})

// Register
router.post('/register', (req, res) => {

  const { name, email, password, password2 } = req.body;
  let errors = [];

  if (!name || !email || !password || !password2) {
    errors.push({ msg: 'Please enter all fields' });
  }

  if (password != password2) {
    errors.push({ msg: 'Passwords do not match' });
  }

  if (password.length < 6) {
    errors.push({ msg: 'Password must be at least 6 characters' });
  }

  if (errors.length > 0) {
    res.render('register', {
      errors,
      name,
      email,
      password,
      password2
    });
  } else {
    User.findOne({ email: email }).then(user => {
      if (user) {
        errors.push({ msg: 'Email already exists' });
        res.render('register', {
          errors,
          name,
          email,
          password,
          password2
        });
      } else {
        const newUser = new User({
          name,
          email,
          password
        });

        bcrypt.genSalt(10, (err, salt) => {
          bcrypt.hash(newUser.password, salt, (err, hash) => {
            if (err) throw err;
            newUser.password = hash;
            newUser
              .save()
              .then(user => {
                req.flash(
                  'success_msg',
                  'You are now registered and can log in'
                );
                res.redirect('/users/login');
              })
              .catch(err => console.log(err));
          });
        });
      }
    });
  }
});

// Login
router.post('/login', (req, res, next) => {
  passport.authenticate('local', {
    successRedirect: '/users/dashboard',
    failureRedirect: '/users/login',
    failureFlash: true
  })(req, res, next);
});

// Logout
router.get('/logout', (req, res) => {
  req.logout();
  req.flash('success_msg', 'You are logged out');
  res.redirect('/users/login');
});

// Dashboard
router.get('/dashboard', ensureAuthenticated, (req, res) =>{
  res.render('dashboard', {
    user: req.user
  })
}
);

// Forgot password url
router.get('/forgot', function(req, res) {
  res.render('forgot');
});

router.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('/users/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({
        service: 'Gmail', 
        auth: {
          user: '',
          pass: ''
        }
      });
      var mailOptions = {
        //to: user.email,
        to: "[email protected]",
        from: '[email protected]',
        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 + '/users/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) {
        console.log('mail sent');
        req.flash('success', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
        done(err, 'done');
      });
    }
  ], function(err) {
    if (err) return next(err);
    res.redirect('/users/forgot');
  });
});

// Reset password url
router.get('/reset/:token', function(req, res) {
  User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
    if (!user) {
      req.flash('error', 'Password reset token is invalid or has expired.');
      return res.redirect('/forgot');
    }
    res.render('reset', {token: req.params.token});
  });
});



 router.post('/reset/:token', function(req, res) {
  async.waterfall([
    function(done) {
      User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
        if (!user) {
          req.flash('error', 'Password reset token is invalid or has expired.');
          return res.redirect('back');
        }
        if(req.body.password === req.body.confirm) {
            user.resetPasswordToken = undefined;
            user.resetPasswordExpires = undefined;
            user.password = req.body.password;

          bcrypt.genSalt(10, (err, salt) => {
            bcrypt.hash(user.password, salt, (err, hash) => {
              if (err) throw err;
              user.password = hash;
                user.save(function(err) {
                  req.login(user, function(err) {
                    console.log(user);
                    done(err, user);
                  });
                });
            });
          });
        } else {
            req.flash("error", "Passwords do not match.");
            return res.redirect('back');
        }
      });
    },
        function(user, done) {
          var smtpTransport = nodemailer.createTransport({
            service: 'Gmail', 
            auth: {
              user: '',
              pass: ''
            }
          });
          var mailOptions = {
            to: "",
            from: '',
            subject: 'Your password has been changed',
            text: 'Hello,\n\n' +
              'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
          };
          smtpTransport.sendMail(mailOptions, function(err) {
            req.flash('success', 'Success! Your password has been changed.');
            done(err);
          });
        }
      ], function(err) {
        res.redirect('/users/dashboard');
      });
    });


    module.exports = router;

I am a bit confused where I have gone wrong. I tried to search various answers online and on this forum but it didn't help me out. Please help me out. Thanks

like image 605
SemperFi Avatar asked Jan 27 '20 14:01

SemperFi


People also ask

What is Passport authentication in node JS?

Passport is Express-compatible authentication middleware for Node. js. Passport's sole purpose is to authenticate requests, which it does through an extensible set of plugins known as strategies.

What does Passport authenticate () do?

In this route, passport. authenticate() is middleware which will authenticate the request. By default, when authentication succeeds, the req. user property is set to the authenticated user, a login session is established, and the next function in the stack is called.

What is NPM Passport local?

This module lets you authenticate using a username and password in your Node. js applications. By plugging into Passport, local authentication can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.


2 Answers

I have made changes to the code. You have used passport-local-mongoose wrongly here.

   //register    
    if (errors.length > 0) {
              res.render('register', {
                errors,
                name,
                username,
                password,
                password2
              });
            } else {
              User.findOne({ username: username }).then(user => {
                if (user) {
                  errors.push({ msg: 'username already exists' });
                  res.render('register', {
                    errors,
                    name,
                    username,
                    password,
                    password2
                  });
                } else {
                  const newUser = new User({
                  name,
                  username,
                  password
                  });

                  User.register(newUser, req.body.password, function(err, user){
                      console.log(req.body)
                      if(err){
                          console.log(err);
                          return res.render("register", {error: err.message});
                      }
                      passport.authenticate("local")(req, res, function(){
                      req.flash("success", "Successfully Signed Up! Nice to meet you " + req.body.name);
                      res.redirect('/users/login');
                      });
                  });
                }
              });
            }

    // forgot password

    router.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({ username: req.body.username }, function(err, user) {
            if (!user) {
              req.flash('error', 'No account with that username address exists.');
              return res.redirect('/users/forgot');
            }

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

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

//reset token
async.waterfall([
    function(done) {
      User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
        if (!user) {
          req.flash('error', 'Password reset token is invalid or has expired.');
          return res.redirect('back');
        }
        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 {
            req.flash("error", "Passwords do not match.");
            return res.redirect('back');
        }
      });
    },
like image 177
Catmandu Avatar answered Nov 15 '22 05:11

Catmandu


I got a changepassword route using passport. Maybe its useful for you. Here it is:

router.post('/changepassword', passport.authenticate('jwt', { session: false }), (req, res) => {
    User.findOne({ username: req.user.username })
        .then(user => {
            if (!user) {
                return res.status(404).json({
                    success: false
                });
            } else if (req.body.password !== req.body.confirm_password) {
                return res.status(404).json({
                    msg: "Wachtwoorden komen niet overeen",
                    success: false
                });
            }
            bcrypt.genSalt(10, (err, salt) => {
                bcrypt.hash(req.body.password, salt, (err, hash) => {
                    user.password = hash;
                    user.save().then(user => {
                        return res.status(201).json({
                            success: true,
                            msg: "Wachtwoord veranderd"
                        });
                    })
                });
            });
        })
        .catch(err => {
            console.log(err)
        })
})
like image 31
Reinier68 Avatar answered Nov 15 '22 06:11

Reinier68