diff --git a/app/controllers/users/profiles_controller.rb b/app/controllers/users/profiles_controller.rb index 6b30b74..4f5ab31 100644 --- a/app/controllers/users/profiles_controller.rb +++ b/app/controllers/users/profiles_controller.rb @@ -18,6 +18,9 @@ class Users::ProfilesController < ApplicationController else redirect_to user_profile_url, alert: update_alert end + rescue ActiveRecord::RecordInvalid + # The password changed again before this browser's new session could start, and that change signed it out. + redirect_to new_session_url end private diff --git a/test/controllers/users/profiles_controller_test.rb b/test/controllers/users/profiles_controller_test.rb index 49fcb3d..035318d 100644 --- a/test/controllers/users/profiles_controller_test.rb +++ b/test/controllers/users/profiles_controller_test.rb @@ -43,6 +43,16 @@ class Users::ProfilesControllerTest < ActionDispatch::IntegrationTest assert_equal 1, users(:david).sessions.count end + test "changing the password signs this browser out when it changes again before its new session starts" do + User.stubs(:uncached).returns(BCrypt::Password.create("someone else's secret", cost: BCrypt::Engine::MIN_COST)) + + assert_changes -> { users(:david).sessions.count }, to: 0 do + put user_profile_url, params: { user: { password: "a new secret123456", password_challenge: "secret123456" } } + end + + assert_redirected_to new_session_url + end + test "changing the password gives this browser a new session, so a copy of its cookie stops working" do copied_cookie = cookies[:session_token]