feat(recovery-phone): Display phone number in desired format (masking + Twilio's nationalFormat)#18340
Conversation
92dd1a7 to
a8c9e68
Compare
| return undefined; | ||
| } | ||
| const { uid: userId, phoneNumber, lookupData } = row; | ||
| const nationalFormat = isLookupDataObject(lookupData) |
There was a problem hiding this comment.
This seems a lot simpler to me:
const nationalFormat = lookupData?.['nationalFormat']
We are at the DB layer here, so there might be some casting going on here. We know what we store is either null or a JsonObject, and if it's object it should contain nationalFormat, but might not. Either way the type guard doesn't do much for me, and I like the cleanliness of optimistic resolution. Just my two cents.
There was a problem hiding this comment.
Yeah this was meant to be a thing to clean up for sure. I had tried that, and I get this:
Element implicitly has an 'any' type because expression of type '"nationalFormat"' can't be used to index type 'string | number | boolean | JsonArray | JsonObject'.
Property 'nationalFormat' does not exist on type 'string | number | boolean | JsonArray | JsonObject'.
I wasn't sure if there was a better way to pull JSON out? But I can just go with
const nationalFormat = (lookupData as { nationalFormat?: string })?.nationalFormat which works. 👍
| new RecoveryPhoneNotEnabled() | ||
| ); | ||
| expect(() => service.maskPhoneNumber('+15550005555')).toThrow( | ||
| expect(() => service.stripPhoneNumber('+15550005555')).toThrow( |
There was a problem hiding this comment.
In someone ways I'd prefer both things to exist. Seems like UX flip flops a lot, and additive changes are easier to track.
There was a problem hiding this comment.
I'm not sure if I like the back-end handling adding the bullet points. Since that feels more presentation layer to me, I think it's nicer for the front-end to handle it - so if we want to change this in the future, we can in those new recovery-phone-utils functions.
| phoneNumber | ||
| ); | ||
| } catch (e) { | ||
| // This should not fail since the number was already validated with Twilio but |
There was a problem hiding this comment.
I'd remove this... If it shouldn't fail, let's not worry about the try catch. If we are worried about the twilio call failing, then let's manually capture a sentry error so we at least know this feature isn't functioning properly.
There was a problem hiding this comment.
There is just the possibility of a network error here for whatever reason. I can remove it if we want though.
| // Clamp lastN between 0 and digits.length | ||
| if (lastN > digits.length) { | ||
| lastN = digits.length; | ||
| } else if (lastN <= 0) { |
There was a problem hiding this comment.
Semantically this doesn't make sense to me. Would would a negaive lastN digits even mean? I'd error or set to 0 as I did above.
There was a problem hiding this comment.
I agree - I actually wasn't sure why we allowed a negative number in the other function, but right now this basically treats negative numbers the same as 0. I've changed this locally to just return an empty string for <= 0 as I think that's more clear.
| phoneNumber: string, | ||
| headers?: Headers | ||
| ) { | ||
| ): Promise<{ nationalFormat?: string }> { |
There was a problem hiding this comment.
This also has a success flag. Might nice to include it too.
| // OTP confirm page before then. "Basic lookups" from Twilio are free, so don't | ||
| // bother persisting in redis. | ||
| // https://www.twilio.com/en-us/user-authentication-identity/pricing/lookup | ||
| const { nationalFormat } = await this.smsManager.phoneNumberLookup( |
There was a problem hiding this comment.
I think this is true, but we might still hit twilio API rate limits. I am pretty sure customs will keep us safe, and we wouldn't encounter this type of volume, but just wanted to mention it.
There was a problem hiding this comment.
Ah yeah. I was so torn on sticking this into redis or not, we only store OTP codes there now from what I can tell. Maybe this is worth noting somewhere in some docs.
There was a problem hiding this comment.
I decided to leave this and just updated the comment noting it would be a network problem. I'm OK if we remove this later though.
| uid, | ||
| } | ||
| ); | ||
| return { nationalFormat }; |
There was a problem hiding this comment.
Should we maybe return both the phoneNumber and the nationalFormat, might be a better API design. Also it's unlikely but possible that the phoneNumber exists, but the nationalFormat does not...
|
I'm going to go ahead and open this out of draft but still want to add a few more tests. |
cac5e46 to
b85d415
Compare
| uid, | ||
| } | ||
| ); | ||
| return { phoneNumber, nationalFormat }; |
There was a problem hiding this comment.
I think this is the problem... Missing { status: RecoveryPhoneStatus.SUCCESS }
28346ca to
b28bd9c
Compare
… + Twilio's nationalFormat) Because: * We want to show the national format provided by Twilio to better display phone numbers for users This commit: * Adds a Twilio lookup call at recovery phone number add for nationalFormat, reads nationalFormat from DB when querying recovery phone data * Updates our server response to return the last 4 digits of a phone number instead of the mask, displays accordingly on the client including new copy * Updates account resolver recovery phone auth-server call to ensure only the last 4 digits are returned if a user's session is not verified closes FXA-11044
Because:
This commit:
closes FXA-11044