diff --git a/Gemfile b/Gemfile index 0821c9086d8..fad0d19010e 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ gem 'rails', '~> 6.1.4' @hostdata_gem ||= { github: '18F/identity-hostdata', tag: 'v3.4.0' } @logging_gem ||= { github: '18F/identity-logging', tag: 'v0.1.0' } @saml_gem ||= { github: '18F/saml_idp', tag: 'v0.14.3-18f' } -@telephony_gem ||= { github: '18f/identity-telephony', tag: 'v0.3.1' } +@telephony_gem ||= { github: '18f/identity-telephony', tag: 'v0.4.0' } @validations_gem ||= { github: '18F/identity-validations', tag: 'v0.7.0' } gem 'identity-hostdata', @hostdata_gem diff --git a/Gemfile.lock b/Gemfile.lock index 3e23e0206d1..8a2a00dc199 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -38,10 +38,10 @@ GIT GIT remote: https://github.com/18f/identity-telephony.git - revision: ce223b6e55e052a63d6bf731f3bd90957cb2040c - tag: v0.3.1 + revision: b73e77c5b003c1b5aad9e3db867f5896781e9e88 + tag: v0.4.0 specs: - identity-telephony (0.3.1) + identity-telephony (0.4.0) aws-sdk-pinpoint aws-sdk-pinpointsmsvoice i18n diff --git a/app/controllers/users/personal_keys_controller.rb b/app/controllers/users/personal_keys_controller.rb index 58396ff4aeb..13601eab7d5 100644 --- a/app/controllers/users/personal_keys_controller.rb +++ b/app/controllers/users/personal_keys_controller.rb @@ -56,7 +56,11 @@ def send_new_personal_key_notifications telephony_responses = MfaContext.new(current_user). phone_configurations.map do |phone_configuration| - Telephony.send_personal_key_regeneration_notice(to: phone_configuration.phone) + phone = phone_configuration.phone + Telephony.send_personal_key_regeneration_notice( + to: phone, + country_code: Phonelib.parse(phone).country, + ) end form_response(emails: emails, telephony_responses: telephony_responses) diff --git a/app/controllers/users/two_factor_authentication_controller.rb b/app/controllers/users/two_factor_authentication_controller.rb index 853311db49e..09ddffd782c 100644 --- a/app/controllers/users/two_factor_authentication_controller.rb +++ b/app/controllers/users/two_factor_authentication_controller.rb @@ -183,6 +183,7 @@ def send_user_otp(method) expiration: TwoFactorAuthenticatable::DIRECT_OTP_VALID_FOR_MINUTES, channel: method.to_sym, domain: IdentityConfig.store.domain_name, + country_code: parsed_phone.country, } if UserSessionContext.authentication_context?(context) diff --git a/app/services/account_reset/cancel.rb b/app/services/account_reset/cancel.rb index aba0aaab092..1eebec4fcaa 100644 --- a/app/services/account_reset/cancel.rb +++ b/app/services/account_reset/cancel.rb @@ -30,7 +30,10 @@ def notify_user_via_email_of_account_reset_cancellation end def notify_user_via_phone_of_account_reset_cancellation - @telephony_response = Telephony.send_account_reset_cancellation_notice(to: phone) + @telephony_response = Telephony.send_account_reset_cancellation_notice( + to: phone, + country_code: Phonelib.parse(phone).country, + ) end def update_account_reset_request diff --git a/app/services/account_reset/create_request.rb b/app/services/account_reset/create_request.rb index 9a3c59ad7f8..9df3c270500 100644 --- a/app/services/account_reset/create_request.rb +++ b/app/services/account_reset/create_request.rb @@ -40,7 +40,10 @@ def notify_user_by_email(request) def notify_user_by_sms_if_applicable phone = MfaContext.new(user).phone_configurations.take&.phone return unless phone - @telephony_response = Telephony.send_account_reset_notice(to: phone) + @telephony_response = Telephony.send_account_reset_notice( + to: phone, + country_code: Phonelib.parse(phone).country, + ) end def extra_analytics_attributes diff --git a/app/services/account_reset/notify_user_of_request_cancellation.rb b/app/services/account_reset/notify_user_of_request_cancellation.rb index 9a988626e25..39077dd2285 100644 --- a/app/services/account_reset/notify_user_of_request_cancellation.rb +++ b/app/services/account_reset/notify_user_of_request_cancellation.rb @@ -21,7 +21,11 @@ def notify_user_via_email_of_account_reset_cancellation def notify_user_via_phone_of_account_reset_cancellation MfaContext.new(user).phone_configurations.each do |phone_configuration| - Telephony.send_account_reset_cancellation_notice(to: phone_configuration.phone) + phone = phone_configuration.phone + Telephony.send_account_reset_cancellation_notice( + to: phone, + country_code: Phonelib.parse(phone).country, + ) end end end diff --git a/app/services/idv/send_phone_confirmation_otp.rb b/app/services/idv/send_phone_confirmation_otp.rb index 3d48c769602..eb2f40b242c 100644 --- a/app/services/idv/send_phone_confirmation_otp.rb +++ b/app/services/idv/send_phone_confirmation_otp.rb @@ -59,6 +59,7 @@ def send_otp expiration: TwoFactorAuthenticatable::DIRECT_OTP_VALID_FOR_MINUTES, channel: delivery_method, domain: IdentityConfig.store.domain_name, + country_code: parsed_phone.country, ) add_cost otp_sent_response @@ -76,7 +77,6 @@ def add_cost end def extra_analytics_attributes - parsed_phone = Phonelib.parse(phone) { otp_delivery_preference: delivery_method, country_code: parsed_phone.country, @@ -85,5 +85,9 @@ def extra_analytics_attributes telephony_response: @telephony_response, } end + + def parsed_phone + @parsed_phone ||= Phonelib.parse(phone) + end end end diff --git a/app/services/idv/steps/send_link_step.rb b/app/services/idv/steps/send_link_step.rb index c88919e797a..9798514f54c 100644 --- a/app/services/idv/steps/send_link_step.rb +++ b/app/services/idv/steps/send_link_step.rb @@ -35,6 +35,7 @@ def send_link Telephony.send_doc_auth_link( to: formatted_destination_phone, link: link(session_uuid), + country_code: Phonelib.parse(formatted_destination_phone).country, ) end diff --git a/app/services/user_alerts/alert_user_about_personal_key_sign_in.rb b/app/services/user_alerts/alert_user_about_personal_key_sign_in.rb index 9bfe7f23713..cbbb97323ce 100644 --- a/app/services/user_alerts/alert_user_about_personal_key_sign_in.rb +++ b/app/services/user_alerts/alert_user_about_personal_key_sign_in.rb @@ -8,7 +8,11 @@ def self.call(user, disavowal_token) ).deliver_now end telephony_responses = MfaContext.new(user).phone_configurations.map do |phone_configuration| - Telephony.send_personal_key_sign_in_notice(to: phone_configuration.phone) + phone = phone_configuration.phone + Telephony.send_personal_key_sign_in_notice( + to: phone, + country_code: Phonelib.parse(phone).country, + ) end form_response(emails: emails, telephony_responses: telephony_responses) end diff --git a/config/application.yml.default b/config/application.yml.default index 052b53319f6..38b4595fae1 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -58,6 +58,7 @@ database_timeout: '5000' deleted_user_accounts_report_configs: '[]' disable_email_sending: 'true' disallow_all_web_crawlers: 'true' +pinpoint_sms_sender_id: 'aaa' doc_auth_extend_timeout_by_minutes: '40' doc_capture_polling_enabled: 'true' doc_auth_client_glare_threshold: '50' diff --git a/config/initializers/telephony.rb b/config/initializers/telephony.rb index 7cc388e4be5..3aa01137089 100644 --- a/config/initializers/telephony.rb +++ b/config/initializers/telephony.rb @@ -1,3 +1,5 @@ +require 'pinpoint_supported_countries' + # rubocop:disable Metrics/BlockLength Telephony.config do |c| c.adapter = IdentityConfig.store.telephony_adapter.to_sym @@ -10,7 +12,10 @@ c.voice_pause_time = IdentityConfig.store.voice_otp_pause_time c.voice_rate = IdentityConfig.store.voice_otp_speech_rate - c.sender_id = IdentityConfig.store.pinpoint_sms_sender_id + c.country_sender_ids = IdentityConfig.store.pinpoint_sms_sender_id.presence && + PinpointSupportedCountries::SENDER_ID_COUNTRIES.index_with do + IdentityConfig.store.pinpoint_sms_sender_id + end IdentityConfig.store.pinpoint_sms_configs.each do |sms_json_config| c.pinpoint.add_sms_config do |sms| diff --git a/config/pinpoint_overrides.yml b/config/pinpoint_overrides.yml index c640daad7c3..7ddb11362bb 100644 --- a/config/pinpoint_overrides.yml +++ b/config/pinpoint_overrides.yml @@ -87,8 +87,6 @@ IE: supports_voice: false IL: supports_voice: false -IN: - supports_sms: true IQ: supports_sms_unconfirmed: false IS: diff --git a/config/pinpoint_supported_countries.yml b/config/pinpoint_supported_countries.yml index 7c41bf133ce..5d321882ebe 100644 --- a/config/pinpoint_supported_countries.yml +++ b/config/pinpoint_supported_countries.yml @@ -437,7 +437,7 @@ IM: IN: country_code: '91' name: India - supports_sms: false + supports_sms: true supports_voice: false IQ: country_code: '964' diff --git a/lib/pinpoint_supported_countries.rb b/lib/pinpoint_supported_countries.rb index c8635663345..4b2acec30e3 100644 --- a/lib/pinpoint_supported_countries.rb +++ b/lib/pinpoint_supported_countries.rb @@ -66,16 +66,18 @@ def sms_support select { |sms_config| sms_config['ISO code'] }. # skip section rows map do |sms_config| iso_code = sms_config['ISO code'] - supports_sms = case trim_digits_spaces(sms_config['Supports sender IDs']) - when 'Registration required' + supports_sms = case trim_spaces(sms_config['Supports sender IDs']) + when 'Registration required1' SENDER_ID_COUNTRIES.include?(iso_code) + when 'Registration required3' # basically only India, has special rules + true else true end CountrySupport.new( iso_code: iso_code, - name: trim_digits_spaces(sms_config['Country or region']), + name: trim_spaces(sms_config['Country or region']), supports_sms: supports_sms, ) end @@ -85,7 +87,7 @@ def sms_support def voice_support TableConverter.new(download(PINPOINT_VOICE_URL)).convert.map do |voice_config| CountrySupport.new( - name: trim_digits_spaces( + name: trim_spaces( voice_config['Country or Region'], # Yes, it is capitalized differently :[ ), supports_voice: true, @@ -145,8 +147,8 @@ def name_to_iso_code(name) }[name] end - def trim_digits_spaces(str) - str.gsub(/\s{2,}/, ' ').gsub(/[\d\s]+$/, '') + def trim_spaces(str) + str.gsub(/\s{2,}/, ' ').gsub(/\s+$/, '') end def digits_only?(str) diff --git a/spec/controllers/test/telephony_controller_spec.rb b/spec/controllers/test/telephony_controller_spec.rb index 708b98521b9..f03a38376b6 100644 --- a/spec/controllers/test/telephony_controller_spec.rb +++ b/spec/controllers/test/telephony_controller_spec.rb @@ -9,6 +9,7 @@ expiration: 10, channel: :sms, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) Telephony.send_authentication_otp( to: '(555) 555-5000', @@ -16,6 +17,7 @@ expiration: 10, channel: :voice, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) get :index @@ -44,6 +46,7 @@ expiration: 10, channel: :sms, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) Telephony.send_authentication_otp( to: '(555) 555-5000', @@ -51,6 +54,7 @@ expiration: 10, channel: :voice, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) delete :destroy diff --git a/spec/controllers/users/two_factor_authentication_controller_spec.rb b/spec/controllers/users/two_factor_authentication_controller_spec.rb index 6250a6b8201..a62fc6477eb 100644 --- a/spec/controllers/users/two_factor_authentication_controller_spec.rb +++ b/spec/controllers/users/two_factor_authentication_controller_spec.rb @@ -251,6 +251,7 @@ def index expiration: 10, channel: :sms, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) expect(subject.current_user.direct_otp).not_to eq(@old_otp) expect(subject.current_user.direct_otp).not_to be_nil @@ -328,6 +329,7 @@ def index expiration: 10, channel: :voice, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) expect(subject.current_user.direct_otp).not_to eq(@old_otp) expect(subject.current_user.direct_otp).not_to be_nil @@ -384,6 +386,7 @@ def index expiration: 10, channel: :sms, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) end diff --git a/spec/features/two_factor_authentication/change_factor_spec.rb b/spec/features/two_factor_authentication/change_factor_spec.rb index 55b422d8c54..5b74ab39f65 100644 --- a/spec/features/two_factor_authentication/change_factor_spec.rb +++ b/spec/features/two_factor_authentication/change_factor_spec.rb @@ -43,6 +43,7 @@ expiration: 10, channel: :sms, domain: IdentityConfig.store.domain_name, + country_code: 'US', ) expect(current_path). diff --git a/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb b/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb index d33c84029eb..d0d21692b3c 100644 --- a/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb +++ b/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb @@ -13,7 +13,7 @@ expect(personal_key_sign_in_mail).to receive(:deliver_now) expect(UserMailer).to receive(:personal_key_sign_in).and_return(personal_key_sign_in_mail) expect(Telephony).to receive(:send_personal_key_sign_in_notice). - with(to: '+1 (202) 345-6789') + with(to: '+1 (202) 345-6789', country_code: 'US') sign_in_before_2fa(user) choose_another_security_option('personal_key') diff --git a/spec/features/users/regenerate_personal_key_spec.rb b/spec/features/users/regenerate_personal_key_spec.rb index b543dbc788c..3032260c924 100644 --- a/spec/features/users/regenerate_personal_key_spec.rb +++ b/spec/features/users/regenerate_personal_key_spec.rb @@ -20,7 +20,7 @@ with(user, user.email). and_return(personal_key_sign_in_mail) expect(Telephony).to receive(:send_personal_key_regeneration_notice). - with(to: user.phone_configurations.first.phone) + with(to: user.phone_configurations.first.phone, country_code: 'US') visit account_two_factor_authentication_path click_button t('account.links.regenerate_personal_key') diff --git a/spec/lib/pinpoint_supported_countries_spec.rb b/spec/lib/pinpoint_supported_countries_spec.rb index a027565036f..9d90021e349 100644 --- a/spec/lib/pinpoint_supported_countries_spec.rb +++ b/spec/lib/pinpoint_supported_countries_spec.rb @@ -60,6 +60,13 @@