mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 07:38:07 -05:00
Do not timeout if remember me is enabled
This commit is contained in:
@@ -9,6 +9,13 @@ module Devise
|
||||
Rails.configuration.session_options.slice(:path, :domain, :secure)
|
||||
end
|
||||
|
||||
def remember_me_is_active?(resource)
|
||||
return false unless resource.respond_to?(:remember_me)
|
||||
scope = Devise::Mapping.find_scope!(resource)
|
||||
cookie = cookies.signed[remember_key(resource, scope)]
|
||||
resource.class.serialized_in_cookie?(resource, *cookie)
|
||||
end
|
||||
|
||||
# Remembers the given resource by setting up a cookie
|
||||
def remember_me(resource)
|
||||
return if env["devise.skip_storage"]
|
||||
|
||||
@@ -19,9 +19,10 @@ Warden::Manager.after_set_user do |record, warden, options|
|
||||
|
||||
proxy = Devise::Hooks::Proxy.new(warden)
|
||||
|
||||
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
|
||||
if record.timedout?(last_request_at) &&
|
||||
!env['devise.skip_timeout'] &&
|
||||
!proxy.remember_me_is_active?(record)
|
||||
Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
|
||||
|
||||
throw :warden, scope: scope, message: :timeout
|
||||
end
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ module Devise
|
||||
def after_remembered
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
module ClassMethods
|
||||
# Create the cookie key using the record id and remember_token
|
||||
@@ -111,6 +110,25 @@ module Devise
|
||||
|
||||
# Recreate the user based on the stored cookie
|
||||
def serialize_from_cookie(*args)
|
||||
serialize_from_cookie_with_or_without_record(nil, args)
|
||||
end
|
||||
|
||||
# Check if the given record is the one serialized in cookie
|
||||
def serialized_in_cookie?(record, *args)
|
||||
!!serialize_from_cookie_with_or_without_record(record, args)
|
||||
end
|
||||
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def remember_token #:nodoc:
|
||||
loop do
|
||||
token = Devise.friendly_token
|
||||
break token unless to_adapter.find_first({ remember_token: token })
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def serialize_from_cookie_with_or_without_record(record, args)
|
||||
id, token, generated_at = args
|
||||
|
||||
# The token is only valid if:
|
||||
@@ -122,20 +140,13 @@ module Devise
|
||||
# 6. the token matches
|
||||
if generated_at &&
|
||||
(self.remember_for.ago < generated_at) &&
|
||||
(record = to_adapter.get(id)) &&
|
||||
(record ||= to_adapter.get(id)) && (id == record.to_key) &&
|
||||
(generated_at > (record.remember_created_at || Time.now).utc) &&
|
||||
Devise.secure_compare(record.rememberable_value, token)
|
||||
record
|
||||
end
|
||||
end
|
||||
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def remember_token #:nodoc:
|
||||
loop do
|
||||
token = Devise.friendly_token
|
||||
break token unless to_adapter.find_first({ remember_token: token })
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: extend_remember_period is no longer used
|
||||
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options, :expire_all_remember_me_on_sign_out)
|
||||
|
||||
@@ -165,7 +165,17 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'does not crashes when the last_request_at is a String' do
|
||||
test 'time out not triggered if remembered' do
|
||||
user = sign_in_as_user remember_me: true
|
||||
get expire_user_path(user)
|
||||
assert_not_nil last_request_at
|
||||
|
||||
get users_path
|
||||
assert_response :success
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'does not crash when the last_request_at is a String' do
|
||||
user = sign_in_as_user
|
||||
|
||||
get edit_form_user_path(user, last_request_at: Time.now.utc.to_s)
|
||||
|
||||
Reference in New Issue
Block a user