Page MenuHomePhabricator

[web] client method for login password user
ClosedPublic

Authored by varun on Dec 22 2023, 7:58 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Nov 13, 7:22 PM
Unknown Object (File)
Wed, Nov 13, 6:59 PM
Unknown Object (File)
Thu, Nov 7, 1:26 AM
Unknown Object (File)
Wed, Nov 6, 9:16 PM
Unknown Object (File)
Fri, Nov 1, 6:16 AM
Unknown Object (File)
Thu, Oct 24, 6:37 AM
Unknown Object (File)
Thu, Oct 24, 5:36 AM
Unknown Object (File)
Thu, Oct 24, 4:45 AM
Subscribers
None

Details

Summary

this method handles all of the logic around session ids (for sticky sessions on identity service) and OPAQUE. we return a string because that's what we do in CommRustModule, and we would like to have a single interface for the two clients.

Test Plan

called loginPasswordUser from root.js and got back a string, from which userID and access token could be parsed

Diff Detail

Repository
rCOMM Comm
Lint
No Lint Coverage
Unit
No Test Coverage

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
varun requested review of this revision.Dec 22 2023, 8:16 AM
ashoat requested changes to this revision.Dec 23 2023, 8:32 AM

Should there be a diff stack here?

web/grpc/identity-service-client-wrapper.js
21 ↗(On Diff #34992)
  1. This should probably be defined in lib/types
  2. It should be defined like other constants are defined. Try git grep Object.freeze
36–74 ↗(On Diff #34992)

Neither of these should be async functions since they don't use the await keyword

125 ↗(On Diff #34992)

Given this gets called every time we need to use the client, I think we should have it return the client directly. That lets us skip the second check on line 130. The same change can be made for deleteUser

162–164 ↗(On Diff #34992)

What do errors look like if these promises reject? Should we wrap each call with a try-catch so we're surfacing a more clear error? It would be good to make sure we can distinguish which of these calls caused an error if one of them rejects

181 ↗(On Diff #34992)

JSON.stringify seems like an implementation detail. I'd rather return the { userID, accessToken } object directly and let the caller stringify it if that's what they need to do

This revision now requires changes to proceed.Dec 23 2023, 8:32 AM
web/grpc/identity-service-client-wrapper.js
21 ↗(On Diff #34992)

this needs to be defined in web because its type (DeviceType, which is a literal union) comes from web/protobufs/identity-structs.cjs

also, this const won't be used elsewhere since we use tonic/Rust for our other gRPC clients

i've defined it like the others, though

125 ↗(On Diff #34992)

good idea

162–164 ↗(On Diff #34992)

the error contains the gRPC status code and error message received from the server, e.g.

code: 5
message: "user not found"

I've added try-catch's so we can log the client method in addition to the code and message

181 ↗(On Diff #34992)

we currently return a stringified object in commRustModule.loginPasswordUser, so i've returned the same stringified object here so we have a consistent interface to use in lib

ashoat requested changes to this revision.Jan 11 2024, 4:58 AM

Lots of issues here...

Separately: still no diff stack. You also ignored my comments about diff stacks here. I want to emphasize that (1) diff stacks should always be represented on Phabricator, (2) comments left by your reviewers should not be ignored.

web/grpc/identity-service-client-wrapper.js
21 ↗(On Diff #35512)

This is a ridiculous line. Object.freeze does nothing when passed a number. Before you use any library function in any language ever, you should do some research to understand what it is that you're calling

21 ↗(On Diff #35512)

this needs to be defined in web because its type (DeviceType, which is a literal union) comes from web/protobufs/identity-structs.cjs

That doesn't explain why it "needs" to be defined in web. It sounds like you're saying it will only be used on web since the equivalent code on both native and keyserver is implented in Rust. But the constant itself seems more general, and it feels more appropriate to keep it next to the other identity-related constants.

Meanwhile, there's really not much of a downside to defining something in lib even if it's only used in web, given that all packagers these days support tree shaking.

i've defined it like the others, though

You definitely have not defined it "like the others". Please try again, and this time please understand that it's critical you learn to read and understand code before using it.

23 ↗(On Diff #35512)

Shouldn't this be implementing IdentityServiceClient? And shouldn't IdentityServiceClient be extended to include loginPasswordUser?

If there was a stack here I could check if it's implemented in a follow-up diff, but since there's no stack I'm left to assume it's simply not done.

36–100 ↗(On Diff #35512)

@palys is modifying the same code in D10584. You'll likely have rebasing issues... I wonder if it would be easier for you to just copy-paste his approach here

Separately, it looks like you're taking a different approach if the authClient is not defined when deleteUser is called. Would be good for you two to discuss which approach makes sense.

161 ↗(On Diff #35512)

We should use this approach instead

176–178 ↗(On Diff #35512)

Same here

184 ↗(On Diff #35512)

we currently return a stringified object in commRustModule.loginPasswordUser, so i've returned the same stringified object here so we have a consistent interface to use in lib

In D10584, @tomek adds getKeyserverKeys to the IdentityServiceClient interface, but he has it return an object instead of a string. He's able to do this because of the new abstraction layer he introduces to native (IdentityServiceContextProvider).

We should take the same approach here. IdentityServiceClient should be typed to return proper objects instead of strings. The conversion on native will be handled in IdentityServiceContextProvider, and the conversion on web will be handled automatically by the proto codegen here in IdentityServiceClientWrapper.

This revision now requires changes to proceed.Jan 11 2024, 4:58 AM
varun marked 6 inline comments as done.

address feedback

varun added inline comments.
lib/types/identity-service-types.js
32–39 ↗(On Diff #35880)

I want to try to remove this from the API and get the key info within the context provider / client wrapper

lib/types/identity-service-types.js
71 ↗(On Diff #35880)
  1. Please try to be match capitalization with the rest of the codebase
  2. deviceTypes is already taken, so maybe identityDeviceTypes?

reduce number of params for login method

remove accidentally added file

web/grpc/identity-service-client-wrapper.js
175–176

there's probably a better way to resolve this, but flow was complaining that contentOneTimeKeys and notifOneTimeKeys are $ReadOnlyArray<string> but the generated methods setOneTimeContentPrekeysList() and setOneTimeNotifPrekeysList() take Array<string>

native/identity-service/identity-service-context-provider.react.js
163

We should validate a result using assertWithValidator like in e.g. getKeyserverKeys

web/grpc/identity-service-client-wrapper.js
175–176

I guess you can simply spread them, e.g. const contentOneTimeKeysArray = [...contentOneTimeKeys];

242

It is a good idea to validate this result

ashoat requested changes to this revision.Jan 25 2024, 2:52 PM
ashoat added inline comments.
native/identity-service/identity-service-context-provider.react.js
151 ↗(On Diff #36134)

Tried to preempt this here... we should not be using generateAndGetPrekeys here

Maybe you can introduce a diff preceding this one in the stack that implements an alternative to generateAndGetPrekeys that doesn't generate a new prekey on every login?

153 ↗(On Diff #36134)

The call to generateAndGetPrekeys has the potential to result in new prekeys being generated. After we upload these new keys to the identity service, we need to mark them as published

(This will likely still be true after we refactor this to not use generateAndGetPrekeys)

web/grpc/identity-service-client-wrapper.js
210 ↗(On Diff #36134)

The call to getDeviceKeyUpload has the potential to result in new one-time keys being generated. After we upload these new keys to the identity service, we need to mark them as published

(The one-time key generation should be revisited, but the above will likely still be true afterwards)

This revision now requires changes to proceed.Jan 25 2024, 2:52 PM
varun added inline comments.
native/identity-service/identity-service-context-provider.react.js
153 ↗(On Diff #36134)
web/grpc/identity-service-client-wrapper.js
210 ↗(On Diff #36134)
varun marked 2 inline comments as done.

address feedback

native/identity-service/identity-service-context-provider.react.js
225–226 ↗(On Diff #36569)

making sure we return upload the short form, as we decided in ENG-6468

ashoat requested changes to this revision.Feb 2 2024, 9:23 AM
ashoat added inline comments.
native/identity-service/identity-service-context-provider.react.js
240–241 ↗(On Diff #36569)

It seems like these both call CryptoModule::generateOneTimeKeys under the hood, but I can't tell what that's function doing.

It seems like it's generating one-time keys too often... a similar problem to the one I highlighted in D10808.

  1. The comparison in this->keys.oneTimeKeys.size() == oneTimeKeysSize should probably not be an equality check... I imagine we want to avoid generating new one-time keys if the limit is exceeded, rather than if it's exactly met.
  2. I don't have a good intuition for what this->keys.oneTimeKeys is, or why it's being checked.

Shouldn't we have consistency between native and web? I suspect that generateOneTimeKeys needs to be updated to match how retrieveAccountKeysSet handles one-time keys, but first we should figure out what this function is doing today and what this->keys.oneTimeKeys is for.

This revision now requires changes to proceed.Feb 2 2024, 9:23 AM

use new CommCoreModule::getOneTimeKeys method which doesn't generate one-time keys unnecessarily

This revision is now accepted and ready to land.Feb 7 2024, 4:02 PM
This revision was automatically updated to reflect the committed changes.