1

In a mean stack app I create a new user in User Schema then a new doc in Doc Schema

    var UserSchema = new Schema({
            username: String,
            password: String,
            docs: [{
                type: mongoose.Schema.Types.ObjectId,
                ref: 'Doc'
            }],
        )
    }

    var DocSchema = new Schema({…)
    }

    UserSchema.pre('save', function(next) {
        if (this.password) {
            this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
            this.password = this.hashPassword(this.password);
        }
        next();
    });

The following parts of code is the passport signup where at the end I have an issue with newUser.save(); After the push method if I do not save the user, doc ID are not displayed in user document. But saving user seems to change the hashed password also. If I comment newUser.save(); login works fine otherwise I get a wrong password

    passport.use('local-signup', new LocalStrategy({
              usernameField: 'username',
              passwordField: 'password',
              passReqToCallback: true
      },
      function(req, username, password, done) {

          process.nextTick(function() {

                  User.findOne({
                          username: username
                      }, function(err, user) {
                          // if there are any errors, return the error
                          if (err)
                              return done(err);
                          if (user) {
                              return done(null, false, req.flash('signupMessage', 'Username is already taken.'));
                          } else {
                              var newUser = new User();
                              newUser.username = username;
                              newUser.password = password;
                              newUser.email = req.body.email;
                              newUser.save(function(err) {
                                  if (err)
                                      throw err;
                                  var doc = new Doc({
                                      user: newUser.username,
                                      docTitle: newUser.username
                                  });
                                  doc.save(function(err) { // create doc
                                      if (err) {
                                          return next(err);
                                      } else {
                                          newUser.docs.push(doc); // push doc'id in docs field in user
                                          newUser.save(); // save user after doc'id has been push
                                      };
                                      return done(null, newUser);
                                  });
                              });

Any help would be appreciated

Manish Kr. Shukla
  • 4,447
  • 1
  • 20
  • 35
Greg
  • 473
  • 1
  • 5
  • 19

1 Answers1

1

Your logic in your mongoose pre save middleware says 'if there is a password on the document being saved, generate a salt and hash the password'. Therefore, if a password exists on the document that has already been salted and hashed, when the middleware runs it will salt and hash this pre-existing password again. This is why you can't login a second time; your password is changing every time you save the document.

I'm guessing you expect the mongoose pre save middleware to run only when you save the document the first time. The pre save middleware runs every time you save the document. There is a this.isNew property available on the document in the pre save middleware that you can make use of. This will ensure the password is only generated the first time you save the document.

UserSchema.pre('save',  function(next) {
    if (this.password && this.isNew) {
        this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
        this.password = this.hashPassword(this.password);
    }
    next();
});
sabrehagen
  • 1,517
  • 1
  • 13
  • 38