Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setPassword on query middleware (findOneAndUpdate) #135

Open
linusbrolin opened this issue May 30, 2016 · 1 comment
Open

setPassword on query middleware (findOneAndUpdate) #135

linusbrolin opened this issue May 30, 2016 · 1 comment

Comments

@linusbrolin
Copy link

Passport-local-mongoose currently only seems to support generating hashed password in document middleware, not in query middleware.
This means that saving documents through findOneAndUpdate, findByIdAndUpdate, etc, will not work if a password is part of that update.

I made an ugly workaround for this to work, but ideally this is something that should be handled by passport-local-mongoose.

Below is my ugly workaround to cover all ways of saving a document:

// document middleware code
// more information: http://mongoosejs.com/docs/middleware.html

UserSchema.pre('save', function(next: Function) {
  var user: User = this;
  user.updatedAt = new Date();

  // only hash the password if it has been modified (or is new)
  if (!user.isModified('password') || !user.password || user.password.length === 0) {
      return next();
  }

  user.setPassword(user.password, function(err: any, usr: User) {
    return next();
  });
});


// query middleware code
// more information: http://mongoosejs.com/docs/middleware.html

function updatePassword(query: any, cb: (err: any, res: any) => void): void {
  let u: User = new UserModel();

  // borrow the password hashing function from passport-local-mongoose
  u.setPassword(query.getUpdate().password, function(err: any, usr: User) {
    if (err) {
      return cb(err, null);
    }

    // we need to delete the clear-text password from the query in order to replace it with our hashed one
    delete query._update.password;

    // update the query with our newly generated hashed password and salt
    query.update({}, {
      $set: {
        password: usr.password,
        salt: usr.salt,
        updatedAt: new Date()
      }
    });

    return cb(null, query);
  });
}

UserSchema.pre('update', function(next: Function) {
  if (this._update.password) {
    updatePassword(this, function(err: any, res: any) {
      return next();
    });
  }
  else {
    // if the password is null then we need to delete it because null is a valid value and it will overwrite whatever is in the database
    delete this._update.password;
    this.update({}, { $set: { updatedAt: new Date() } });
    return next();
  }
});

UserSchema.pre('findOneAndUpdate', function(next: Function) {
  if (this._update.password) {
    updatePassword(this, function(err: any, res: any) {
      return next();
    });
  }
  else {
    // if the password is null then we need to delete it because null is a valid value and it will overwrite whatever is in the database
    delete this._update.password;
    this.update({}, { $set: { updatedAt: new Date() } });
    return next();
  }
});
@TimUnderhay
Copy link

I agree that this is a considerable issue. It would be lovely to get acknowledgement of it from the developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants