balderdashy / balderdashy/sails
Model.updateOne().set() inappropriately manipulates the valuesToSet object
- Dominant language
- JavaScript
- Stars
- 22.8k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
**Node version**: 18.12.0
**Sails version** _(sails)_: 1.5.3
**ORM hook version** _(sails-hook-orm)_: 2.1.1
**Sockets hook version** _(sails-hook-sockets)_: 2.0.3
**Organics hook version** _(sails-hook-organics)_: 2.2.0
**Grunt hook version** _(sails-hook-grunt)_: 5.0.0
**Uploads hook version** _(sails-hook-uploads)_: not installed (at least not listed in my package.json, so whatever is native)
**DB adapter & version** _(e.g. sails-mysql@5.55.5)_: sails-mongo@2.0.0
**Skipper adapter & version** _(e.g. skipper-s3@5.55.5)_: not installed (at least not listed in my package.json, so whatever is native)
Model.updateOne().set() manipulates the valuesToSet object and it should not. This matters because I reuse the valuesToSet object to reset the same document multiple times in my test scripts: For additional context, my database is a mongo db.
The following is the initial state of valuesToSet:
```json
{
createdAt: 1667199444571,
updatedAt: 1667199444571,
id: '000000000000000000000002',
email: 'testuseraccount@gmail.com',
firstName: 'Ruby',
lastName: 'Rod',
password: '*******',
accountStatus: 'confirmed',
emailProofToken: '',
emailProofTokenExpiresAt: 0,
passwordResetToken: '',
passwordResetTokenExpiresAt: 0,
emailChangeCandidate: '',
stripeCustomerId: ''
}
```
The following is the valuesToSet object after it has been used in call to Model.updateOne().set(criteria, valuesToSet)
```json
{
createdAt: 1667199444571,
updatedAt: 1667199444571,
email: 'testuseraccount@gmail.com',
firstName: 'Ruby',
lastName: 'Rod',
password: '****',
accountStatus: 'confirmed',
emailProofToken: '',
emailProofTokenExpiresAt: 0,
passwordResetToken: '',
passwordResetTokenExpiresAt: 0,
emailChangeCandidate: '',
stripeCustomerId: '',
_id: ObjectID {
_bsontype: 'ObjectID',
id: Buffer(12) [Uint8Array] [
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 2
]
}
}
```
Note that not only does the value of "id" get changed to a bson representation of the same string, but so does its key (id to _id).
The object seems to be getting painted over by the raw object as retrieved from the Mongo database, which I don't think should happen. If for whatever reason you deem it should happen though, at a minimum the the translation from _id to id should likely happen per the documentation. That being said, I ultimately feel that the .set() function should not be manipulating the valuesToSet object at all.... rather it should only be manipulating the database document, and returning the database document while leaving valuesToSet purely as an input object
Contributor guide
Research direction
Start by reproducing Model.updateOne().set(criteria, valuesToSet) with the Mongo adapter and compare valuesToSet before and after the call. Trace where the input object is changed, then verify that the database update still works while the caller's object remains unchanged and its id key is preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, mongodb, node.js
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100