balderdashy / balderdashy/sails

Model.updateOne().set() inappropriately manipulates the valuesToSet object

Open
#7,260 8 comments 0 reactions 0 assignees View on GitHub
does this answer your question?
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.