1

This is the authentication passport code I have put it in passport.js:

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

passport.serializeUser(function (user, done) {
  done(null, user._id);
});

passport.deserializeUser(function (id, done) {
  User.findOne({_id: id}, function (err, user) {
    done(err, user);
  })
});

passport.use(new LocalStrategy({
    usernameField: 'email'
  },
  function (username, password, done) {
    User.findOne({email: username}, function (err, user) {
      if (err) return done(err);
      if (!user) {
        return done(null, false, {
          message: 'Incorrect username or password'
        });
      }
      if (!user.validPassword(password)) {
        return done(null, false, {
          message: 'Incorrect username or password'
        });
      }

      return done(null, user);
    })
  }
));

And this is the Schema code I am storing password in the form of salt and hash in mongoDB using mongoose queries:

var mongoose = require('mongoose');
var crypto = require('crypto');

var userSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true,
    required: true
  },
  name: {
    type: String,
    required: true
  },

  hash: String,
  salt: String
 
});

userSchema.methods.setPassword = function(password) {
  this.salt = crypto.randomBytes(16).toString('hex');
  this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
};

userSchema.methods.validPassword = function(password) {
  var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
  return this.hash === hash;
};

module.exports = mongoose.model('User', userSchema);

This is the auth.js code for Login route:

   var express = require('express');
    var router = express.Router();
    var passport = require('passport');
    var mkdirp = require('mkdirp');
    
    var nodemailer = require('nodemailer');
    var config = require('../config');
    var transporter = nodemailer.createTransport(config.mailer);
    
    
    
    router.route('/login')
      .get(function(req, res, next) {
        res.render('login', { title: 'Login your account'});
      })
      .post(passport.authenticate('local', {
        failureRedirect: '/login'
      }), function (req, res) {
      res.redirect('/profile');
})

And below is the password change route I am trying to execute which is possibly not working. What I think is I need to update the hash and salt value into the database while user changes password successfully which I am unable to figure out how can I do it. Please help!!!!!!!!!!!!!!!

 router.post('/api/changePassword', function(req,res,next){
      req.checkBody('oldPass', 'Empty Password').notEmpty();
      req.checkBody('newPass', 'Password do not match').equals(req.body.confirmPass).notEmpty();

      var errors = req.validationErrors();
      if (errors) {
        console.log("Errors hain bhai");
        console.log(errors);
        res.render('settingsClient', {
          oldPass: req.body.oldPass,
          newPass: req.body.newPass,
          confirmPass:req.body.confirmPass,
          errorMessages: errors
        });
      }
      else {

       User.findOne({id: req.user.id}, function (err, data) {
         console.log("came inside api changePassword else condition inside User.findOne");
         if (err) {
          console.log(err);
         }
         else {
       data.setPassword(req.body.newPass, function(err,datas){
         if(datas) {
         data.save(function (err,datass) {
          if (err) {
            res.render('settingsClient', {errorMessages: err});
          } else {
            console.log("Hash and Salt saved");
          }
        });
      }
      else {
        console.log("setPassword error"+ err);
      }
       });
    }
      })
    }
    })

Its not working/not updating the password values into the database. What could be the possible reason and mistake I might be doing?

Biku7
  • 450
  • 6
  • 16
  • 1
    I don't think the `data.setPassword` function accepts a callback. Try it like this `console.log('data before', data); data.setPassword(req.body.newPass); console.log('data after', data); data.save(.....)` – Molda Oct 28 '20 at 10:05
  • you can use authentication-flows-js, which supports all flows (create account, forgot password, change password and more) https://www.npmjs.com/package/authentication-flows-js – OhadR Apr 27 '21 at 07:54

1 Answers1

0

Yeah! So I removed the callback funtion from the setPassword and tried with the promises way/route to solve this query: Here I am posting the solution which is working fine now.

 User.findOne(userObj).then(function(sanitizedUser) {
               if (sanitizedUser) {
                 console.log("sanitizedUser.hash = "+ sanitizedUser.hash);
                   sanitizedUser.setPassword(req.body.newPass);
                       console.log("Password going to be changed successfully now")
                       sanitizedUser.save(function (err,data) {
                         if (err) {
                           res.render('register', {errorMessages: err});
                         } else {
                           console.log("Password changed successfully");
                           res.send('Password reset successful');
                         }
                       });

               } else {
                   res.send('user does not exist');
               }
           }, function(err) {
               console.error(err);
           });
Biku7
  • 450
  • 6
  • 16