Bdyce
Bdyce

Reputation: 332

Mongoose - 5.3.4 - Prevent cast to ObjectId for query with string

I am attempting to findOneAndUpdatea string-based token on a User model. And I receive the error:

Cast to ObjectId failed for value "{ passwordResetToken: '4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7',
  passwordResetExpires: { '$gt': 1543196590882 } }" at path "_id" for model "User"

the document is stored like so:

{
    "_id": {
        "$oid": "5bfb424da0cc0923f05b67f1"
    },
    "local": {
        "email": "XXXXXXXXXXXXXXXXX",
        "password": "XXXXXXXXXXXXXXXXX"
    },
    "isVerified": false,
    "method": "local",
    "__v": 0,
    "passwordResetExpires": {
        "$date": "2018-11-26T02:41:17.851Z"
    },
    "passwordResetToken": "4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7"
}

and I query the document like so:

req.params.token = "4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7"


User.findByIdAndUpdate({
      'passwordResetToken': req.params.token,
      'passwordResetExpires': { $gt: Date.now() }
    }, 
    {
      'local.password'        : req.body.password,
      'passwordResetExpires'  : null,
      'passwordResetToken'    : null
    }, {new: true})
    .then(user => {
      res.send(user);
    })
    .catch(err => next(err))

This is my current Schema:

var userSchema = mongoose.Schema({
  method: {
    type: String,
    enum: ['local', 'google', 'facebook']
  },
  local: {
    email: {
      type: String,
      lowercase: true
    },
    password: String,
  },
  google: {
    id: String,
    email: {
      type: String,
      lowercase: true
    },
    name: String,
    token: String
  },
  facebook: {
    id: String,
    name: String,
    token: String
  },
  isVerified: {
    type: Boolean,
    default: false,
    required: true
  },
  passwordResetToken: String,
  passwordResetExpires: Date
});

I guess mongoose Is attempting to cast this hex string into a _id value? Is there some way to prevent mongoose from casting the string into an ObjectId Type?

Upvotes: 1

Views: 980

Answers (1)

Rohan Dhar
Rohan Dhar

Reputation: 1837

In mongoose, if you use findByIdAndUpdate(), you have to provide a value that is the objectID. So, in your case, it tries to find an Object ID but cannot and hence you get an error. Something more appropriate to your use case would be findOneAndUpdate(). Here, you are free to use other parameters.

Upvotes: 1

Related Questions