- Notifications
You must be signed in to change notification settings - Fork 88
Feat/add authenticate method pkp base #447
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
Conversation
| (await this.authContext?.client?.getSessionSigs( | ||
| this.authContext.getSessionSigsProps | ||
| )) || this.controllerSessionSigs; | ||
| |
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.
can we have an ultimate check to see if controllerSessionSigs exists?
if(!controllerSessionSigs){ throw new Error('bruh.. no session sigs'); }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.
Updated the pr with a new validation method validateAuthenticate() which will throw if controllerSessionSigs is not defined after authenticate is called.
MaximusHaximus left a comment
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.
Questions in-line
| const controllerSessionSigs = | ||
| (await this.authContext?.client?.getSessionSigs( | ||
| this.authContext.getSessionSigsProps | ||
| )) || this.controllerSessionSigs; |
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.
This strikes me as a bit odd -- why would we keep the existing value for this.controllerSessionSigs here rather than throwing an error if our authenticate logic returns a falsy value, or set this.controllerSessionSigs to the falsy value that was returned?
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 was also on the fence about this but wanted a fallback if a previous authenticate call was successful. But probably should just let it throw if not defined after getSessionSigs is called.
| } | ||
| } | ||
| | ||
| public async authenticate(): Promise<void> { |
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.
Would be good to have JSDoc on this if it's part of our public API, especially if we're going to leave the existing controllerSessionSigs intact if our call to getSessionSigs() returns a falsy value, explaining why that is
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.
added doc header
| this.throwError('pkpPubKey (aka. uncompressPubKey) is required'); | ||
| } | ||
| | ||
| this.validateAuthContext(); |
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.
Can we really get rid of this call and assume everything is correct? It seems like we would still want to call it, after calling authenticate? And if we're going to do that, wouldn't we want to leave the logic inside validateAuthContext() intact rather than removing the check for this.controllerSessionSigs?
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.
The problem I ran into with the validation was the now both authContext and controllerSessionSigs may be defined on the object since we will assign controllerSessionSigs in scope of authenticate which will fail validation since now both will be defined.
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.
Update: I have added a new validateAuthenticate() method to check on the internal properties of the object after getSessionSigs is called on the client which will perform the needed checks similar to validateAuthContext but is specific to the checks needed after we generate a new session instance.
| } | ||
| } | ||
| | ||
| public async authenticate(): Promise<void> { |
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.
copy/paste this if you need:
/** * Authenticates the user - generate sessionSigs from litNodeClient(authContext.client) is provided. Otherwise, use * controllerSessionSigs. * * @returns A Promise that resolves to void. * @throws An error if `controllerSessionSigs` is not found. */ | | ||
| if (providedAuthentications !== 2) { | ||
| // log which authentications has the user provided | ||
| if (this.controllerAuthSig) { |
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.
Note for myself (@Ansonhkg): remove this for 0.1 release https://linear.app/litprotocol/issue/LIT-3032/[auth-unification]-remove-all-v0-stuff-before-v1-release
MaximusHaximus left a comment
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.
Added some questions in-line -- I'm still not sure about what the golden path is for using this API and I think there are some issues w/ error handling. Happy to huddle if you'd like to work it out sync :)
| if (this.authContext) { | ||
| // It must have a valid client and getSessionSigsProps | ||
| if ( | ||
| !(this.authContext.client instanceof LitNodeClientNodeJs) || |
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.
instanceof is less than ideal way to check for validity -- we should avoid it whenever possible, especially given that we're leveraging typescript with interfaces. Consider that if someone passes us something other than a LitNodeClientNodeJs instance, but that thing still conforms to the LitClientSessionManager interface, which the type of this.authMethod expects to see as the client property, then this check will inaccurately throw an error even though it might be a usable implementation.
Also, if we disentangle LitNodeClient from LitNodeClientNodeJs in the future, or define a LitClientSessionManager object that isn't a full fledged LitNodeClientNodeJs instance, then this will be problematic since it might be an instance of multiple implementations of the client.
I think it's safest (and quite reasonable from a usability perspective) just to ducktype check that it appears to be what we expect, using e.g. this.authContext.client && this.authContext.client.getSessionSigsProps
| this.controllerSessionSigs, | ||
| ].filter(Boolean).length; | ||
| | ||
| if (providedAuthentications !== 2) { |
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'm confused -- why is 'any 2' the magic numberof authentications that passes this if check and avoids the throwError() call on L282?
Is it really ok if any combination of two of these is passed in? Why is any 2 OK? A comment here explaining why it's ok if any 2 of 3 are defined, but if only 1 or if all 3 are defined it's a critical error
| if (this.authContext) { | ||
| const controllerSessionSigs = | ||
| await this.authContext?.client?.getSessionSigs( | ||
| this.authContext.getSessionSigsProps |
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.
We try to use this.getSessionSigsProps before we actually validate that it exists inside of validateAuthenticate() (because we don't call it until after we call getSessionSigs() on the client) -- and that means that validateAuthenticate() will never throw an error in this case even if this.getSessionSigsProps is undefined, because calling getSessionSigs() with undefined will cause that function to throw a cannot get property 'sessionKey' of undefined
| } | ||
| } | ||
| | ||
| private validateAuthenticate() { |
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.
If we're only going to call it in one place and it's a private method, we may as well just in-line it where it needs to be until and if we need it in multiple places. Incidentally, this relates to my other comment below that we should be validating this.authContext.client and this.getSessionSigsProps before trying to use those properties, since if this wasn't a separate method you could easily validate those 2 things first and the authentications last.
| * @throws An error if `controllerSessionSigs` is not found after session generation has resolved. | ||
| */ | ||
| public async authenticate(): Promise<void> { | ||
| // If we dont have an authContext instance then we log that this is being depricated soon in favor of implicit session loading |
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.
Since this is a brand new method, and the only reason I can see that a consumer would ever call it is to run this.authContext.client.getSessionSigs(), can we just make it assume that the authContext functionality must be set, and must work rather than have it fall-through if it's not defined or the client isn't defined?
What is the use case for someone calling this new method without having those things defined, but being OK with the existing this.controllerSessionSigs value still remaining on the object, but only if there are exactly two out of 3 of this.controllerAuthSig, this.authContext and this.controllerSessionSigs defined, even if one of those isn't this.controllerSessionSigs?
| Closing as after some investigation with @MaximusHaximus It will be lowering the performance of the overall |
Description
Adds an
authenticatemethod which will use theauthContextif provided to reassign thecontrollerSessionSigsproperty onPKPBasewhich allows forauthenticationoperations to be explicitly invoked. This is helpful when we require to first check the authentication status before allowing other operations to occur. Without this addition it would not be possible to get thecontrollerSessionSigsbefore calling a higher level function onPKPEthersfor example.A new validation method has been added
validateAuthenticatewhich will check on the object internally to validate that authentication operations did not fail and we are able to continue with future operations on the network.Type of change
How Has This Been Tested?
An Additional check has been added to test-pkp-sign-with-session-sigs-session-cache.mjs
to assert that
sessionhas been defined before callingsignMessageChecklist: