diff --git a/lib/sorcery/controller/submodules/session_timeout.rb b/lib/sorcery/controller/submodules/session_timeout.rb index f02b221f..7c64b853 100644 --- a/lib/sorcery/controller/submodules/session_timeout.rb +++ b/lib/sorcery/controller/submodules/session_timeout.rb @@ -52,6 +52,7 @@ def register_login_time(_user, _credentials = nil) def validate_session session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time] if (session_to_use && sorcery_session_expired?(session_to_use.to_time)) || sorcery_session_invalidated? + forget_me! if current_user.present? && Config.submodules.include?(:remember_me) reset_sorcery_session remove_instance_variable :@current_user if defined? @current_user else diff --git a/spec/controllers/controller_session_timeout_spec.rb b/spec/controllers/controller_session_timeout_spec.rb index 43e565e2..641b2041 100644 --- a/spec/controllers/controller_session_timeout_spec.rb +++ b/spec/controllers/controller_session_timeout_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe SorceryController, type: :controller do - let!(:user) { double('user', id: 42) } + let!(:user) { double('user', id: 42, password: 'secret') } # ----------------- SESSION TIMEOUT ----------------------- context 'with session timeout features' do @@ -36,6 +36,61 @@ expect(response).to be_a_redirect end + context 'with remember_me module' do + before(:example) do + if SORCERY_ORM == :active_record + MigrationHelper.migrate("#{Rails.root}/db/migrate/remember_me") + User.reset_column_information + end + + sorcery_reload!([:remember_me, :session_timeout]) + + allow(user).to receive(:remember_me_token) + allow(user).to receive(:forget_me!) + allow(user).to receive(:remember_me_token_expires_at) + allow(user).to receive_message_chain(:sorcery_config, :remember_me_token_attribute_name).and_return(:remember_me_token) + allow(user).to receive_message_chain(:sorcery_config, :remember_me_token_expires_at_attribute_name).and_return(:remember_me_token_expires_at) + end + + after(:example) do + if SORCERY_ORM == :active_record + MigrationHelper.rollback("#{Rails.root}/db/migrate/remember_me") + end + + sorcery_reload!([:session_timeout]) + end + + it 'resets session and remember_me cookies after session timeout' do + expect(User).to receive(:authenticate).with('bla@bla.com', 'secret', '1') { |&block| block.call(user, nil) } + expect(user).to receive(:remember_me!) + expect(user).to receive(:remember_me_token).and_return('abracadabra') + + post :test_login_with_remember_in_login, params: { email: 'bla@bla.com', password: 'secret', remember: '1' } + + Timecop.travel(Time.now.in_time_zone + 0.6) + + get :test_login_from_cookie + + expect(cookies['remember_me_token']).to be_nil + expect(session[:user_id]).to be_nil + end + + it 'does not resets session and remember_me cookies after session timeout' do + expect(User).to receive(:authenticate).with('bla@bla.com', 'secret', '1') { |&block| block.call(user, nil) } + expect(user).to receive(:remember_me!) + expect(user).to receive(:remember_me_token).and_return('abracadabra') + + post :test_login_with_remember_in_login, params: { email: 'bla@bla.com', password: 'secret', remember: '1' } + + Timecop.travel(Time.now.in_time_zone + 0.4) + + get :test_login_from_cookie + + expect(cookies['remember_me_token']).to be_present + expect(session[:user_id]).to be_present + end + end + context "with 'invalidate_active_sessions_enabled'" do it 'does not reset the session if invalidate_sessions_before is nil' do sorcery_controller_property_set(:session_timeout_invalidate_active_sessions_enabled, true)