From 8824b767f3ae4a56a058198ab25907a5f2ec0a01 Mon Sep 17 00:00:00 2001 From: Trevor Turk Date: Tue, 29 Jun 2010 20:54:19 -0500 Subject: [PATCH] remember_across_browsers option for rememberable module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- lib/devise.rb | 4 +++ lib/devise/models/rememberable.rb | 10 ++++-- .../devise/install/templates/devise.rb | 3 ++ test/models/rememberable_test.rb | 33 +++++++++++++++++++ test/rails_app/config/initializers/devise.rb | 3 ++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/devise.rb b/lib/devise.rb index d7253546..d939642d 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -89,6 +89,10 @@ module Devise mattr_accessor :remember_for @@remember_for = 2.weeks + # If a valid remember token can be re-used between multiple browsers. + mattr_accessor :remember_across_browsers + @@remember_across_browsers = true + # Time interval you can access your account before confirming your account. mattr_accessor :confirm_within @@confirm_within = 0.days diff --git a/lib/devise/models/rememberable.rb b/lib/devise/models/rememberable.rb index f4ccb992..c2ecceeb 100644 --- a/lib/devise/models/rememberable.rb +++ b/lib/devise/models/rememberable.rb @@ -20,6 +20,10 @@ module Devise # time for the cookie created to remember the user. # By default remember_for is 2.weeks. # + # remember_across_browsers: if a valid remember token can be re-used + # between multiple browsers. + # By default remember_across_browsers is true. + # # Examples: # # User.find(1).remember_me! # regenerating the token @@ -38,8 +42,10 @@ module Devise attr_accessor :remember_me end - # Generate a new remember token and save the record without validations. + # Generate a new remember token and save the record without validations + # unless remember_across_browsers is true and the user already has a valid token. def remember_me! + return if self.class.remember_across_browsers && self.remember_created_at && !self.remember_expired? self.remember_token = Devise.friendly_token self.remember_created_at = Time.now.utc save(:validate => false) @@ -86,7 +92,7 @@ module Devise record if record && !record.remember_expired? end - Devise::Models.config(self, :remember_for, :cookie_domain) + Devise::Models.config(self, :remember_for, :remember_across_browsers, :cookie_domain) end end end diff --git a/lib/generators/devise/install/templates/devise.rb b/lib/generators/devise/install/templates/devise.rb index f13c51a0..6031ba7c 100644 --- a/lib/generators/devise/install/templates/devise.rb +++ b/lib/generators/devise/install/templates/devise.rb @@ -57,6 +57,9 @@ Devise.setup do |config| # The time the user will be remembered without asking for credentials again. # config.remember_for = 2.weeks + # If a valid remember token can be re-used between multiple browsers. + # config.remember_across_browsers = true + # ==> Configuration for :validatable # Range for password length # config.password_length = 6..20 diff --git a/test/models/rememberable_test.rb b/test/models/rememberable_test.rb index de19c7da..f803c33b 100644 --- a/test/models/rememberable_test.rb +++ b/test/models/rememberable_test.rb @@ -107,4 +107,37 @@ class RememberableTest < ActiveSupport::TestCase assert_not user.remember_expired? end end + + test 'if remember_across_browsers is true, remember_me! should create a new token if no token exists' do + swap Devise, :remember_across_browsers => true do + user = create_user + assert_equal nil, user.remember_token + user.remember_me! + assert_not_equal nil, user.remember_token + end + end + + test 'if remember_across_browsers is true, remember_me! should create a new token if a token exists but has expired' do + swap Devise, :remember_across_browsers => true, :remember_for => 1.day do + user = create_user + user.remember_me! + user.remember_created_at = 2.days.ago + user.save + token = user.remember_token + user.remember_me! + assert_not_equal token, user.remember_token + end + end + + test 'if remember_across_browsers is true, remember_me! should not create a new token if a token exists and has not expired' do + swap Devise, :remember_across_browsers => true, :remember_for => 2.days do + user = create_user + user.remember_me! + user.remember_created_at = 1.day.ago + user.save + token = user.remember_token + user.remember_me! + assert_equal token, user.remember_token + end + end end diff --git a/test/rails_app/config/initializers/devise.rb b/test/rails_app/config/initializers/devise.rb index 4c4f4bc9..15e2bdf8 100644 --- a/test/rails_app/config/initializers/devise.rb +++ b/test/rails_app/config/initializers/devise.rb @@ -29,6 +29,9 @@ Devise.setup do |config| # The time the user will be remembered without asking for credentials again. # config.remember_for = 2.weeks + # If a valid remember token can be re-used between multiple browsers. + # config.remember_across_browsers = true + # The time you want to timeout the user session without activity. After this # time the user will be asked for credentials again. # config.timeout_in = 10.minutes