Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

modify password with expressjs mongoose passport-local

First of all, I'm french, and my english is not really good, I do my best :)

I created a local authentification using PassportJs, Mongoose and Expressjs (v3.x). It works perfectly. When the user is logged, in the /account/ space, I created a form to change the current password (3 input : pass, newpass, newpassconfirm). But after that, I have no idea how to process ...

Do I have to create another passport LocalStrategy to find my user and call a "setPassword" function declared in my Users Schema ? Can I maybe do this operation without using passportjs .. ? If it's possible, how can I get my User access to the database ?

Here is my code for my authentification that works.

My /login POST (/routes/user.js)

app.post('/login', function(req, res, next) {
    passport.authenticate('local-login', function(err, user, info) {
        if (err) { 
            return next(err); 
        }

        if (!user) { 
            return res.redirect('/login'); 
        }

        req.logIn(user, function(err) {
            if (err) { 
                return next(err); 
            }

            req.session.pseudo = user.pseudo;
            return res.redirect('/');
        });
    })(req, res, next);
});

My passport script (/script/passport.js)

passport.use('local-login', new LocalStrategy({
    usernameField : 'pseudo',
    passwordField : 'pass',
    passReqToCallback : true // permet de passer l'objet req dans le callback
}, function (req, pseudo, pass, done) {
    Users.findOne({ 'pseudo': pseudo }, function (err, user) {
        if (err) { 
            return done(err); 
        }
        if (!user) { 
            return done(null, false, req.flash('loginMessage', 'Cet utilisateur n\'existe pas.'));
        }
        if (!user.verifyPassword(pass)) { 
            return done(null, false, req.flash('loginMessage', 'Mot de passe incorrect.')); 
        }
        return done(null, user);
    });
}));

My User Schema (/models/db_Users.js)

var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');

// Schema de la collection User
var usersSchema = mongoose.Schema({
    pseudo: String,
    pass: String,
    admin: Boolean,
}, 
{
    collection: 'Users' 
});

usersSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

usersSchema.methods.verifyPassword = function(password) {
    return bcrypt.compareSync(password, this.pass);
};

module.exports = mongoose.model('Users', usersSchema);

the /changepass POST where I have issues (/routes/users.js)

app.post('/changepass' , function (req, res, next) {
    //console.log(req.body.pass, req.body.newpass, req.body.newpassconfirm);

    // Should I call another passport LocalStrategy to acces to my User and set the new password here ?

    res.redirect('/account');
});

You can find all the project here, if you have questions about the structure of my app : https://github.com/tibaldev/docu

Thanks for your help !

like image 240
tibalte Avatar asked Mar 20 '23 11:03

tibalte


2 Answers

/models/db_Users.js

// bcrypt middleware
usersSchema.pre('save', function(next){
    var user = this;

    //check if password is modified, else no need to do anything
    if (!user.isModified('pass')) {
       return next()
    }

    user.pass = bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
    next()
})

Inside your routes/users.js

var User = require('mongoose').model('Users')

app.post('/changepass' , function (req, res, next) {
     if (newpass !== newpassconfirm) {
        throw new Error('password and confirm password do not match');
     }

     var user = req.user;

     user.pass = newpass;

     user.save(function(err){
         if (err) { next(err) }
         else {
             res.redirect('/account');
         }
     })
});
like image 126
ashu Avatar answered Mar 23 '23 22:03

ashu


You could try something like this

app.post("/update/userid", function(req, res) {
    var userid = req.params.id
    var username = req.session.passport.user
    var newPass = req.body.password
    console.log(username, userid)
    User.findByUsername(username).then(function(sanitizedUser) {
        if (sanitizedUser) {
            sanitizedUser.setPassword(newPass, function() {
                sanitizedUser.save();
                res.send('password reset successful');
            });
        } else {
            res.send('user does not exist');
        }
    }, function(err) {
        console.error(err);
    })
})
like image 38
OluO Avatar answered Mar 23 '23 22:03

OluO