From 79e7eb7cfbbd2ebc4d7307402941d467e185148b Mon Sep 17 00:00:00 2001 From: alceops Date: Fri, 1 May 2026 01:57:03 -0400 Subject: [PATCH 1/2] Avoid Turbo race after password reset --- app/views/devise/passwords/edit.html.erb | 2 +- spec/system/person_changes_password_test.rb | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index 37920a33e..aaedc55ab 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -55,7 +55,7 @@
- <%= f.submit "Set password", class: "btn btn-primary" %> + <%= f.submit "Set password", class: "btn btn-primary", data: { turbo: false } %>
<% end %> diff --git a/spec/system/person_changes_password_test.rb b/spec/system/person_changes_password_test.rb index b977326f4..a8b0aa1e0 100644 --- a/spec/system/person_changes_password_test.rb +++ b/spec/system/person_changes_password_test.rb @@ -43,7 +43,11 @@ fill_in 'New password', with: 'NewPassword123!' fill_in 'Confirm new password', with: 'NewPassword123!' - click_button 'Set password' + reset_submit = find_button("Set password") + expect(reset_submit["data-turbo"]).to eq("false") + expect(reset_submit.find(:xpath, "ancestor::form")["data-turbo"]).to be_nil + + click_button "Set password" expect(page).to have_content('Your password has been set successfully') expect(page).to have_current_path('/') From 85932559b7332337913aab3accfc3b7bf05449a4 Mon Sep 17 00:00:00 2001 From: alceops Date: Sat, 2 May 2026 23:09:58 -0400 Subject: [PATCH 2/2] Fix password-change Turbo redirect race --- app/views/devise/passwords/edit.html.erb | 2 +- app/views/users/change_password.html.erb | 22 +++++++++---------- spec/system/person_changes_password_test.rb | 6 +---- .../users/change_password.html.erb_spec.rb | 9 ++++++++ 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index aaedc55ab..37920a33e 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -55,7 +55,7 @@
- <%= f.submit "Set password", class: "btn btn-primary", data: { turbo: false } %> + <%= f.submit "Set password", class: "btn btn-primary" %>
<% end %> diff --git a/app/views/users/change_password.html.erb b/app/views/users/change_password.html.erb index 9e08ff70e..bda7ecda0 100644 --- a/app/views/users/change_password.html.erb +++ b/app/views/users/change_password.html.erb @@ -5,7 +5,7 @@ <%= simple_form_for :user, url: update_password_path, method: :post, - html: { class: "space-y-4" } do |f| %> + html: { class: "space-y-4", data: { turbo: false } } do |f| %>
@@ -26,16 +26,6 @@
-

- Don't remember your password? - <%= link_to "Log out and reset it.", - destroy_user_session_path(reset_password: true), - class: "action-link-text text-black-300 underline hover:text-blue-600", - data: { - turbo_method: :delete, - turbo_confirm: "This will log you out and send you to the password reset page. Continue?" - } %> -

@@ -84,5 +74,15 @@ <%= f.submit "Change Password", class: "btn btn-primary" %>
<% end %> +

+ Don't remember your password? + <%= link_to "Log out and reset it.", + destroy_user_session_path(reset_password: true), + class: "action-link-text text-black-300 underline hover:text-blue-600", + data: { + turbo_method: :delete, + turbo_confirm: "This will log you out and send you to the password reset page. Continue?" + } %> +

diff --git a/spec/system/person_changes_password_test.rb b/spec/system/person_changes_password_test.rb index a8b0aa1e0..b977326f4 100644 --- a/spec/system/person_changes_password_test.rb +++ b/spec/system/person_changes_password_test.rb @@ -43,11 +43,7 @@ fill_in 'New password', with: 'NewPassword123!' fill_in 'Confirm new password', with: 'NewPassword123!' - reset_submit = find_button("Set password") - expect(reset_submit["data-turbo"]).to eq("false") - expect(reset_submit.find(:xpath, "ancestor::form")["data-turbo"]).to be_nil - - click_button "Set password" + click_button 'Set password' expect(page).to have_content('Your password has been set successfully') expect(page).to have_current_path('/') diff --git a/spec/views/users/change_password.html.erb_spec.rb b/spec/views/users/change_password.html.erb_spec.rb index cceaacd7b..31cddfff9 100644 --- a/spec/views/users/change_password.html.erb_spec.rb +++ b/spec/views/users/change_password.html.erb_spec.rb @@ -29,6 +29,15 @@ expect(rendered).to have_field("New password confirmation", type: :password) end + it "submits the password update outside Turbo to avoid the auth-cookie redirect race" do + expect(rendered).to have_css('form[data-turbo="false"]') + end + + it "keeps the logout-and-reset link outside the non-Turbo password form" do + expect(rendered).to have_link("Log out and reset it.", href: destroy_user_session_path(reset_password: true)) + expect(rendered).not_to have_css('form a', text: "Log out and reset it.") + end + it "has a submit button" do expect(rendered).to have_button("Change Password") end