fix: Don't reencrypt vault with no private values using Model.build #9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We sometimes serialize a Sequelize model, and then rehydrate it using
Model.build
at a later time. This object is in the form:Where the
encrypted
field is asequelize-encrypted
vault.As part of
Model.build
, Sequelize calls all custom field setters. This results inVault.set()
being called with{}
, at which point it is re-encrypted in case the user ends up calling.save()
. However, given the default value for a Vault call is{}
anyway, this operation is pointless.With many sub-objects, this behaviour becomes pathological and causes serious performance issues:
This PR simply skips the re-encryption operation if
Vault.set()
is called with an empty object (and there's no existing data to override).Note, that this PR only helps performance in cases where the vault is empty - in cases where it is not, the existing behaviour is maintained. Ideally, (re)encryption would be deferred to the point that the user actually calls
.save()
on a field.With the same data, after this PR a performance trace is much saner (44ms -> 17ms on 1500 subobjects):