From f6d93a7683673508372485fdebfb5d875df87a71 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 31 May 2024 12:08:26 -0400 Subject: [PATCH 1/4] Document analytics for critical-path sign-in flow changelog: Internal, Analytics, Document analytics for critical-path sign-in flow --- app/services/analytics_events.rb | 141 +++++++++++++++++++------------ 1 file changed, 88 insertions(+), 53 deletions(-) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 4b0588c6407..86e9ad17975 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -3639,20 +3639,22 @@ def logout_initiated( # @param [Boolean] success Whether authentication was successful # @param [Hash] errors Authentication error reasons, if unsuccessful # @param [Hash] error_details Details for error that occurred in unsuccessful submission - # @param [String] context - # @param [Boolean] new_device - # @param [String] multi_factor_auth_method + # @param ["authentication","reauthentication","confirmation"] context User session context + # @param [Boolean] new_device Whether the user is authenticating from a new d evice + # @param [String] multi_factor_auth_method Authentication method used # @param [DateTime] multi_factor_auth_method_created_at time auth method was created - # @param [Integer] auth_app_configuration_id - # @param [Integer] piv_cac_configuration_id - # @param [Integer] key_id - # @param [Integer] webauthn_configuration_id - # @param [Integer] phone_configuration_id - # @param [Boolean] confirmation_for_add_phone - # @param [String] area_code - # @param [String] country_code + # @param [Integer] auth_app_configuration_id Database ID of authentication app configuration + # @param [Integer] piv_cac_configuration_id Database ID of PIV/CAC configuration + # @param [Integer] key_id PIV/CAC key_id + # @param [Integer] webauthn_configuration_id Database ID of WebAuthn configuration + # @param [Integer] phone_configuration_id Database ID of phone configuration + # @param [Boolean] confirmation_for_add_phone Whether authenticating while adding phone + # @param [String] area_code Area code of phone number + # @param [String] country_code Country code associated with phonoe number # @param [String] phone_fingerprint the hmac fingerprint of the phone number formatted as e164 # @param [String] frontend_error Name of error that occurred in frontend during submission + # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow + # @param [Integer] enabled_mfa_methods_count Number of MFAs associated with user # Multi-Factor Authentication def multi_factor_auth( success:, @@ -3673,6 +3675,8 @@ def multi_factor_auth( country_code: nil, phone_fingerprint: nil, frontend_error: nil, + in_account_creation_flow: nil, + enabled_mfa_methods_count: nil, **extra ) track_event( @@ -3696,6 +3700,8 @@ def multi_factor_auth( country_code: country_code, phone_fingerprint: phone_fingerprint, frontend_error:, + in_account_creation_flow:, + enabled_mfa_methods_count:, **extra, }.compact, ) @@ -3764,24 +3770,39 @@ def multi_factor_auth_enter_backup_code_visit(context:, **extra) ) end - # @param [String] context + # @param ["authentication","reauthentication","confirmation"] context User session context # @param [String] multi_factor_auth_method # @param [Boolean] confirmation_for_add_phone # @param [Integer] phone_configuration_id + # @param [String] area_code Area code of phone number + # @param [String] country_code Abbreviated country code associated with phone number + # @param [String] phone_fingerprint Fingerprint hash of phone number + # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow + # @param [Integer] enabled_mfa_methods_count Number of MFAs associated with user # Multi-Factor Authentication enter OTP visited def multi_factor_auth_enter_otp_visit( context:, multi_factor_auth_method:, confirmation_for_add_phone:, phone_configuration_id:, + area_code:, + country_code:, + phone_fingerprint:, + in_account_creation_flow:, + enabled_mfa_methods_count:, **extra ) track_event( 'Multi-Factor Authentication: enter OTP visited', - context: context, - multi_factor_auth_method: multi_factor_auth_method, - confirmation_for_add_phone: confirmation_for_add_phone, - phone_configuration_id: phone_configuration_id, + context:, + multi_factor_auth_method:, + confirmation_for_add_phone:, + phone_configuration_id:, + area_code:, + country_code:, + phone_fingerprint:, + in_account_creation_flow:, + enabled_mfa_methods_count:, **extra, ) end @@ -4059,17 +4080,23 @@ def oidc_logout_visited( end # Tracks when a sucessful openid authorization request is returned + # @param [Boolean] success Whether form validations were succcessful + # @param [Boolean] user_sp_authorized Whether user granted consent during this authorization # @param [String] client_id # @param [String] code_digest hash of returned "code" param def openid_connect_authorization_handoff( + success:, + user_sp_authorized:, client_id:, code_digest:, **extra ) track_event( 'OpenID Connect: authorization request handoff', - client_id: client_id, - code_digest: code_digest, + success:, + user_sp_authorized:, + client_id:, + code_digest:, **extra, ) end @@ -4161,29 +4188,32 @@ def openid_connect_token(client_id:, user_id:, code_digest:, expires_in:, ial:, end # Tracks when user makes an otp delivery selection + # @param [Boolean] success Whether the form was submitted successfully. + # @param [Hash] errors Errors resulting from form validation + # @param ["authentication","reauthentication","confirmation"] context User session context # @param [String] otp_delivery_preference (sms or voice) - # @param [Boolean] resend - # @param [String] country_code - # @param [String] area_code - # @param ["authentication","reauthentication","confirmation"] context user session context - # @param [Hash] pii_like_keypaths + # @param [Boolean] resend Whether the user requested another code + # @param [String] country_code Country code associated with phone number + # @param [String] area_code Area code of phone number def otp_delivery_selection( + success:, + errors:, + context:, otp_delivery_preference:, resend:, country_code:, area_code:, - context:, - pii_like_keypaths:, **extra ) track_event( 'OTP: Delivery Selection', - otp_delivery_preference: otp_delivery_preference, - resend: resend, - country_code: country_code, - area_code: area_code, - context: context, - pii_like_keypaths: pii_like_keypaths, + success:, + errors:, + context:, + otp_delivery_preference:, + resend:, + country_code:, + area_code:, **extra, ) end @@ -5182,14 +5212,15 @@ def user_registration_2fa_setup_visit( end # User registration has been handed off to agency page - # @param [Boolean] ial2 - # @param [Integer] ialmax - # @param [String] service_provider_name - # @param [String] page_occurence - # @param [String] needs_completion_screen_reason + # @param [Boolean] ial2 Whether the user registration was for a verified identity + # @param [Integer] ialmax Whether the user registration was for an IALMax request + # @param [String] service_provider_name The friendly name of the service provider + # @param ['account-page','agency-page'] page_occurence Where the user concluded registration + # @param ['new_sp','new_attributes','reverified_after_consent'] needs_completion_screen_reason The + # reason for the consent screen being shown # @param [Boolean] in_account_creation_flow Whether user is going through account creation - # @param [Array] sp_request_requested_attributes - # @param [Array] sp_session_requested_attributes + # @param [Array] sp_request_requested_attributes Attributes requested by the service provider + # @param [Array] sp_session_requested_attributes Attributes requested by the service provider def user_registration_agency_handoff_page_visit( ial2:, service_provider_name:, @@ -5226,18 +5257,21 @@ def user_registration_cancellation(request_came_from:, **extra) end # Tracks when user completes registration - # @param [Boolean] ial2 - # @param [Boolean] ialmax - # @param [String] service_provider_name - # @param [String] page_occurence - # @param [String] needs_completion_screen_reason - # @param [Array] sp_request_requested_attributes - # @param [Array] sp_session_requested_attributes + # @param [Boolean] ial2 Whether the user registration was for a verified identity + # @param [Boolean] ialmax Whether the user registration was for an IALMax request + # @param [String] service_provider_name The friendly name of the service provider + # @param ['account-page','agency-page'] page_occurence Where the user concluded registration + # @param ['new_sp','new_attributes','reverified_after_consent'] needs_completion_screen_reason The + # reason for the consent screen being shown + # @param [Array] sp_request_requested_attributes Attributes requested by the service provider + # @param [Array] sp_session_requested_attributes Attributes requested by the service provider + # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow # @param [String, nil] disposable_email_domain Disposable email domain used for registration def user_registration_complete( ial2:, service_provider_name:, page_occurence:, + in_account_creation_flow:, needs_completion_screen_reason:, sp_session_requested_attributes:, sp_request_requested_attributes: nil, @@ -5247,14 +5281,15 @@ def user_registration_complete( ) track_event( 'User registration: complete', - ial2: ial2, - ialmax: ialmax, - service_provider_name: service_provider_name, - page_occurence: page_occurence, - needs_completion_screen_reason: needs_completion_screen_reason, - sp_request_requested_attributes: sp_request_requested_attributes, - sp_session_requested_attributes: sp_session_requested_attributes, - disposable_email_domain: disposable_email_domain, + ial2:, + ialmax:, + service_provider_name:, + page_occurence:, + in_account_creation_flow:, + needs_completion_screen_reason:, + sp_request_requested_attributes:, + sp_session_requested_attributes:, + disposable_email_domain:, **extra, ) end From 5aea38fca226fccd18607c571ddf5f0c0261e5bf Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 31 May 2024 13:11:59 -0400 Subject: [PATCH 2/4] Remove unnecessary allowed_extra_analytics --- spec/controllers/account_reset/request_controller_spec.rb | 2 +- spec/controllers/sign_up/completions_controller_spec.rb | 2 +- spec/features/ialmax/saml_sign_in_spec.rb | 2 +- spec/features/remember_device/cookie_expiration_spec.rb | 3 +-- spec/features/remember_device/revocation_spec.rb | 2 +- spec/features/remember_device/session_expiration_spec.rb | 3 +-- spec/features/reports/sp_active_users_report_spec.rb | 2 +- spec/features/saml/multiple_endpoints_spec.rb | 2 +- spec/features/saml/saml_logout_spec.rb | 2 +- spec/features/saml/saml_relay_state_spec.rb | 2 +- spec/features/saml/saml_spec.rb | 2 +- spec/features/sign_in/banned_users_spec.rb | 2 +- spec/features/sign_in/remember_device_default_spec.rb | 2 +- spec/features/sign_in/sp_return_log_spec.rb | 2 +- .../two_factor_authentication/backup_code_sign_up_spec.rb | 2 +- .../two_factor_authentication/second_mfa_reminder_spec.rb | 2 +- spec/features/visitors/bad_password_spec.rb | 3 +-- spec/requests/openid_connect_authorize_spec.rb | 3 +-- 18 files changed, 18 insertions(+), 22 deletions(-) diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 5077481222c..47a05718390 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe AccountReset::RequestController, allowed_extra_analytics: [:*] do +RSpec.describe AccountReset::RequestController do include ActionView::Helpers::DateHelper let(:user) { create(:user, :with_authentication_app) } describe '#show' do diff --git a/spec/controllers/sign_up/completions_controller_spec.rb b/spec/controllers/sign_up/completions_controller_spec.rb index 6f0b9990838..cb77ae0be7d 100644 --- a/spec/controllers/sign_up/completions_controller_spec.rb +++ b/spec/controllers/sign_up/completions_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SignUp::CompletionsController, allowed_extra_analytics: [:*] do +RSpec.describe SignUp::CompletionsController do let(:temporary_email) { 'name@temporary.com' } describe '#show' do diff --git a/spec/features/ialmax/saml_sign_in_spec.rb b/spec/features/ialmax/saml_sign_in_spec.rb index 9111adfb23e..cf6aa2a6545 100644 --- a/spec/features/ialmax/saml_sign_in_spec.rb +++ b/spec/features/ialmax/saml_sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML IALMAX sign in', allowed_extra_analytics: [:*] do +RSpec.feature 'SAML IALMAX sign in' do include SamlAuthHelper context 'with an ial2 SP' do diff --git a/spec/features/remember_device/cookie_expiration_spec.rb b/spec/features/remember_device/cookie_expiration_spec.rb index 4aa8f4a6af4..b17659d3c52 100644 --- a/spec/features/remember_device/cookie_expiration_spec.rb +++ b/spec/features/remember_device/cookie_expiration_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' -RSpec.describe 'signing in with remember device and closing browser', - allowed_extra_analytics: [:*] do +RSpec.describe 'signing in with remember device and closing browser' do include SamlAuthHelper let(:user) { user_with_2fa } diff --git a/spec/features/remember_device/revocation_spec.rb b/spec/features/remember_device/revocation_spec.rb index df8b654fced..1c83a366484 100644 --- a/spec/features/remember_device/revocation_spec.rb +++ b/spec/features/remember_device/revocation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'taking an action that revokes remember device', allowed_extra_analytics: [:*] do +RSpec.feature 'taking an action that revokes remember device' do include NavigationHelper before do diff --git a/spec/features/remember_device/session_expiration_spec.rb b/spec/features/remember_device/session_expiration_spec.rb index 664823fec24..1fea732eb4d 100644 --- a/spec/features/remember_device/session_expiration_spec.rb +++ b/spec/features/remember_device/session_expiration_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' -RSpec.describe 'signing in with remember device and idling on the sign in page', - allowed_extra_analytics: [:*] do +RSpec.describe 'signing in with remember device and idling on the sign in page' do include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/reports/sp_active_users_report_spec.rb b/spec/features/reports/sp_active_users_report_spec.rb index 663db74a256..caae13a6856 100644 --- a/spec/features/reports/sp_active_users_report_spec.rb +++ b/spec/features/reports/sp_active_users_report_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sp active users report', allowed_extra_analytics: [:*] do +RSpec.feature 'sp active users report' do include SamlAuthHelper include OidcAuthHelper include IdvHelper diff --git a/spec/features/saml/multiple_endpoints_spec.rb b/spec/features/saml/multiple_endpoints_spec.rb index c85718f1a0c..fa66a4341a8 100644 --- a/spec/features/saml/multiple_endpoints_spec.rb +++ b/spec/features/saml/multiple_endpoints_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'multiple saml endpoints', allowed_extra_analytics: [:*] do +RSpec.describe 'multiple saml endpoints' do include SamlAuthHelper include IdvHelper diff --git a/spec/features/saml/saml_logout_spec.rb b/spec/features/saml/saml_logout_spec.rb index 9d92642d9b0..3e1400f1e90 100644 --- a/spec/features/saml/saml_logout_spec.rb +++ b/spec/features/saml/saml_logout_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML logout', allowed_extra_analytics: [:*] do +RSpec.feature 'SAML logout' do include SamlAuthHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/features/saml/saml_relay_state_spec.rb b/spec/features/saml/saml_relay_state_spec.rb index 0081a5b53e7..4c4293d78ca 100644 --- a/spec/features/saml/saml_relay_state_spec.rb +++ b/spec/features/saml/saml_relay_state_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML RelayState', allowed_extra_analytics: [:*] do +RSpec.feature 'SAML RelayState' do include SamlAuthHelper context 'when RelayState is passed in authn request' do diff --git a/spec/features/saml/saml_spec.rb b/spec/features/saml/saml_spec.rb index 9a38081eacd..73cb1f469d3 100644 --- a/spec/features/saml/saml_spec.rb +++ b/spec/features/saml/saml_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'saml api', allowed_extra_analytics: [:*] do +RSpec.feature 'saml api' do include SamlAuthHelper include IdvHelper diff --git a/spec/features/sign_in/banned_users_spec.rb b/spec/features/sign_in/banned_users_spec.rb index 3d745b607fb..aecb624ae3a 100644 --- a/spec/features/sign_in/banned_users_spec.rb +++ b/spec/features/sign_in/banned_users_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Banning users for an SP', allowed_extra_analytics: [:*] do +RSpec.feature 'Banning users for an SP' do include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/sign_in/remember_device_default_spec.rb b/spec/features/sign_in/remember_device_default_spec.rb index 933759d99ff..6679e98eca3 100644 --- a/spec/features/sign_in/remember_device_default_spec.rb +++ b/spec/features/sign_in/remember_device_default_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Remember device checkbox', allowed_extra_analytics: [:*] do +RSpec.describe 'Remember device checkbox' do include SamlAuthHelper context 'when the user signs in and arrives at the 2FA page' do diff --git a/spec/features/sign_in/sp_return_log_spec.rb b/spec/features/sign_in/sp_return_log_spec.rb index cdf0d48e8e3..93e7b185515 100644 --- a/spec/features/sign_in/sp_return_log_spec.rb +++ b/spec/features/sign_in/sp_return_log_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SP return logs', allowed_extra_analytics: [:*] do +RSpec.feature 'SP return logs' do include SamlAuthHelper it 'updates user id after user authenticates so we can track any user back to issuer', :email do diff --git a/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb b/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb index 640365d0f6f..5ee7d702930 100644 --- a/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb +++ b/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sign up with backup code', allowed_extra_analytics: [:*] do +RSpec.feature 'sign up with backup code' do include DocAuthHelper include SamlAuthHelper diff --git a/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb b/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb index 434261f55b8..b2d15ec3e93 100644 --- a/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb +++ b/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Second MFA Reminder', allowed_extra_analytics: [:*] do +RSpec.feature 'Second MFA Reminder' do include OidcAuthHelper let(:service_provider) { ServiceProvider.find_by(issuer: OidcAuthHelper::OIDC_IAL1_ISSUER) } diff --git a/spec/features/visitors/bad_password_spec.rb b/spec/features/visitors/bad_password_spec.rb index f63bb61898c..53fe0364040 100644 --- a/spec/features/visitors/bad_password_spec.rb +++ b/spec/features/visitors/bad_password_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' -RSpec.feature 'Visitor signs in with bad passwords and gets locked out', - allowed_extra_analytics: [:*] do +RSpec.feature 'Visitor signs in with bad passwords and gets locked out' do let(:user) { create(:user, :fully_registered) } let(:bad_password) { 'badpassword' } diff --git a/spec/requests/openid_connect_authorize_spec.rb b/spec/requests/openid_connect_authorize_spec.rb index e30adf4f7dd..051b1061602 100644 --- a/spec/requests/openid_connect_authorize_spec.rb +++ b/spec/requests/openid_connect_authorize_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' -RSpec.describe 'user signs in partially and visits openid_connect/authorize', - allowed_extra_analytics: [:*] do +RSpec.describe 'user signs in partially and visits openid_connect/authorize' do let(:user) { create(:user, :fully_registered, with: { phone: '+1 (202) 555-1213' }) } it 'prompts the user to 2FA' do From 284517ee6c37557dc252bd7a3b5ff0aa4616c49a Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 31 May 2024 13:34:43 -0400 Subject: [PATCH 3/4] Restore allowed_extra_analytics --- spec/controllers/account_reset/request_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 47a05718390..5077481222c 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe AccountReset::RequestController do +RSpec.describe AccountReset::RequestController, allowed_extra_analytics: [:*] do include ActionView::Helpers::DateHelper let(:user) { create(:user, :with_authentication_app) } describe '#show' do From c2b242c70eaa7d34a47b44ccae7ffb7f25878a4d Mon Sep 17 00:00:00 2001 From: Andrew Duthie <1779930+aduth@users.noreply.github.com> Date: Fri, 31 May 2024 14:20:56 -0400 Subject: [PATCH 4/4] Fix typos and readability Co-authored-by: Zach Margolis --- app/services/analytics_events.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 86e9ad17975..002d9db7de3 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -3640,7 +3640,7 @@ def logout_initiated( # @param [Hash] errors Authentication error reasons, if unsuccessful # @param [Hash] error_details Details for error that occurred in unsuccessful submission # @param ["authentication","reauthentication","confirmation"] context User session context - # @param [Boolean] new_device Whether the user is authenticating from a new d evice + # @param [Boolean] new_device Whether the user is authenticating from a new device # @param [String] multi_factor_auth_method Authentication method used # @param [DateTime] multi_factor_auth_method_created_at time auth method was created # @param [Integer] auth_app_configuration_id Database ID of authentication app configuration @@ -3650,7 +3650,7 @@ def logout_initiated( # @param [Integer] phone_configuration_id Database ID of phone configuration # @param [Boolean] confirmation_for_add_phone Whether authenticating while adding phone # @param [String] area_code Area code of phone number - # @param [String] country_code Country code associated with phonoe number + # @param [String] country_code Country code associated with phone number # @param [String] phone_fingerprint the hmac fingerprint of the phone number formatted as e164 # @param [String] frontend_error Name of error that occurred in frontend during submission # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow @@ -3775,7 +3775,7 @@ def multi_factor_auth_enter_backup_code_visit(context:, **extra) # @param [Boolean] confirmation_for_add_phone # @param [Integer] phone_configuration_id # @param [String] area_code Area code of phone number - # @param [String] country_code Abbreviated country code associated with phone number + # @param [String] country_code Abbreviated 2-letter country code associated with phone number # @param [String] phone_fingerprint Fingerprint hash of phone number # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow # @param [Integer] enabled_mfa_methods_count Number of MFAs associated with user @@ -4192,7 +4192,7 @@ def openid_connect_token(client_id:, user_id:, code_digest:, expires_in:, ial:, # @param [Hash] errors Errors resulting from form validation # @param ["authentication","reauthentication","confirmation"] context User session context # @param [String] otp_delivery_preference (sms or voice) - # @param [Boolean] resend Whether the user requested another code + # @param [Boolean] resend True if the user re-requested a code # @param [String] country_code Country code associated with phone number # @param [String] area_code Area code of phone number def otp_delivery_selection(