From 67ffa13f606570ff83cdb3abbbb4ba6e71609368 Mon Sep 17 00:00:00 2001 From: Malick DiarrA Date: Tue, 7 Jan 2025 09:40:07 -0500 Subject: [PATCH 1/5] changelog: Upcoming Features, Authentication, allow all_emails and email to return last sign in email --- .../connected_accounts/selected_email_controller.rb | 12 ++++++++++-- app/controllers/sign_up/select_email_controller.rb | 10 +++++++++- app/models/service_provider_identity.rb | 4 ++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/controllers/accounts/connected_accounts/selected_email_controller.rb b/app/controllers/accounts/connected_accounts/selected_email_controller.rb index 1ae8b77a6fe..68118063f8d 100644 --- a/app/controllers/accounts/connected_accounts/selected_email_controller.rb +++ b/app/controllers/accounts/connected_accounts/selected_email_controller.rb @@ -20,7 +20,7 @@ def edit def update @select_email_form = build_select_email_form - result = @select_email_form.submit(form_params) + result = @select_email_form.submit(selected_email_id: selected_email_id) analytics.sp_select_email_submitted(**result) @@ -52,7 +52,15 @@ def identity @identity = current_user.identities.find_by(id: params[:identity_id]) end - def last_email + def selected_email_id + if current_sp.present? && current_sp.metadata[:all_emails] && current_sp.metadata[:emails] + last_email_id + else + form_params[:selected_email_id] + end + end + + def last_email_id current_user.last_sign_in_email_address.id end end diff --git a/app/controllers/sign_up/select_email_controller.rb b/app/controllers/sign_up/select_email_controller.rb index 2abfff30c60..0b23b19cbf9 100644 --- a/app/controllers/sign_up/select_email_controller.rb +++ b/app/controllers/sign_up/select_email_controller.rb @@ -25,7 +25,7 @@ def create analytics.sp_select_email_submitted(**result, needs_completion_screen_reason:) if result.success? - user_session[:selected_email_id_for_linked_identity] = form_params[:selected_email_id] + user_session[:selected_email_id_for_linked_identity] = selected_email_id redirect_to sign_up_completed_path else flash[:error] = result.first_error_message @@ -55,6 +55,14 @@ def last_email end end + def selected_email_id + if current_sp.present? && current_sp.metadata[:all_emails] && current_sp.metadata[:emails] + current_user.last_sign_in_email_address.email.id + else + form_params[:selected_email_id] + end + end + def verify_needs_completions_screen redirect_to account_url unless needs_completion_screen_reason end diff --git a/app/models/service_provider_identity.rb b/app/models/service_provider_identity.rb index 5ad3eaf6ede..b023fd286bc 100644 --- a/app/models/service_provider_identity.rb +++ b/app/models/service_provider_identity.rb @@ -57,6 +57,10 @@ def friendly_name sp_metadata[:friendly_name] end + def all_email_and_single_email_requested? + current_sp.metadata[:all_emails] && current_sp.metadata[:emails] + end + def service_provider_id service_provider_record&.id end From 1cf573d88af9a18301d6c9c29ef9dd84e11e8557 Mon Sep 17 00:00:00 2001 From: Malick DiarrA Date: Tue, 7 Jan 2025 21:23:04 -0500 Subject: [PATCH 2/5] add spec for identity check --- .../sign_up/select_email_controller.rb | 6 ++-- app/models/service_provider_identity.rb | 3 +- .../selected_email_controller_spec.rb | 34 ++++++++++++++++-- .../sign_up/select_email_controller_spec.rb | 35 +++++++++++++++---- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/app/controllers/sign_up/select_email_controller.rb b/app/controllers/sign_up/select_email_controller.rb index 0b23b19cbf9..faa60281ca1 100644 --- a/app/controllers/sign_up/select_email_controller.rb +++ b/app/controllers/sign_up/select_email_controller.rb @@ -56,8 +56,10 @@ def last_email end def selected_email_id - if current_sp.present? && current_sp.metadata[:all_emails] && current_sp.metadata[:emails] - current_user.last_sign_in_email_address.email.id + if current_sp.present? && + current_sp.metadata[:attribute_bundle].include?('all_email') && + current_sp.metadata[:attribute_bundle].include?('email') + current_user.last_sign_in_email_address.id else form_params[:selected_email_id] end diff --git a/app/models/service_provider_identity.rb b/app/models/service_provider_identity.rb index b023fd286bc..f43a0cdead9 100644 --- a/app/models/service_provider_identity.rb +++ b/app/models/service_provider_identity.rb @@ -58,7 +58,8 @@ def friendly_name end def all_email_and_single_email_requested? - current_sp.metadata[:all_emails] && current_sp.metadata[:emails] + sp_metadata[:attribute_bundle].include?('all_email') && + sp_metadata[:attribute_bundle].include?('email') end def service_provider_id diff --git a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb index 53826485151..d1f30d256ca 100644 --- a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb +++ b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb @@ -89,8 +89,8 @@ describe '#update' do let(:identity_id) { user.identities.take.id } - let(:selected_email) { user.confirmed_email_addresses.sample } - let(:params) { { identity_id:, select_email_form: { selected_email_id: selected_email.id } } } + let(:selected_email_id) { user.confirmed_email_addresses.sample } + let(:params) { { identity_id:, select_email_form: { selected_email_id: selected_email_id } } } subject(:response) { patch :update, params: } it 'redirects to connected accounts path with the appropriate flash message' do @@ -106,10 +106,38 @@ expect(@analytics).to have_logged_event( :sp_select_email_submitted, success: true, - selected_email_id: selected_email.id, + selected_email_id: selected_email_id, ) end + context ' with all_email and emails requested' do + let(:service_provider_attribute_bundle) { %w[email all_email] } + + let(:sp) do + create( + :service_provider, + attribute_bundle: service_provider_attribute_bundle, + ) + end + let(:identity) do + create(:service_provider_identity, :active, service_provider: sp.issuer, user: user) + end + + let(:last_sign_in_email_id) { user.last_sign_in_email_address.id } + let(:available_email_ids) { user.confirmed_email_addresses.map(&:id) } + let(:selected_email_id) do + (available_email_ids - [last_sign_in_email_id]).sample + end + + it 'returns last sign in email' do + response + + expect( + controller.user_session[:selected_email_id_for_linked_identity], + ).to eq(last_sign_in_email_id) + end + end + context 'with invalid submission' do let(:params) { super().merge(select_email_form: { selected_email_id: '' }) } diff --git a/spec/controllers/sign_up/select_email_controller_spec.rb b/spec/controllers/sign_up/select_email_controller_spec.rb index 7eefddb0368..729d3b7747a 100644 --- a/spec/controllers/sign_up/select_email_controller_spec.rb +++ b/spec/controllers/sign_up/select_email_controller_spec.rb @@ -2,7 +2,13 @@ RSpec.describe SignUp::SelectEmailController do let(:user) { create(:user, :with_multiple_emails) } - let(:sp) { create(:service_provider) } + let(:service_provider_attribute_bundle) { %w[email] } + let(:sp) do + create( + :service_provider, + attribute_bundle: service_provider_attribute_bundle, + ) + end before do stub_sign_in(user) @@ -75,8 +81,8 @@ end describe '#create' do - let(:selected_email) { user.confirmed_email_addresses.sample } - let(:params) { { select_email_form: { selected_email_id: selected_email.id } } } + let(:selected_email_id) { user.confirmed_email_addresses.sample.id } + let(:params) { { select_email_form: { selected_email_id: selected_email_id } } } subject(:response) { post :create, params: params } @@ -85,7 +91,7 @@ expect( controller.user_session[:selected_email_id_for_linked_identity], - ).to eq(selected_email.id.to_s) + ).to eq(selected_email_id.to_s) end it 'logs analytics event' do @@ -97,10 +103,27 @@ :sp_select_email_submitted, success: true, needs_completion_screen_reason: :new_attributes, - selected_email_id: selected_email.id, + selected_email_id: selected_email_id, ) end + context ' with all_email and emails requested' do + let(:service_provider_attribute_bundle) { %w[email all_email] } + let(:last_sign_in_email_id) { user.last_sign_in_email_address.id } + let(:available_email_ids) { user.confirmed_email_addresses.map(&:id) } + let(:selected_email_id) do + (available_email_ids - [last_sign_in_email_id]).sample + end + + it 'returns last sign in email' do + response + + expect( + controller.user_session[:selected_email_id_for_linked_identity], + ).to eq(last_sign_in_email_id) + end + end + context 'with a corrupted email selected_email_id form' do let(:other_user) { create(:user) } let(:selected_email) { other_user.confirmed_email_addresses.sample } @@ -122,7 +145,7 @@ success: false, error_details: { selected_email_id: { not_found: true } }, needs_completion_screen_reason: :new_attributes, - selected_email_id: selected_email.id, + selected_email_id: selected_email_id, ) end end From b5c52d21fafda9cae80fadc81bd8644643cd8cca Mon Sep 17 00:00:00 2001 From: Malick DiarrA Date: Wed, 8 Jan 2025 09:34:53 -0500 Subject: [PATCH 3/5] update selected_email controller and spec --- .../accounts/connected_accounts/selected_email_controller.rb | 2 +- .../connected_accounts/selected_email_controller_spec.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/accounts/connected_accounts/selected_email_controller.rb b/app/controllers/accounts/connected_accounts/selected_email_controller.rb index 68118063f8d..0c9b61747c2 100644 --- a/app/controllers/accounts/connected_accounts/selected_email_controller.rb +++ b/app/controllers/accounts/connected_accounts/selected_email_controller.rb @@ -14,7 +14,7 @@ def edit @select_email_form = build_select_email_form @can_add_email = EmailPolicy.new(current_user).can_add_email? analytics.sp_select_email_visited - @email_id = @identity.email_address_id || last_email + @email_id = @identity.email_address_id || last_email_id end def update diff --git a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb index d1f30d256ca..265c08efcf2 100644 --- a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb +++ b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb @@ -135,6 +135,8 @@ expect( controller.user_session[:selected_email_id_for_linked_identity], ).to eq(last_sign_in_email_id) + identity.reload + expect(identity.email_address_id).to eq(last_sign_in_email_id) end end From 3348e2a6df79a4c42a38c5b3c9a5338fa53adb46 Mon Sep 17 00:00:00 2001 From: Malick DiarrA Date: Wed, 8 Jan 2025 11:10:19 -0500 Subject: [PATCH 4/5] fix selected email working for all email and emails --- .../connected_accounts/selected_email_controller.rb | 2 +- app/controllers/sign_up/select_email_controller.rb | 4 ++-- app/models/service_provider_identity.rb | 4 ++-- .../selected_email_controller_spec.rb | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/controllers/accounts/connected_accounts/selected_email_controller.rb b/app/controllers/accounts/connected_accounts/selected_email_controller.rb index 0c9b61747c2..40d240e7299 100644 --- a/app/controllers/accounts/connected_accounts/selected_email_controller.rb +++ b/app/controllers/accounts/connected_accounts/selected_email_controller.rb @@ -53,7 +53,7 @@ def identity end def selected_email_id - if current_sp.present? && current_sp.metadata[:all_emails] && current_sp.metadata[:emails] + if identity.all_email_and_single_email_requested? last_email_id else form_params[:selected_email_id] diff --git a/app/controllers/sign_up/select_email_controller.rb b/app/controllers/sign_up/select_email_controller.rb index faa60281ca1..0cd97c71966 100644 --- a/app/controllers/sign_up/select_email_controller.rb +++ b/app/controllers/sign_up/select_email_controller.rb @@ -57,8 +57,8 @@ def last_email def selected_email_id if current_sp.present? && - current_sp.metadata[:attribute_bundle].include?('all_email') && - current_sp.metadata[:attribute_bundle].include?('email') + current_sp.attribute_bundle&.include?('all_email') && + current_sp.attribute_bundle.include?('email') current_user.last_sign_in_email_address.id else form_params[:selected_email_id] diff --git a/app/models/service_provider_identity.rb b/app/models/service_provider_identity.rb index f43a0cdead9..b7047ddb0f0 100644 --- a/app/models/service_provider_identity.rb +++ b/app/models/service_provider_identity.rb @@ -58,8 +58,8 @@ def friendly_name end def all_email_and_single_email_requested? - sp_metadata[:attribute_bundle].include?('all_email') && - sp_metadata[:attribute_bundle].include?('email') + service_provider_record&.attribute_bundle&.include?('all_email') && + service_provider_record&.attribute_bundle.include?('email') end def service_provider_id diff --git a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb index 265c08efcf2..45afba3531f 100644 --- a/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb +++ b/spec/controllers/accounts/connected_accounts/selected_email_controller_spec.rb @@ -89,7 +89,7 @@ describe '#update' do let(:identity_id) { user.identities.take.id } - let(:selected_email_id) { user.confirmed_email_addresses.sample } + let(:selected_email_id) { user.confirmed_email_addresses.sample.id } let(:params) { { identity_id:, select_email_form: { selected_email_id: selected_email_id } } } subject(:response) { patch :update, params: } @@ -120,7 +120,7 @@ ) end let(:identity) do - create(:service_provider_identity, :active, service_provider: sp.issuer, user: user) + create(:service_provider_identity, :active, service_provider: sp.issuer) end let(:last_sign_in_email_id) { user.last_sign_in_email_address.id } @@ -129,12 +129,13 @@ (available_email_ids - [last_sign_in_email_id]).sample end + before do + identity.update!(user_id: user.id) + end + it 'returns last sign in email' do response - expect( - controller.user_session[:selected_email_id_for_linked_identity], - ).to eq(last_sign_in_email_id) identity.reload expect(identity.email_address_id).to eq(last_sign_in_email_id) end @@ -163,7 +164,7 @@ context 'signed out' do let(:other_user) { create(:user, identities: [create(:service_provider_identity, :active)]) } - let(:selected_email) { other_user.confirmed_email_addresses.sample } + let(:selected_email_id) { other_user.confirmed_email_addresses.sample.id } let(:identity_id) { other_user.identities.take.id } let(:user) { nil } From 321b9c334de1f3636dcd9939cea3a5d80b149172 Mon Sep 17 00:00:00 2001 From: Malick DiarrA Date: Wed, 8 Jan 2025 11:58:59 -0500 Subject: [PATCH 5/5] fix select email controller --- spec/controllers/sign_up/select_email_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/sign_up/select_email_controller_spec.rb b/spec/controllers/sign_up/select_email_controller_spec.rb index 729d3b7747a..7a8e3b37ea6 100644 --- a/spec/controllers/sign_up/select_email_controller_spec.rb +++ b/spec/controllers/sign_up/select_email_controller_spec.rb @@ -126,7 +126,7 @@ context 'with a corrupted email selected_email_id form' do let(:other_user) { create(:user) } - let(:selected_email) { other_user.confirmed_email_addresses.sample } + let(:selected_email_id) { other_user.confirmed_email_addresses.sample.id } it 'rejects email not belonging to the user' do expect(response).to redirect_to(sign_up_select_email_path)