-
Notifications
You must be signed in to change notification settings - Fork 26
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
Move optional arguments after mandatory arguments #80
base: main
Are you sure you want to change the base?
Conversation
This is a decently written PR @davegomez, but I'm still worried about these changes that I mentioned here. Not only would we change the semantics of ssb-keys, we would also have to consider making breaking changes to ssb-validate which has similar function arguments. Because So a breaking change plus a possible performance tax are negatives that in my opinion are not enough to be greater than the positives (minor developer experience improvement). Not a net positive in my view, unfortunately. |
Well, I'm not sure about the performance because This changes are backwards compatible, would that be breaking? |
Oh, now I see that Sorry for the misunderstanding. |
Okay, I think this is acceptable then, if backwards compatibility is kept. I just want to make sure this new change still supports the weird corner cases, I'll mention a few inline. |
That's right. These changes in fact are not doing anything different than the current code, but just improving the validation of the arguments and the swapping. I also added test to guarantee old code will keep working as well as new code with the new order. |
index.js
Outdated
function validateParameters(obj, hmac_key) { | ||
var temp; | ||
|
||
if (isObject(hmac_key) && (isBuffer(obj) || isString(obj) || obj === null)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I noticed is that the old API supported verifyObj(keys, undefined, obj)
but if you're checking for a null
, then the undefined case will not go inside this if
, and that would be a breaking change. So I think it's safer to just check if the second argument is falsy.
By the way, it would be easier to understand this function's implementation if the arguments were called first
and second
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, to be sure, it would be good to have tests for all these weird cases. (In fact, good to have tests for these weird cases before this PR #80 is merged, to ensure backwards compat)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha! I had undefined
in my initial code and I didn't keep it because I couldn't find a usage example with undefined
.
I'll tidy up the tests and update the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good @davegomez, also note it would be useful to have a separate PR for tests that should be true for the current main
branch codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, it would be easier to understand this function's implementation if the arguments were called first and second.
While doing this I thought that is important for the function to differentiate what we are doing here. Because this is not a generalistic function used to swap two parameters but is instead of checking for very specific conditions for each of the parameters.
I added a comment and docs to clarify what is happening instead.
d1c5ebf
to
1d8a08b
Compare
@staltz I updated the PR with the changes discussed here. |
@staltz WAIT! Don't merge yet. I forgot a couple of changes. |
3c1bf01
to
dbd21a8
Compare
@staltz The PR is good to go. |
@davegomez Tests aren't passing in CI. |
This is a very interesting case. The following lines are using a Buffer created with These buffers are always filled with We should discourage this method of HMAC creation informing about the possible issue in the documentation. |
a9c2392
to
db76b5a
Compare
db76b5a
to
37643de
Compare
PR Update
|
* @param {Any} obj | ||
* @param {Any} hmac_key | ||
* @return {Array} [obj, hmac_key] | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I double appreciate internal documentation with JSDoc 👍
@davegomez It looks ready in my opinion, I'm going to ask for someone else to review as well. |
Hmm, I realize this support for both ways will complicate ssb-neon-keys' compatibility with ssb-keys, and also overall it might be very confusing that both argument orders are magically supported. I'm still somewhat on the fence with this change, in my opinion it doesn't make the code overall better (this doesn't mean I will block it from happening, just sharing my feelings about it). |
Isn't ssb-neon-keys already supporting both way as the current version of ssb-keys does? Remember the value swapping is not new, is just not this detailed and robust, but the first line of both functions is swapping the values in the case the hmac key is not present. |
Yeah, the thing is I realized that ssb-neon-keys doesn't do the swapping. One obstacle I have is that I don't know how to (or maybe we can't) check for falsy values within Rust / Neon. |
I faced the same issue with Swift and decided not to support the current order, but go with using the hmac key as the last argument, providing support only to "new implementations." |
You can ask for rust help @staltz I've looked over this and think it's well tested and documented. It's the middle of the night here so I would like another person to check closely (could be me tmrw!), as you don't crypto after midnight. |
Ok more thinking :
Why? I would hazard a guess that these methods are used less than a dozen times across all repos and those instances would be easy to find. We could surface them very quickly with a loud throw for incorrect usage. |
Ok, I think we should not publish this breaking change version before we do the investigative work to highlight all usage cases that we can identify in the wild. And then we should rather atomically update all usages. |
Let's start a collaborative checklist of modules we want to check:
feel free to edit this message |
I'm afraid of breaking changes like this in such a low-level package. I understand and appreciate the desire of the PR to move optional arguments after mandatory ones but I'd rather have the code that figures out if the module is being called in legacy mode and fix the call than to introduce a breaking change. Still, I don't want to block this if others feel like this is the way forward. I just wanted to voice that I'm OK with the magical code in the name of keeping it working for the current users. If it is documented well enough and maintainers are encouraged to refactor to the new order, then once they refactor we can introduce the breaking change. Basically for me it needs to happen backwards: 1 - introduce magical code (aka merge this PR). |
@soapdog Sounds like a good plan, we can minimize the time this magic is used in production. |
I'm good with that idea. If like to decide
(how about a throw which triggers after a certain unix time?! I've always been fascinated with the idea of code which expires. Actually maybe the magical code just doesn't run after a certain date, that would be fun) |
These changes switch the position of the
obj
andhmac_key
arguments to move the optional argument to the end of the list.To accomplish this I created a parameter validation function to assert the order of the arguments keeping backward compatibility, the function also displays a deprecation warning that can be removed when we consider appropriate.
Closes issue #67.
cc/ @christianbundy