devise 3.0.4 → 3.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of devise might be problematic. Click here for more details.
- data/{CHANGELOG.rdoc → CHANGELOG.md} +41 -30
- data/Gemfile.lock +14 -13
- data/README.md +12 -11
- data/app/controllers/devise/confirmations_controller.rb +6 -2
- data/app/controllers/devise/registrations_controller.rb +2 -2
- data/app/controllers/devise/sessions_controller.rb +1 -1
- data/app/mailers/devise/mailer.rb +6 -3
- data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
- data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
- data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
- data/app/views/devise/shared/_links.erb +2 -2
- data/config/locales/en.yml +2 -2
- data/devise.gemspec +1 -0
- data/gemfiles/Gemfile.rails-3.2.x.lock +45 -42
- data/lib/devise.rb +20 -13
- data/lib/devise/controllers/helpers.rb +1 -0
- data/lib/devise/hooks/rememberable.rb +2 -1
- data/lib/devise/mailers/helpers.rb +0 -6
- data/lib/devise/models.rb +8 -12
- data/lib/devise/models/authenticatable.rb +8 -16
- data/lib/devise/models/confirmable.rb +27 -37
- data/lib/devise/models/lockable.rb +15 -17
- data/lib/devise/models/recoverable.rb +21 -27
- data/lib/devise/models/token_authenticatable.rb +4 -1
- data/lib/devise/parameter_sanitizer.rb +49 -19
- data/lib/devise/rails.rb +7 -11
- data/lib/devise/rails/routes.rb +12 -9
- data/lib/devise/rails/warden_compat.rb +1 -0
- data/lib/devise/strategies/authenticatable.rb +0 -12
- data/lib/devise/strategies/database_authenticatable.rb +3 -6
- data/lib/devise/token_generator.rb +70 -0
- data/lib/devise/version.rb +1 -1
- data/lib/generators/templates/devise.rb +14 -8
- data/test/controllers/passwords_controller_test.rb +3 -4
- data/test/failure_app_test.rb +1 -1
- data/test/integration/confirmable_test.rb +16 -41
- data/test/integration/lockable_test.rb +11 -14
- data/test/integration/recoverable_test.rb +23 -15
- data/test/mailers/confirmation_instructions_test.rb +6 -2
- data/test/mailers/reset_password_instructions_test.rb +6 -2
- data/test/mailers/unlock_instructions_test.rb +6 -2
- data/test/models/confirmable_test.rb +20 -30
- data/test/models/lockable_test.rb +15 -5
- data/test/models/recoverable_test.rb +20 -48
- data/test/models_test.rb +0 -19
- data/test/parameter_sanitizer_test.rb +23 -9
- data/test/rails_app/config/initializers/devise.rb +3 -0
- data/test/rails_app/lib/shared_admin.rb +3 -0
- data/test/rails_app/lib/shared_user.rb +4 -0
- data/test/support/helpers.rb +0 -21
- metadata +23 -7
- data/app/views/devise/_links.erb +0 -3
data/lib/devise.rb
CHANGED
@@ -14,6 +14,7 @@ module Devise
|
|
14
14
|
autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
|
15
15
|
autoload :TestHelpers, 'devise/test_helpers'
|
16
16
|
autoload :TimeInflector, 'devise/time_inflector'
|
17
|
+
autoload :TokenGenerator, 'devise/token_generator'
|
17
18
|
|
18
19
|
module Controllers
|
19
20
|
autoload :Helpers, 'devise/controllers/helpers'
|
@@ -45,6 +46,20 @@ module Devise
|
|
45
46
|
# True values used to check params
|
46
47
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
47
48
|
|
49
|
+
# Secret key used by the key generator
|
50
|
+
mattr_accessor :secret_key
|
51
|
+
@@secret_key = nil
|
52
|
+
|
53
|
+
# Allow insecure token lookup. Must be used
|
54
|
+
# temporarily just for migration.
|
55
|
+
mattr_accessor :allow_insecure_token_lookup
|
56
|
+
@@allow_insecure_tokens_lookup = false
|
57
|
+
|
58
|
+
# Allow insecure sign in after confirmation. Must be used
|
59
|
+
# temporarily just for migration.
|
60
|
+
mattr_accessor :allow_insecure_sign_in_after_confirmation
|
61
|
+
@@allow_insecure_sign_in_after_confirmation = false
|
62
|
+
|
48
63
|
# Custom domain or key for cookies. Not set by default
|
49
64
|
mattr_accessor :rememberable_options
|
50
65
|
@@rememberable_options = {}
|
@@ -227,18 +242,6 @@ module Devise
|
|
227
242
|
mattr_accessor :clean_up_csrf_token_on_authentication
|
228
243
|
@@clean_up_csrf_token_on_authentication = true
|
229
244
|
|
230
|
-
def self.encryptor=(value)
|
231
|
-
warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
|
232
|
-
end
|
233
|
-
|
234
|
-
def self.use_salt_as_remember_token=(value)
|
235
|
-
warn "\n[DEVISE] Devise.use_salt_as_remember_token is deprecated and has no effect. Please remove it.\n"
|
236
|
-
end
|
237
|
-
|
238
|
-
def self.apply_schema=(value)
|
239
|
-
warn "\n[DEVISE] Devise.apply_schema is deprecated and has no effect. Please remove it.\n"
|
240
|
-
end
|
241
|
-
|
242
245
|
# PRIVATE CONFIGURATION
|
243
246
|
|
244
247
|
# Store scopes mappings.
|
@@ -263,6 +266,10 @@ module Devise
|
|
263
266
|
mattr_accessor :paranoid
|
264
267
|
@@paranoid = false
|
265
268
|
|
269
|
+
# Stores the token generator
|
270
|
+
mattr_accessor :token_generator
|
271
|
+
@@token_generator = nil
|
272
|
+
|
266
273
|
# Default way to setup Devise. Run rails generate devise_install to create
|
267
274
|
# a fresh initializer with all configuration values.
|
268
275
|
def self.setup
|
@@ -451,7 +458,7 @@ module Devise
|
|
451
458
|
|
452
459
|
# Generate a friendly string randomly to be used as token.
|
453
460
|
def self.friendly_token
|
454
|
-
SecureRandom.
|
461
|
+
SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz')
|
455
462
|
end
|
456
463
|
|
457
464
|
# constant-time comparison algorithm to prevent timing attacks
|
@@ -117,6 +117,7 @@ module Devise
|
|
117
117
|
# sign_in :user, @user # sign_in(scope, resource)
|
118
118
|
# sign_in @user # sign_in(resource)
|
119
119
|
# sign_in @user, :event => :authentication # sign_in(resource, options)
|
120
|
+
# sign_in @user, :store => false # sign_in(resource, options)
|
120
121
|
# sign_in @user, :bypass => true # sign_in(resource, options)
|
121
122
|
#
|
122
123
|
def sign_in(resource_or_scope, *args)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
2
2
|
scope = options[:scope]
|
3
|
-
if record.respond_to?(:remember_me) &&
|
3
|
+
if record.respond_to?(:remember_me) && options[:store] != false &&
|
4
|
+
record.remember_me && warden.authenticated?(scope)
|
4
5
|
Devise::Controllers::Rememberable::Proxy.new(warden).remember_me(record)
|
5
6
|
end
|
6
7
|
end
|
@@ -35,12 +35,6 @@ module Devise
|
|
35
35
|
:template_name => action
|
36
36
|
}.merge(opts)
|
37
37
|
|
38
|
-
if resource.respond_to?(:headers_for)
|
39
|
-
ActiveSupport::Deprecation.warn "Calling headers_for in the model is no longer supported. " <<
|
40
|
-
"Please customize your mailer instead."
|
41
|
-
headers.merge!(resource.headers_for(action))
|
42
|
-
end
|
43
|
-
|
44
38
|
@email = headers[:to]
|
45
39
|
headers
|
46
40
|
end
|
data/lib/devise/models.rb
CHANGED
@@ -56,14 +56,8 @@ module Devise
|
|
56
56
|
klass.devise_modules.each do |mod|
|
57
57
|
constant = const_get(mod.to_s.classify)
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
failed_attributes << field unless instance.respond_to?(field)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
ActiveSupport::Deprecation.warn "The module #{mod} doesn't implement self.required_fields(klass). " \
|
65
|
-
"Devise uses required_fields to warn developers of any missing fields in their models. " \
|
66
|
-
"Please implement #{mod}.required_fields(klass) that returns an array of symbols with the required fields."
|
59
|
+
constant.required_fields(klass).each do |field|
|
60
|
+
failed_attributes << field unless instance.respond_to?(field)
|
67
61
|
end
|
68
62
|
end
|
69
63
|
|
@@ -89,11 +83,13 @@ module Devise
|
|
89
83
|
|
90
84
|
devise_modules_hook! do
|
91
85
|
include Devise::Models::Authenticatable
|
92
|
-
selected_modules.each do |m|
|
93
|
-
if m == :encryptable && !(defined?(Devise::Models::Encryptable))
|
94
|
-
warn "[DEVISE] You're trying to include :encryptable in your model but it is not bundled with the Devise gem anymore. Please add `devise-encryptable` to your Gemfile to proceed.\n"
|
95
|
-
end
|
96
86
|
|
87
|
+
if selected_modules.include?(:token_authenticatable)
|
88
|
+
ActiveSupport::Deprecation.warn "devise :token_authenticatable is deprecated. " \
|
89
|
+
"Please check Devise 3.1 release notes for more information on how to upgrade."
|
90
|
+
end
|
91
|
+
|
92
|
+
selected_modules.each do |m|
|
97
93
|
mod = Devise::Models.const_get(m.to_s.classify)
|
98
94
|
|
99
95
|
if mod.const_defined?("ClassMethods")
|
@@ -144,20 +144,20 @@ module Devise
|
|
144
144
|
#
|
145
145
|
# protected
|
146
146
|
#
|
147
|
-
# def send_devise_notification(notification,
|
148
|
-
# #
|
147
|
+
# def send_devise_notification(notification, *args)
|
148
|
+
# # If the record is new or changed then delay the
|
149
149
|
# # delivery until the after_commit callback otherwise
|
150
150
|
# # send now because after_commit will not be called.
|
151
151
|
# if new_record? || changed?
|
152
|
-
# pending_notifications << [notification,
|
152
|
+
# pending_notifications << [notification, args]
|
153
153
|
# else
|
154
|
-
# devise_mailer.send(notification, self,
|
154
|
+
# devise_mailer.send(notification, self, *args).deliver
|
155
155
|
# end
|
156
156
|
# end
|
157
157
|
#
|
158
158
|
# def send_pending_notifications
|
159
|
-
# pending_notifications.each do |
|
160
|
-
# devise_mailer.send(
|
159
|
+
# pending_notifications.each do |notification, args|
|
160
|
+
# devise_mailer.send(notification, self, *args).deliver
|
161
161
|
# end
|
162
162
|
#
|
163
163
|
# # Empty the pending notifications array because the
|
@@ -171,8 +171,8 @@ module Devise
|
|
171
171
|
# end
|
172
172
|
# end
|
173
173
|
#
|
174
|
-
def send_devise_notification(notification,
|
175
|
-
devise_mailer.send(notification, self,
|
174
|
+
def send_devise_notification(notification, *args)
|
175
|
+
devise_mailer.send(notification, self, *args).deliver
|
176
176
|
end
|
177
177
|
|
178
178
|
def downcase_keys
|
@@ -279,14 +279,6 @@ module Devise
|
|
279
279
|
def devise_parameter_filter
|
280
280
|
@devise_parameter_filter ||= Devise::ParameterFilter.new(case_insensitive_keys, strip_whitespace_keys)
|
281
281
|
end
|
282
|
-
|
283
|
-
# Generate a token by looping and ensuring does not already exist.
|
284
|
-
def generate_token(column)
|
285
|
-
loop do
|
286
|
-
token = Devise.friendly_token
|
287
|
-
break token unless to_adapter.find_first({ column => token })
|
288
|
-
end
|
289
|
-
end
|
290
282
|
end
|
291
283
|
end
|
292
284
|
end
|
@@ -7,7 +7,7 @@ module Devise
|
|
7
7
|
#
|
8
8
|
# == Options
|
9
9
|
#
|
10
|
-
# Confirmable adds the following options to
|
10
|
+
# Confirmable adds the following options to +devise+:
|
11
11
|
#
|
12
12
|
# * +allow_unconfirmed_access_for+: the time you want to allow the user to access his account
|
13
13
|
# before confirming it. After this period, the user access is denied. You can
|
@@ -40,9 +40,10 @@ module Devise
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def initialize(*args, &block)
|
43
|
-
@
|
43
|
+
@bypass_confirmation_postpone = false
|
44
44
|
@reconfirmation_required = false
|
45
45
|
@skip_confirmation_notification = false
|
46
|
+
@raw_confirmation_token = nil
|
46
47
|
super
|
47
48
|
end
|
48
49
|
|
@@ -93,10 +94,12 @@ module Devise
|
|
93
94
|
|
94
95
|
# Send confirmation instructions by email
|
95
96
|
def send_confirmation_instructions
|
96
|
-
|
97
|
+
unless @raw_confirmation_token
|
98
|
+
generate_confirmation_token!
|
99
|
+
end
|
97
100
|
|
98
101
|
opts = pending_reconfirmation? ? { :to => unconfirmed_email } : { }
|
99
|
-
send_devise_notification(:confirmation_instructions, opts)
|
102
|
+
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
100
103
|
end
|
101
104
|
|
102
105
|
def send_reconfirmation_instructions
|
@@ -109,17 +112,11 @@ module Devise
|
|
109
112
|
|
110
113
|
# Resend confirmation token.
|
111
114
|
# Regenerates the token if the period is expired.
|
112
|
-
def
|
115
|
+
def resend_confirmation_instructions
|
113
116
|
pending_any_confirmation do
|
114
|
-
regenerate_confirmation_token! if confirmation_period_expired?
|
115
117
|
send_confirmation_instructions
|
116
118
|
end
|
117
119
|
end
|
118
|
-
|
119
|
-
# Generate a confirmation token unless already exists and save the record.
|
120
|
-
def ensure_confirmation_token!
|
121
|
-
generate_confirmation_token! if should_generate_confirmation_token?
|
122
|
-
end
|
123
120
|
|
124
121
|
# Overwrites active_for_authentication? for confirmation
|
125
122
|
# by verifying whether a user is active to sign in or not. If the user
|
@@ -149,19 +146,16 @@ module Devise
|
|
149
146
|
# If you don't want reconfirmation to be sent, neither a code
|
150
147
|
# to be generated, call skip_reconfirmation!
|
151
148
|
def skip_reconfirmation!
|
152
|
-
@
|
149
|
+
@bypass_confirmation_postpone = true
|
153
150
|
end
|
154
151
|
|
155
152
|
protected
|
156
|
-
def should_generate_confirmation_token?
|
157
|
-
confirmation_token.nil? || confirmation_period_expired?
|
158
|
-
end
|
159
153
|
|
160
154
|
# A callback method used to deliver confirmation
|
161
155
|
# instructions on creation. This can be overriden
|
162
156
|
# in models to map to a nice sign up e-mail.
|
163
157
|
def send_on_create_confirmation_instructions
|
164
|
-
|
158
|
+
send_confirmation_instructions
|
165
159
|
end
|
166
160
|
|
167
161
|
# Callback to overwrite if confirmation is required or not.
|
@@ -221,10 +215,12 @@ module Devise
|
|
221
215
|
end
|
222
216
|
end
|
223
217
|
|
224
|
-
# Generates a new random token for confirmation, and stores
|
225
|
-
# this token is being generated
|
218
|
+
# Generates a new random token for confirmation, and stores
|
219
|
+
# the time this token is being generated
|
226
220
|
def generate_confirmation_token
|
227
|
-
|
221
|
+
raw, enc = Devise.token_generator.generate(self.class, :confirmation_token)
|
222
|
+
@raw_confirmation_token = raw
|
223
|
+
self.confirmation_token = enc
|
228
224
|
self.confirmation_sent_at = Time.now.utc
|
229
225
|
end
|
230
226
|
|
@@ -232,25 +228,16 @@ module Devise
|
|
232
228
|
generate_confirmation_token && save(:validate => false)
|
233
229
|
end
|
234
230
|
|
235
|
-
# Regenerates a new token.
|
236
|
-
def regenerate_confirmation_token
|
237
|
-
generate_confirmation_token
|
238
|
-
end
|
239
|
-
|
240
|
-
def regenerate_confirmation_token!
|
241
|
-
regenerate_confirmation_token && save(:validate => false)
|
242
|
-
end
|
243
|
-
|
244
231
|
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
|
245
232
|
@reconfirmation_required = true
|
246
233
|
self.unconfirmed_email = self.email
|
247
234
|
self.email = self.email_was
|
248
|
-
|
235
|
+
generate_confirmation_token
|
249
236
|
end
|
250
237
|
|
251
238
|
def postpone_email_change?
|
252
|
-
postpone = self.class.reconfirmable && email_changed? && !@
|
253
|
-
@
|
239
|
+
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && !self.email.blank?
|
240
|
+
@bypass_confirmation_postpone = false
|
254
241
|
postpone
|
255
242
|
end
|
256
243
|
|
@@ -275,7 +262,7 @@ module Devise
|
|
275
262
|
unless confirmable.try(:persisted?)
|
276
263
|
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
277
264
|
end
|
278
|
-
confirmable.
|
265
|
+
confirmable.resend_confirmation_instructions if confirmable.persisted?
|
279
266
|
confirmable
|
280
267
|
end
|
281
268
|
|
@@ -284,16 +271,19 @@ module Devise
|
|
284
271
|
# If the user is already confirmed, create an error for the user
|
285
272
|
# Options must have the confirmation_token
|
286
273
|
def confirm_by_token(confirmation_token)
|
274
|
+
original_token = confirmation_token
|
275
|
+
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
|
276
|
+
|
287
277
|
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
|
278
|
+
if !confirmable.persisted? && Devise.allow_insecure_token_lookup
|
279
|
+
confirmable = find_or_initialize_with_error_by(:confirmation_token, original_token)
|
280
|
+
end
|
281
|
+
|
288
282
|
confirmable.confirm! if confirmable.persisted?
|
283
|
+
confirmable.confirmation_token = original_token
|
289
284
|
confirmable
|
290
285
|
end
|
291
286
|
|
292
|
-
# Generate a token checking if one does not already exist in the database.
|
293
|
-
def confirmation_token
|
294
|
-
generate_token(:confirmation_token)
|
295
|
-
end
|
296
|
-
|
297
287
|
# Find a record for confirmation by unconfirmed email field
|
298
288
|
def find_by_unconfirmed_email_with_errors(attributes = {})
|
299
289
|
unconfirmed_required_attributes = confirmation_keys.map { |k| k == :email ? :unconfirmed_email : k }
|
@@ -38,7 +38,6 @@ module Devise
|
|
38
38
|
self.locked_at = Time.now.utc
|
39
39
|
|
40
40
|
if unlock_strategy_enabled?(:email)
|
41
|
-
generate_unlock_token!
|
42
41
|
send_unlock_instructions
|
43
42
|
else
|
44
43
|
save(:validate => false)
|
@@ -60,11 +59,15 @@ module Devise
|
|
60
59
|
|
61
60
|
# Send unlock instructions by email
|
62
61
|
def send_unlock_instructions
|
63
|
-
|
62
|
+
raw, enc = Devise.token_generator.generate(self.class, :unlock_token)
|
63
|
+
self.unlock_token = enc
|
64
|
+
self.save(:validate => false)
|
65
|
+
send_devise_notification(:unlock_instructions, raw, {})
|
66
|
+
raw
|
64
67
|
end
|
65
68
|
|
66
69
|
# Resend the unlock instructions if the user is locked.
|
67
|
-
def
|
70
|
+
def resend_unlock_instructions
|
68
71
|
if_access_locked { send_unlock_instructions }
|
69
72
|
end
|
70
73
|
|
@@ -122,15 +125,6 @@ module Devise
|
|
122
125
|
self.failed_attempts > self.class.maximum_attempts
|
123
126
|
end
|
124
127
|
|
125
|
-
# Generates unlock token
|
126
|
-
def generate_unlock_token
|
127
|
-
self.unlock_token = self.class.unlock_token
|
128
|
-
end
|
129
|
-
|
130
|
-
def generate_unlock_token!
|
131
|
-
generate_unlock_token && save(:validate => false)
|
132
|
-
end
|
133
|
-
|
134
128
|
# Tells if the lock is expired if :time unlock strategy is active
|
135
129
|
def lock_expired?
|
136
130
|
if unlock_strategy_enabled?(:time)
|
@@ -158,7 +152,7 @@ module Devise
|
|
158
152
|
# Options must contain the user's unlock keys
|
159
153
|
def send_unlock_instructions(attributes={})
|
160
154
|
lockable = find_or_initialize_with_errors(unlock_keys, attributes, :not_found)
|
161
|
-
lockable.
|
155
|
+
lockable.resend_unlock_instructions if lockable.persisted?
|
162
156
|
lockable
|
163
157
|
end
|
164
158
|
|
@@ -167,8 +161,16 @@ module Devise
|
|
167
161
|
# If the user is not locked, creates an error for the user
|
168
162
|
# Options must have the unlock_token
|
169
163
|
def unlock_access_by_token(unlock_token)
|
164
|
+
original_token = unlock_token
|
165
|
+
unlock_token = Devise.token_generator.digest(self, :unlock_token, unlock_token)
|
166
|
+
|
170
167
|
lockable = find_or_initialize_with_error_by(:unlock_token, unlock_token)
|
168
|
+
if !lockable.persisted? && Devise.allow_insecure_token_lookup
|
169
|
+
lockable = find_or_initialize_with_error_by(:unlock_token, original_token)
|
170
|
+
end
|
171
|
+
|
171
172
|
lockable.unlock_access! if lockable.persisted?
|
173
|
+
lockable.unlock_token = original_token
|
172
174
|
lockable
|
173
175
|
end
|
174
176
|
|
@@ -182,10 +184,6 @@ module Devise
|
|
182
184
|
self.lock_strategy == strategy
|
183
185
|
end
|
184
186
|
|
185
|
-
def unlock_token
|
186
|
-
Devise.friendly_token
|
187
|
-
end
|
188
|
-
|
189
187
|
Devise::Models.config(self, :maximum_attempts, :lock_strategy, :unlock_strategy, :unlock_in, :unlock_keys)
|
190
188
|
end
|
191
189
|
end
|
@@ -42,17 +42,19 @@ module Devise
|
|
42
42
|
save
|
43
43
|
end
|
44
44
|
|
45
|
-
# Resets reset password token and send reset password instructions by email
|
45
|
+
# Resets reset password token and send reset password instructions by email.
|
46
|
+
# Returns the token sent in the e-mail.
|
46
47
|
def send_reset_password_instructions
|
47
|
-
|
48
|
-
|
48
|
+
raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)
|
49
|
+
|
50
|
+
self.reset_password_token = enc
|
51
|
+
self.reset_password_sent_at = Time.now.utc
|
52
|
+
self.save(:validate => false)
|
53
|
+
|
54
|
+
send_devise_notification(:reset_password_instructions, raw, {})
|
55
|
+
raw
|
49
56
|
end
|
50
|
-
|
51
|
-
# Generate reset password token unless already exists and save the record.
|
52
|
-
def ensure_reset_password_token!
|
53
|
-
generate_reset_password_token! if should_generate_reset_token?
|
54
|
-
end
|
55
|
-
|
57
|
+
|
56
58
|
# Checks if the reset password token sent is within the limit time.
|
57
59
|
# We do this by calculating if the difference between today and the
|
58
60
|
# sending date does not exceed the confirm in time configured.
|
@@ -79,23 +81,6 @@ module Devise
|
|
79
81
|
|
80
82
|
protected
|
81
83
|
|
82
|
-
def should_generate_reset_token?
|
83
|
-
reset_password_token.nil? || !reset_password_period_valid?
|
84
|
-
end
|
85
|
-
|
86
|
-
# Generates a new random token for reset password
|
87
|
-
def generate_reset_password_token
|
88
|
-
self.reset_password_token = self.class.reset_password_token
|
89
|
-
self.reset_password_sent_at = Time.now.utc
|
90
|
-
self.reset_password_token
|
91
|
-
end
|
92
|
-
|
93
|
-
# Resets the reset password token with and save the record without
|
94
|
-
# validating
|
95
|
-
def generate_reset_password_token!
|
96
|
-
generate_reset_password_token && save(:validate => false)
|
97
|
-
end
|
98
|
-
|
99
84
|
# Removes reset_password token
|
100
85
|
def clear_reset_password_token
|
101
86
|
self.reset_password_token = nil
|
@@ -127,7 +112,14 @@ module Devise
|
|
127
112
|
# containing an error in reset_password_token attribute.
|
128
113
|
# Attributes must contain reset_password_token, password and confirmation
|
129
114
|
def reset_password_by_token(attributes={})
|
130
|
-
|
115
|
+
original_token = attributes[:reset_password_token]
|
116
|
+
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
|
117
|
+
|
118
|
+
recoverable = find_or_initialize_with_error_by(:reset_password_token, reset_password_token)
|
119
|
+
if !recoverable.persisted? && Devise.allow_insecure_token_lookup
|
120
|
+
recoverable = find_or_initialize_with_error_by(:reset_password_token, original_token)
|
121
|
+
end
|
122
|
+
|
131
123
|
if recoverable.persisted?
|
132
124
|
if recoverable.reset_password_period_valid?
|
133
125
|
recoverable.reset_password!(attributes[:password], attributes[:password_confirmation])
|
@@ -135,6 +127,8 @@ module Devise
|
|
135
127
|
recoverable.errors.add(:reset_password_token, :expired)
|
136
128
|
end
|
137
129
|
end
|
130
|
+
|
131
|
+
recoverable.reset_password_token = original_token
|
138
132
|
recoverable
|
139
133
|
end
|
140
134
|
|