diff --git a/app/controllers/devise/passwords_controller.rb b/app/controllers/devise/passwords_controller.rb index ab99fc8..370645e 100644 --- a/app/controllers/devise/passwords_controller.rb +++ b/app/controllers/devise/passwords_controller.rb @@ -55,7 +55,12 @@ class Devise::PasswordsController < DeviseController protected def after_resetting_password_path_for(resource) - Devise.sign_in_after_reset_password ? after_sign_in_path_for(resource) : new_session_path(resource_name) + session.delete(:user_return_to) + if Devise.sign_in_after_reset_password + root_path + else + new_session_path(resource_name) + end end # The path used after sending reset password instructions diff --git a/spec/features/devise/password_reset.rb b/spec/features/devise/password_reset.rb index c12396c..874f39a 100644 --- a/spec/features/devise/password_reset.rb +++ b/spec/features/devise/password_reset.rb @@ -50,5 +50,26 @@ RSpec.describe 'Password reset', type: :feature do expect(page).to have_content 'Your password has been changed successfully' expect(user.reload.reset_password_token).to be_nil end + + scenario "Ignores a stale return location left by an rs/oauth request" do + expect(Devise::LDAP::Adapter).to receive(:update_password) + .with(user.cn, 'catch me if you can').and_return(true) + + # Simulate an earlier rs/oauth authorization request that stored a + # return URL in the session (the original cause of issue #235). + visit new_rs_oauth_path(user.cn, + redirect_uri: "https://example.com", + client_id: "https://example.com", + scope: "documents") + + visit edit_user_password_path(reset_password_token: token) + fill_in :user_password, with: 'catch me if you can' + fill_in :user_password_confirmation, with: 'catch me if you can' + click_button 'Change my password' + + expect(page).to have_content 'Your password has been changed successfully' + expect(page).to have_current_path(root_path) + expect(page).not_to have_content 'Bad request' + end end end diff --git a/spec/requests/devise/passwords_spec.rb b/spec/requests/devise/passwords_spec.rb new file mode 100644 index 0000000..bdfae93 --- /dev/null +++ b/spec/requests/devise/passwords_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +RSpec.describe "Devise password reset", type: :request do + let(:user) { create :user } + + describe "PUT /users/password" do + let(:token) { user.send(:set_reset_password_token) } + + before do + allow(Devise::LDAP::Adapter).to receive(:update_password).and_return(true) + end + + context "with a stale stored return location from an rs/oauth request" do + before do + get new_rs_oauth_url(user.cn, + redirect_uri: "https://example.com", + client_id: "https://example.com", + scope: "documents") + expect(session[:user_return_to]).to be_present + end + + it "redirects to the dashboard instead of the stored return URL" do + put user_password_path, params: { + user: { + reset_password_token: token, + password: "a brand new password", + password_confirmation: "a brand new password" + } + } + + expect(response).to redirect_to(root_path) + expect(session[:user_return_to]).to be_nil + end + end + end +end