-
Notifications
You must be signed in to change notification settings - Fork 51
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
Failing update operations with encrypted subdocument array on Mongoose 6 #105
Comments
So I was able to get around this by calling doc.children[0].text = 'New unencrypted text';
doc.directModifiedPaths().forEach((path) => doc.unmarkModified(path));
doc.save(); I believe this is because mongoose v6 now uses proxies for arrays and uses them to track modifications. |
@spencersteers cool, thanks! That workaround seems to help in my case, too. |
Thanks @yelworc for reporting this and for the excellent unit test! I agree that this should be taken care of within the plugin. The As to fixing it in the plugin, I do agree that should be done. I might not get to it for a bit since I'll first need to get up to date on whatever Mongoose is doing with its subdocuments these days and am not using it day-to-day anymore. Definitely welcome any PRs if folks with a bit more familiarity want to take a stab. If you branch from @yelworc's excellent unit test then the CI pipeline will take care of testing across both Mongoose version 5 & 6, and also crediting appropriately. Ideally there can be a simple fix, that just updates the handling of subdocs to match whatever Mongoose now expects, but maintains backward compatibility with Mongoose v5. It does seem like unmarking modified could help, but again I'm not sure the repercussions, and importantly don't want to break scenarios in which a user might be using this alongside another mongoose plugin, or their own middleware, which certainly could take advantage of that. Maybe if we did it as the very last step before encrypting that would be safe...? Welcome any thoughts on this as well! |
Any progress for this thread ? MongoDb Atlas will update to MongoDB 5 (witch is only compatible with Mongoose v6 => https://mongoosejs.com/docs/compatibility.html) on shared cluster next week... |
As of Mongoose v6, encrypted subdocument arrays lead to the following error when updating an existing document: > MongoServerError: Updating the path '…' would create a conflict at '…' This change circumvents the problem by marking the corresponding schema paths as unmodified (which should be safe, since those encrypted fields are not meant to be stored anyway). Fixes joegoldbeck#105
Tried my luck at a fix (see #119). Thanks for your feedback, @joegoldbeck – I share your concerns around I think this is the PR that introduced the new array change tracking in Mongoose; as far as I can see, there is no option to disable it (which might have been another solution to this problem). |
FWIW, I finally upgraded our production system to Mongoose 6 some 4 weeks ago, using the workaround/fix in #119 – no ugly surprises so far 😄 EDIT: Moved to Mongoose 7 for a short bit, and now finally on Mongoose 8. Everything still seems to be fine. |
I'm getting errors like this one when trying to update encrypted documents after upgrading to Mongoose 6:
The schema/model in question has encryption enabled for an entire field that contains an array of subdocuments, i.e.
schema.plugin(encrypt, { /* keys… */, encryptedFields: ['subdocs'] });
This may not have been a good idea, but here we are 😄 (it's been in production like that for a long time).
I created a unit test that reproduces the problem. With Mongoose 5, the update operation results in this query:
whereas with Mongoose 6, it's:
Most likely, the
children.0.text
in the$unset
part of the query is the issue. That's about as far as I got – not sure where to go from here…The text was updated successfully, but these errors were encountered: