-
Notifications
You must be signed in to change notification settings - Fork 156
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
Allow replacing nested fields #276
Comments
This was done to prevent anyone from overwriting private/protected nested fields. Let's say we have,
Then, someone with PATCH /Model/some-id
{
info: {
bmi: 33,
weight: 100
}
} With and without I agree that the current situation isn't perfect and can lead to surprising behavior. It's a compromise we chose for security reasons, I am certainly open to hearing alternative ideas here! |
i had no idea that there is access control on nested fields ... that seems to complicate things. currently there are 2 ways to interact with the API that seem different but (unfortunately) compile to the same thing, aka: If dropping support for nested security fields is an option, that would simplify this discussion a lot. They're not exposed in the docs (as far as I've seen) and they seem like a niche feature whereas this is a much more frequent occurrence. |
So you are suggesting,
This is very breaking so it's probably not going to happen on This means you would, PUT /Model/some-id
{
// entire document
...,
info: {
bmi: 33
}
} Assuming you have proper access, this would entirely replace the existing doc with this one. As a side note, keep in mind that breaking backward compatibility is okay (yay, semver!), but we have to make the changes as small as possible to allow fellow devs to easily update. |
pretty much. It definitely makes sense having this functionality on I'm not sure how common this issue is, but I find |
Yes, it could be behind a flag. |
This is pretty simple actually. This code, becomes: const cleanBody = depopulate(req.body)
if (options.updateDeep) {
cleanBody = moredots(cleanBody)
} Where The work here is mostly in writing tests and making it clear that it disables nested protected and protected fields. |
Which parts of the code are affected and have to be tested? May be we can help. |
Actually, rather than implementing yet another flag, I think we should perhaps be stricter and more "correct" in our use of HTTP verbs.
|
what happens to the private nested fields functionality in the case of i.e. if you have the object |
Right, thanks for bringing that up. I see a couple options, but I'm open to hearing your suggestions.
In retrospect, enabling private/protected nested fields was not a great choice. I'm not against taking this away, but it would make upgrading very hard on users relying on this feature. That said, if you see other options, please pitch in! |
Any progress here? |
Due to some (of my own!) earlier development decisions, it's a simple issue with complicated ramifications 😞 Removing support for private/protected nested fields would make this issue a lot easier to fix. Honestly I think that would be a good thing, but it puts some of our users in a bad spot because their schema design might require it. |
…pfel#276 for possibles issues
Thank you, this worked for me. Can you elaborate on the |
Due to the use of
moredots
inmodifyObject
, it is currently impossible to remove properties of a nested object via the API (talking about this line: https://github.com/florianholzapfel/express-restify-mongoose/blob/master/src/operations.js#L204)so if you have a schema:
User.info
is a generic object, so one would assume doing aPATCH /User/1 {info: {bmi: 33}}
would update theinfo
prop to the given value. But becausemoredots
has no concept of the schema the above query gets converted to:This is a problem because if you have the following document:
There is no way to remove
info.weight
since posting with{info: {bmi: 22}}
will just update thebmi
instead of overwriting the entireinfo
Not sure if this was the intention or not, but it seems to me that it makes more sense to have
PATCH
be update only at the root level, and not recursive.The current workaround is to specifically post with
{info: {bmi: 22, weight: null}}
which will overwrite that property tonull
which is not really ideal since it requires prior knowledge about the document and the schemaEDIT: Another workaround is if you make a middleware that does the above and sets unwanted values to
undefined
, since sending the object{info: {bmi: 22, weight: undefined}}
does removeweight
but you can't json serializeundefined
and you still have the issue of having to know about the structure of the data before updatingThe text was updated successfully, but these errors were encountered: