Disable phone OTP option in select US area codes#1559
Conversation
|
Right now this only includes code for the frontend part of this. I still need to figure how this looks on the backend. |
zachmargolis
left a comment
There was a problem hiding this comment.
definitely worth re-doing
There was a problem hiding this comment.
Do we want to worry about translating these names?
There was a problem hiding this comment.
Also I think we should move these values to something on the server, and expose them as data- attributes in the DOM or something (that way we can double check these values on the server which also works for clients without JS)
There was a problem hiding this comment.
Yeah, still working on the direction for how this looks on the server and thinking in that direction.
There was a problem hiding this comment.
might be worth expanding our custom I18n.t in JS to do templating?
ex
I18n.t('devise.two_factor_authentication.otp_delivery_preference.phone_unsupported', { location: country })There was a problem hiding this comment.
did you mean to query the entire document? or just a part of a particular form?
There was a problem hiding this comment.
Ooops, meant to come back and clean this part up.
There was a problem hiding this comment.
what if we called the variable guam_phone and removed the comment?
|
I've made some changes. For forms with an OTP delivery method option, I added a validation to confirm that the OTP delivery method is supported for the given phone number. If it is not, it will add an error explaining the problem. For forms without an OTP delivery method option (edit 2FA method form and idv phone confirmation) I added some code to make sure the OTP is sent via SMS and that the option to send a code via voice call is not presented to the user. |
|
Changed it up a little bit more so that the unsupported area codes are fed to the form in a data attribute. This should be ready for review now. |
|
We should remove the "Mobile or landline okay" text, or make it dynamic such that it says "Mobile only" when voice is not supported. |
.rubocop.yml
Outdated
There was a problem hiding this comment.
Rubocop does not check Slim files. This can safely be removed.
There was a problem hiding this comment.
We have rubocop enabled for slim-lint. It runs rubocop on the files after slim processes them. I added a multiline hash to one and since slim removes all indentation this cop got angry.
There is a ignored_cops options for slim-lint, but adding one cop to that appears to re-enable all of the cops that slim-lint ignores by default.
There was a problem hiding this comment.
Huh. This must be new. I didn't know you could disable cops within .rubocop.yml for slim-lint to ignore.
There was a problem hiding this comment.
@monfresh: Here's the line that makes slim-lint upset. An alternative I'd prefer to disabling the IndentHash cop is figuring out how to make this a bit shorter.
There was a problem hiding this comment.
Yes, I thought about that. You could set the hash in the controller and pass it to the view as a local variable.
There was a problem hiding this comment.
Personally I think using Phonelib here is clearer, like we do here? https://github.com/18F/identity-idp/blob/master/app/forms/otp_delivery_selection_form.rb#L37-L48
Phonelib.parse(phone).area_codeThere was a problem hiding this comment.
Fancy 👔. So many phone gems.....
There was a problem hiding this comment.
Alright, so this started breaking the spec for the IdV flow. The problem is that at this point the phone number has been formatted for the vendor and no longer includes the country code. It appears to still work for US numbers, but gets confused for numbers with a US country code.
Using Phony to normalize it to add the +1 works, so I may do that.
Related: We may want to make sure we only accept US phone numbers for IdV in #1544
There was a problem hiding this comment.
so it looks like in all the uses of this, we do !capabilities.voice? -- maybe should we just invert it and switch to capabilities.sms_only?
|
One thing this PR doesn't address is that in the screen where you enter your new phone number when you want to change it, it doesn't mention anything about what kind of phone you can enter. Perhaps we should replace that view with the same view as in the Phone Setup? |
|
Re the UI issue on the OTP verification: Looks like it also breaks if you have an authenticator app. It just says " or get a security code via authentication app." I did also consider pulling the same UI we use for 2FA setup into the edit 2FA view, but wanted to pause on that and prioritize international calling and then come back to it if we have time at the end of this sprint or the beginning of the next one. |
|
Alright, I think I've addressed everything above^ |
4faec7e to
662d2cf
Compare
There was a problem hiding this comment.
Code Climate says this line is not tested.
There was a problem hiding this comment.
Ah yeah, this presenter has basically no tests. I can stick some in there.
There was a problem hiding this comment.
@monfresh: Added tests for the parts I changed.
There was a problem hiding this comment.
We discourage the use of allow_any_instance_of, as do the RSpec docs: https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance
The problem with this before statement is that it makes it look like UpdateUser should be called even if the validation failed, which is not true.
Instead, we do something like:
update_user = instance_double(UpdateUser)
attributes = { otp_delivery_preference: 'voice' }
allow(UpdateUser).to receive(:new).with(user: user, attributes: attributes).and_return(update_user)
expect(update_user).to receive(:call) # when validation passes
capabilities = instance_double(PhoneNumberCapabilities)
allow(PhoneNumberCapabilities).to receive(:new).with(phone).and_return(capabilities)
allow(capabilities).to receive(:sms_only).and_return(false)
result = subject.submit(phone: phone, otp_delivery_preference: 'voice')and
expect(update_user).to_not receive(:call) # when validation failsThere was a problem hiding this comment.
@monfresh: Feels weird to stub new 🤔, but I went ahead and changed the test. I used a spy for the phone number capabilities because it handles some other calls to build the error message.
There was a problem hiding this comment.
That's what I get for copy/pasting 😳
**Why**: Twilio does not allow us to call users in some US territories which have a +1 internation code. This commit adds frontend code that disables the phone option and messages the user that they will have to receive an OTP via text. Validate that phone and otp delivery method match **Why**: If we can't support voice for a user's phone number, and they manage to submit the form (e.g. they have JS disabled) we want to display an error message explaining the problem Disable unsupported voice cofirm in phone forms **Why**: If a user provides a phone number that is unsupported for voice in the form to edit their 2FA phone number or the idv phone form, we want to send them an SMS and not send them give them the option to select phone. Load unsupported phone area codes in data attr **Why**: We don't want to maintain a list of unsupported area codes in both the JS and in the ruby code.
9c03886 to
2f053bc
Compare



Why: Twilio does not allow us to call users in some US territories
which have a +1 internation code. This commit adds frontend code that
disables the phone option and messages the user that they will have to
receive an OTP via text.