devise 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of devise might be problematic. Click here for more details.
- data/{CHANGELOG.rdoc → CHANGELOG.md} +67 -25
- data/Gemfile.lock +13 -12
- data/README.md +19 -17
- data/app/controllers/devise/confirmations_controller.rb +11 -3
- data/app/controllers/devise/registrations_controller.rb +9 -3
- 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 +4 -3
- data/devise.gemspec +1 -0
- data/gemfiles/Gemfile.rails-3.2.x.lock +47 -44
- data/lib/devise/controllers/helpers.rb +1 -0
- data/lib/devise/controllers/rememberable.rb +1 -0
- data/lib/devise/hooks/csrf_cleaner.rb +5 -0
- data/lib/devise/hooks/lockable.rb +1 -1
- data/lib/devise/hooks/rememberable.rb +2 -1
- data/lib/devise/mailers/helpers.rb +0 -6
- data/lib/devise/models/authenticatable.rb +9 -16
- data/lib/devise/models/confirmable.rb +34 -43
- data/lib/devise/models/lockable.rb +15 -17
- data/lib/devise/models/recoverable.rb +21 -27
- data/lib/devise/models/rememberable.rb +6 -2
- data/lib/devise/models/timeoutable.rb +1 -1
- data/lib/devise/models/token_authenticatable.rb +4 -1
- data/lib/devise/models.rb +8 -12
- data/lib/devise/parameter_sanitizer.rb +49 -19
- data/lib/devise/rails/routes.rb +12 -9
- data/lib/devise/rails/warden_compat.rb +10 -2
- data/lib/devise/rails.rb +7 -11
- data/lib/devise/strategies/authenticatable.rb +0 -12
- data/lib/devise/token_generator.rb +70 -0
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +23 -12
- data/lib/generators/active_record/devise_generator.rb +2 -5
- data/lib/generators/active_record/templates/migration.rb +0 -1
- data/lib/generators/active_record/templates/migration_existing.rb +0 -1
- data/lib/generators/devise/orm_helpers.rb +25 -6
- data/lib/generators/mongoid/devise_generator.rb +2 -2
- data/lib/generators/templates/devise.rb +21 -9
- data/test/controllers/helpers_test.rb +1 -1
- data/test/controllers/passwords_controller_test.rb +4 -5
- data/test/failure_app_test.rb +1 -1
- data/test/generators/active_record_generator_test.rb +31 -1
- data/test/integration/authenticatable_test.rb +15 -1
- data/test/integration/confirmable_test.rb +29 -42
- data/test/integration/http_authenticatable_test.rb +1 -1
- data/test/integration/lockable_test.rb +11 -14
- data/test/integration/recoverable_test.rb +23 -24
- data/test/integration/rememberable_test.rb +15 -13
- 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 +38 -27
- data/test/models/lockable_test.rb +15 -5
- data/test/models/recoverable_test.rb +20 -48
- data/test/models/rememberable_test.rb +8 -0
- data/test/models/timeoutable_test.rb +5 -0
- 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 +42 -26
- data/app/views/devise/_links.erb +0 -3
@@ -1,21 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
devise (3.
|
4
|
+
devise (3.1.0)
|
5
5
|
bcrypt-ruby (~> 3.0)
|
6
6
|
orm_adapter (~> 0.1)
|
7
7
|
railties (>= 3.2.6, < 5)
|
8
|
-
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
warden (~> 1.2.3)
|
9
10
|
|
10
11
|
GEM
|
11
12
|
remote: https://rubygems.org/
|
12
13
|
specs:
|
13
|
-
actionmailer (3.2.
|
14
|
-
actionpack (= 3.2.
|
15
|
-
mail (~> 2.5.
|
16
|
-
actionpack (3.2.
|
17
|
-
activemodel (= 3.2.
|
18
|
-
activesupport (= 3.2.
|
14
|
+
actionmailer (3.2.14)
|
15
|
+
actionpack (= 3.2.14)
|
16
|
+
mail (~> 2.5.4)
|
17
|
+
actionpack (3.2.14)
|
18
|
+
activemodel (= 3.2.14)
|
19
|
+
activesupport (= 3.2.14)
|
19
20
|
builder (~> 3.0.0)
|
20
21
|
erubis (~> 2.7.0)
|
21
22
|
journey (~> 1.0.4)
|
@@ -23,49 +24,49 @@ GEM
|
|
23
24
|
rack-cache (~> 1.2)
|
24
25
|
rack-test (~> 0.6.1)
|
25
26
|
sprockets (~> 2.2.1)
|
26
|
-
activemodel (3.2.
|
27
|
-
activesupport (= 3.2.
|
27
|
+
activemodel (3.2.14)
|
28
|
+
activesupport (= 3.2.14)
|
28
29
|
builder (~> 3.0.0)
|
29
|
-
activerecord (3.2.
|
30
|
-
activemodel (= 3.2.
|
31
|
-
activesupport (= 3.2.
|
30
|
+
activerecord (3.2.14)
|
31
|
+
activemodel (= 3.2.14)
|
32
|
+
activesupport (= 3.2.14)
|
32
33
|
arel (~> 3.0.2)
|
33
34
|
tzinfo (~> 0.3.29)
|
34
|
-
activeresource (3.2.
|
35
|
-
activemodel (= 3.2.
|
36
|
-
activesupport (= 3.2.
|
37
|
-
activesupport (3.2.
|
38
|
-
i18n (
|
35
|
+
activeresource (3.2.14)
|
36
|
+
activemodel (= 3.2.14)
|
37
|
+
activesupport (= 3.2.14)
|
38
|
+
activesupport (3.2.14)
|
39
|
+
i18n (~> 0.6, >= 0.6.4)
|
39
40
|
multi_json (~> 1.0)
|
40
41
|
arel (3.0.2)
|
41
|
-
|
42
|
+
atomic (1.1.13)
|
43
|
+
bcrypt-ruby (3.1.1)
|
42
44
|
builder (3.0.4)
|
43
45
|
erubis (2.7.0)
|
44
|
-
faraday (0.8.
|
45
|
-
multipart-post (~> 1.
|
46
|
+
faraday (0.8.8)
|
47
|
+
multipart-post (~> 1.2.0)
|
46
48
|
hashie (1.2.0)
|
47
|
-
hike (1.2.
|
49
|
+
hike (1.2.3)
|
48
50
|
httpauth (0.2.0)
|
49
|
-
i18n (0.6.
|
51
|
+
i18n (0.6.5)
|
50
52
|
journey (1.0.4)
|
51
|
-
json (1.
|
53
|
+
json (1.8.0)
|
52
54
|
jwt (0.1.8)
|
53
55
|
multi_json (>= 1.5)
|
54
|
-
mail (2.5.
|
55
|
-
i18n (>= 0.4.0)
|
56
|
+
mail (2.5.4)
|
56
57
|
mime-types (~> 1.16)
|
57
58
|
treetop (~> 1.4.8)
|
58
59
|
metaclass (0.0.1)
|
59
60
|
mime-types (1.23)
|
60
61
|
mocha (0.13.3)
|
61
62
|
metaclass (~> 0.0.1)
|
62
|
-
mongoid (3.1.
|
63
|
+
mongoid (3.1.4)
|
63
64
|
activemodel (~> 3.2)
|
64
|
-
moped (~> 1.4
|
65
|
+
moped (~> 1.4)
|
65
66
|
origin (~> 1.0)
|
66
67
|
tzinfo (~> 0.3.22)
|
67
|
-
moped (1.
|
68
|
-
multi_json (1.7.
|
68
|
+
moped (1.5.1)
|
69
|
+
multi_json (1.7.9)
|
69
70
|
multipart-post (1.2.0)
|
70
71
|
nokogiri (1.5.9)
|
71
72
|
oauth2 (0.8.1)
|
@@ -98,22 +99,22 @@ GEM
|
|
98
99
|
rack
|
99
100
|
rack-test (0.6.2)
|
100
101
|
rack (>= 1.0)
|
101
|
-
rails (3.2.
|
102
|
-
actionmailer (= 3.2.
|
103
|
-
actionpack (= 3.2.
|
104
|
-
activerecord (= 3.2.
|
105
|
-
activeresource (= 3.2.
|
106
|
-
activesupport (= 3.2.
|
102
|
+
rails (3.2.14)
|
103
|
+
actionmailer (= 3.2.14)
|
104
|
+
actionpack (= 3.2.14)
|
105
|
+
activerecord (= 3.2.14)
|
106
|
+
activeresource (= 3.2.14)
|
107
|
+
activesupport (= 3.2.14)
|
107
108
|
bundler (~> 1.0)
|
108
|
-
railties (= 3.2.
|
109
|
-
railties (3.2.
|
110
|
-
actionpack (= 3.2.
|
111
|
-
activesupport (= 3.2.
|
109
|
+
railties (= 3.2.14)
|
110
|
+
railties (3.2.14)
|
111
|
+
actionpack (= 3.2.14)
|
112
|
+
activesupport (= 3.2.14)
|
112
113
|
rack-ssl (~> 1.3.2)
|
113
114
|
rake (>= 0.8.7)
|
114
115
|
rdoc (~> 3.4)
|
115
116
|
thor (>= 0.14.6, < 2.0)
|
116
|
-
rake (10.0
|
117
|
+
rake (10.1.0)
|
117
118
|
rdoc (3.12.2)
|
118
119
|
json (~> 1.4)
|
119
120
|
ruby-openid (2.2.3)
|
@@ -124,12 +125,14 @@ GEM
|
|
124
125
|
tilt (~> 1.1, != 1.3.0)
|
125
126
|
sqlite3 (1.3.7)
|
126
127
|
thor (0.18.1)
|
127
|
-
|
128
|
-
|
128
|
+
thread_safe (0.1.2)
|
129
|
+
atomic
|
130
|
+
tilt (1.4.1)
|
131
|
+
treetop (1.4.14)
|
129
132
|
polyglot
|
130
133
|
polyglot (>= 0.3.1)
|
131
134
|
tzinfo (0.3.37)
|
132
|
-
warden (1.2.
|
135
|
+
warden (1.2.3)
|
133
136
|
rack (>= 1.0)
|
134
137
|
webrat (0.7.3)
|
135
138
|
nokogiri (>= 1.2.0)
|
@@ -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)
|
@@ -21,6 +21,7 @@ module Devise
|
|
21
21
|
|
22
22
|
# Remembers the given resource by setting up a cookie
|
23
23
|
def remember_me(resource)
|
24
|
+
return if env["devise.skip_storage"]
|
24
25
|
scope = Devise::Mapping.find_scope!(resource)
|
25
26
|
resource.remember_me!(resource.extend_remember_period)
|
26
27
|
cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)
|
@@ -2,6 +2,6 @@
|
|
2
2
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
3
|
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
4
4
|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
|
5
|
-
record.update_attribute(:failed_attempts, 0) unless record.failed_attempts.zero?
|
5
|
+
record.update_attribute(:failed_attempts, 0) unless record.failed_attempts.to_i.zero?
|
6
6
|
end
|
7
7
|
end
|
@@ -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
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'devise/hooks/activatable'
|
2
|
+
require 'devise/hooks/csrf_cleaner'
|
2
3
|
|
3
4
|
module Devise
|
4
5
|
module Models
|
@@ -143,20 +144,20 @@ module Devise
|
|
143
144
|
#
|
144
145
|
# protected
|
145
146
|
#
|
146
|
-
# def send_devise_notification(notification,
|
147
|
-
# #
|
147
|
+
# def send_devise_notification(notification, *args)
|
148
|
+
# # If the record is new or changed then delay the
|
148
149
|
# # delivery until the after_commit callback otherwise
|
149
150
|
# # send now because after_commit will not be called.
|
150
151
|
# if new_record? || changed?
|
151
|
-
# pending_notifications << [notification,
|
152
|
+
# pending_notifications << [notification, args]
|
152
153
|
# else
|
153
|
-
# devise_mailer.send(notification, self,
|
154
|
+
# devise_mailer.send(notification, self, *args).deliver
|
154
155
|
# end
|
155
156
|
# end
|
156
157
|
#
|
157
158
|
# def send_pending_notifications
|
158
|
-
# pending_notifications.each do |
|
159
|
-
# devise_mailer.send(
|
159
|
+
# pending_notifications.each do |notification, args|
|
160
|
+
# devise_mailer.send(notification, self, *args).deliver
|
160
161
|
# end
|
161
162
|
#
|
162
163
|
# # Empty the pending notifications array because the
|
@@ -170,8 +171,8 @@ module Devise
|
|
170
171
|
# end
|
171
172
|
# end
|
172
173
|
#
|
173
|
-
def send_devise_notification(notification,
|
174
|
-
devise_mailer.send(notification, self,
|
174
|
+
def send_devise_notification(notification, *args)
|
175
|
+
devise_mailer.send(notification, self, *args).deliver
|
175
176
|
end
|
176
177
|
|
177
178
|
def downcase_keys
|
@@ -278,14 +279,6 @@ module Devise
|
|
278
279
|
def devise_parameter_filter
|
279
280
|
@devise_parameter_filter ||= Devise::ParameterFilter.new(case_insensitive_keys, strip_whitespace_keys)
|
280
281
|
end
|
281
|
-
|
282
|
-
# Generate a token by looping and ensuring does not already exist.
|
283
|
-
def generate_token(column)
|
284
|
-
loop do
|
285
|
-
token = Devise.friendly_token
|
286
|
-
break token unless to_adapter.find_first({ column => token })
|
287
|
-
end
|
288
|
-
end
|
289
282
|
end
|
290
283
|
end
|
291
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
|
|
@@ -66,7 +67,7 @@ module Devise
|
|
66
67
|
self.confirmation_token = nil
|
67
68
|
self.confirmed_at = Time.now.utc
|
68
69
|
|
69
|
-
if self.class.reconfirmable && unconfirmed_email.present?
|
70
|
+
saved = if self.class.reconfirmable && unconfirmed_email.present?
|
70
71
|
skip_reconfirmation!
|
71
72
|
self.email = unconfirmed_email
|
72
73
|
self.unconfirmed_email = nil
|
@@ -76,6 +77,9 @@ module Devise
|
|
76
77
|
else
|
77
78
|
save(:validate => false)
|
78
79
|
end
|
80
|
+
|
81
|
+
after_confirmation if saved
|
82
|
+
saved
|
79
83
|
end
|
80
84
|
end
|
81
85
|
|
@@ -90,10 +94,12 @@ module Devise
|
|
90
94
|
|
91
95
|
# Send confirmation instructions by email
|
92
96
|
def send_confirmation_instructions
|
93
|
-
|
97
|
+
unless @raw_confirmation_token
|
98
|
+
generate_confirmation_token!
|
99
|
+
end
|
94
100
|
|
95
101
|
opts = pending_reconfirmation? ? { :to => unconfirmed_email } : { }
|
96
|
-
send_devise_notification(:confirmation_instructions, opts)
|
102
|
+
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
97
103
|
end
|
98
104
|
|
99
105
|
def send_reconfirmation_instructions
|
@@ -106,17 +112,11 @@ module Devise
|
|
106
112
|
|
107
113
|
# Resend confirmation token.
|
108
114
|
# Regenerates the token if the period is expired.
|
109
|
-
def
|
115
|
+
def resend_confirmation_instructions
|
110
116
|
pending_any_confirmation do
|
111
|
-
regenerate_confirmation_token! if confirmation_period_expired?
|
112
117
|
send_confirmation_instructions
|
113
118
|
end
|
114
119
|
end
|
115
|
-
|
116
|
-
# Generate a confirmation token unless already exists and save the record.
|
117
|
-
def ensure_confirmation_token!
|
118
|
-
generate_confirmation_token! if should_generate_confirmation_token?
|
119
|
-
end
|
120
120
|
|
121
121
|
# Overwrites active_for_authentication? for confirmation
|
122
122
|
# by verifying whether a user is active to sign in or not. If the user
|
@@ -146,19 +146,16 @@ module Devise
|
|
146
146
|
# If you don't want reconfirmation to be sent, neither a code
|
147
147
|
# to be generated, call skip_reconfirmation!
|
148
148
|
def skip_reconfirmation!
|
149
|
-
@
|
149
|
+
@bypass_confirmation_postpone = true
|
150
150
|
end
|
151
151
|
|
152
152
|
protected
|
153
|
-
def should_generate_confirmation_token?
|
154
|
-
confirmation_token.nil? || confirmation_period_expired?
|
155
|
-
end
|
156
153
|
|
157
154
|
# A callback method used to deliver confirmation
|
158
155
|
# instructions on creation. This can be overriden
|
159
156
|
# in models to map to a nice sign up e-mail.
|
160
157
|
def send_on_create_confirmation_instructions
|
161
|
-
|
158
|
+
send_confirmation_instructions
|
162
159
|
end
|
163
160
|
|
164
161
|
# Callback to overwrite if confirmation is required or not.
|
@@ -218,10 +215,12 @@ module Devise
|
|
218
215
|
end
|
219
216
|
end
|
220
217
|
|
221
|
-
# Generates a new random token for confirmation, and stores
|
222
|
-
# this token is being generated
|
218
|
+
# Generates a new random token for confirmation, and stores
|
219
|
+
# the time this token is being generated
|
223
220
|
def generate_confirmation_token
|
224
|
-
|
221
|
+
raw, enc = Devise.token_generator.generate(self.class, :confirmation_token)
|
222
|
+
@raw_confirmation_token = raw
|
223
|
+
self.confirmation_token = enc
|
225
224
|
self.confirmation_sent_at = Time.now.utc
|
226
225
|
end
|
227
226
|
|
@@ -229,30 +228,16 @@ module Devise
|
|
229
228
|
generate_confirmation_token && save(:validate => false)
|
230
229
|
end
|
231
230
|
|
232
|
-
# Regenerates a new token.
|
233
|
-
def regenerate_confirmation_token
|
234
|
-
generate_confirmation_token
|
235
|
-
end
|
236
|
-
|
237
|
-
def regenerate_confirmation_token!
|
238
|
-
regenerate_confirmation_token && save(:validate => false)
|
239
|
-
end
|
240
|
-
|
241
|
-
def after_password_reset
|
242
|
-
super
|
243
|
-
confirm! unless confirmed?
|
244
|
-
end
|
245
|
-
|
246
231
|
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
|
247
232
|
@reconfirmation_required = true
|
248
233
|
self.unconfirmed_email = self.email
|
249
234
|
self.email = self.email_was
|
250
|
-
|
235
|
+
generate_confirmation_token
|
251
236
|
end
|
252
237
|
|
253
238
|
def postpone_email_change?
|
254
|
-
postpone = self.class.reconfirmable && email_changed? && !@
|
255
|
-
@
|
239
|
+
postpone = self.class.reconfirmable && email_changed? && !@bypass_confirmation_postpone && !self.email.blank?
|
240
|
+
@bypass_confirmation_postpone = false
|
256
241
|
postpone
|
257
242
|
end
|
258
243
|
|
@@ -264,6 +249,9 @@ module Devise
|
|
264
249
|
confirmation_required? && !@skip_confirmation_notification && !self.email.blank?
|
265
250
|
end
|
266
251
|
|
252
|
+
def after_confirmation
|
253
|
+
end
|
254
|
+
|
267
255
|
module ClassMethods
|
268
256
|
# Attempt to find a user by its email. If a record is found, send new
|
269
257
|
# confirmation instructions to it. If not, try searching for a user by unconfirmed_email
|
@@ -274,7 +262,7 @@ module Devise
|
|
274
262
|
unless confirmable.try(:persisted?)
|
275
263
|
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
276
264
|
end
|
277
|
-
confirmable.
|
265
|
+
confirmable.resend_confirmation_instructions if confirmable.persisted?
|
278
266
|
confirmable
|
279
267
|
end
|
280
268
|
|
@@ -283,16 +271,19 @@ module Devise
|
|
283
271
|
# If the user is already confirmed, create an error for the user
|
284
272
|
# Options must have the confirmation_token
|
285
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
|
+
|
286
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
|
+
|
287
282
|
confirmable.confirm! if confirmable.persisted?
|
283
|
+
confirmable.confirmation_token = original_token
|
288
284
|
confirmable
|
289
285
|
end
|
290
286
|
|
291
|
-
# Generate a token checking if one does not already exist in the database.
|
292
|
-
def confirmation_token
|
293
|
-
generate_token(:confirmation_token)
|
294
|
-
end
|
295
|
-
|
296
287
|
# Find a record for confirmation by unconfirmed email field
|
297
288
|
def find_by_unconfirmed_email_with_errors(attributes = {})
|
298
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
|
|
@@ -110,12 +110,16 @@ module Devise
|
|
110
110
|
# Recreate the user based on the stored cookie
|
111
111
|
def serialize_from_cookie(id, remember_token)
|
112
112
|
record = to_adapter.get(id)
|
113
|
-
record if record &&
|
113
|
+
record if record && !record.remember_expired? &&
|
114
|
+
Devise.secure_compare(record.rememberable_value, remember_token)
|
114
115
|
end
|
115
116
|
|
116
117
|
# Generate a token checking if one does not already exist in the database.
|
117
118
|
def remember_token #:nodoc:
|
118
|
-
|
119
|
+
loop do
|
120
|
+
token = Devise.friendly_token
|
121
|
+
break token unless to_adapter.find_first({ :remember_token => token })
|
122
|
+
end
|
119
123
|
end
|
120
124
|
|
121
125
|
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options)
|
@@ -37,7 +37,7 @@ module Devise
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def remember_exists_and_not_expired?
|
40
|
-
return false unless respond_to?(:remember_created_at)
|
40
|
+
return false unless respond_to?(:remember_created_at) && respond_to?(:remember_expired?)
|
41
41
|
remember_created_at && !remember_expired?
|
42
42
|
end
|
43
43
|
|
@@ -79,7 +79,10 @@ module Devise
|
|
79
79
|
|
80
80
|
# Generate a token checking if one does not already exist in the database.
|
81
81
|
def authentication_token
|
82
|
-
|
82
|
+
loop do
|
83
|
+
token = Devise.friendly_token
|
84
|
+
break token unless to_adapter.find_first({ :authentication_token => token })
|
85
|
+
end
|
83
86
|
end
|
84
87
|
|
85
88
|
Devise::Models.config(self, :token_authentication_key, :expire_auth_token_on_timeout)
|