devise 4.2.0 → 4.4.3
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.
- checksums.yaml +5 -5
- data/.travis.yml +27 -5
- data/CHANGELOG.md +65 -0
- data/CONTRIBUTING.md +68 -28
- data/Gemfile +3 -1
- data/Gemfile.lock +79 -83
- data/ISSUE_TEMPLATE.md +19 -0
- data/MIT-LICENSE +1 -1
- data/README.md +108 -11
- data/Rakefile +1 -0
- data/app/controllers/devise/confirmations_controller.rb +2 -0
- data/app/controllers/devise/omniauth_callbacks_controller.rb +4 -2
- data/app/controllers/devise/passwords_controller.rb +2 -0
- data/app/controllers/devise/registrations_controller.rb +6 -3
- data/app/controllers/devise/sessions_controller.rb +3 -1
- data/app/controllers/devise/unlocks_controller.rb +2 -0
- data/app/controllers/devise_controller.rb +2 -0
- data/app/helpers/devise_helper.rb +2 -0
- data/app/mailers/devise/mailer.rb +6 -0
- data/app/views/devise/confirmations/new.html.erb +1 -1
- data/app/views/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/edit.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/views/devise/unlocks/new.html.erb +1 -1
- data/config/locales/en.yml +2 -0
- data/devise.gemspec +3 -1
- data/gemfiles/Gemfile.rails-4.1-stable +3 -1
- data/gemfiles/Gemfile.rails-4.1-stable.lock +67 -70
- data/gemfiles/Gemfile.rails-4.2-stable +3 -1
- data/gemfiles/Gemfile.rails-4.2-stable.lock +69 -73
- data/gemfiles/Gemfile.rails-5.0-stable +33 -0
- data/gemfiles/Gemfile.rails-5.0-stable.lock +192 -0
- data/gemfiles/Gemfile.rails-5.2-rc1 +26 -0
- data/gemfiles/Gemfile.rails-5.2-rc1.lock +201 -0
- data/guides/bug_report_templates/integration_test.rb +2 -0
- data/lib/devise/controllers/helpers.rb +2 -0
- data/lib/devise/controllers/rememberable.rb +2 -0
- data/lib/devise/controllers/scoped_views.rb +2 -0
- data/lib/devise/controllers/sign_in_out.rb +6 -1
- data/lib/devise/controllers/store_location.rb +25 -7
- data/lib/devise/controllers/url_helpers.rb +2 -0
- data/lib/devise/delegator.rb +2 -0
- data/lib/devise/encryptor.rb +2 -0
- data/lib/devise/failure_app.rb +14 -12
- data/lib/devise/hooks/activatable.rb +2 -0
- data/lib/devise/hooks/csrf_cleaner.rb +2 -0
- data/lib/devise/hooks/forgetable.rb +2 -0
- data/lib/devise/hooks/lockable.rb +6 -1
- data/lib/devise/hooks/proxy.rb +2 -0
- data/lib/devise/hooks/rememberable.rb +2 -0
- data/lib/devise/hooks/timeoutable.rb +2 -0
- data/lib/devise/hooks/trackable.rb +2 -0
- data/lib/devise/mailers/helpers.rb +6 -3
- data/lib/devise/mapping.rb +2 -0
- data/lib/devise/models/authenticatable.rb +4 -2
- data/lib/devise/models/confirmable.rb +53 -17
- data/lib/devise/models/database_authenticatable.rb +40 -4
- data/lib/devise/models/lockable.rb +8 -2
- data/lib/devise/models/omniauthable.rb +2 -0
- data/lib/devise/models/recoverable.rb +26 -9
- data/lib/devise/models/registerable.rb +2 -0
- data/lib/devise/models/rememberable.rb +4 -2
- data/lib/devise/models/timeoutable.rb +2 -0
- data/lib/devise/models/trackable.rb +7 -0
- data/lib/devise/models/validatable.rb +10 -3
- data/lib/devise/models.rb +3 -1
- data/lib/devise/modules.rb +2 -0
- data/lib/devise/omniauth/config.rb +2 -0
- data/lib/devise/omniauth/url_helpers.rb +2 -0
- data/lib/devise/omniauth.rb +2 -0
- data/lib/devise/orm/active_record.rb +2 -0
- data/lib/devise/orm/mongoid.rb +2 -0
- data/lib/devise/parameter_filter.rb +2 -0
- data/lib/devise/parameter_sanitizer.rb +2 -0
- data/lib/devise/rails/routes.rb +3 -1
- data/lib/devise/rails/warden_compat.rb +2 -0
- data/lib/devise/rails.rb +3 -5
- data/lib/devise/secret_key_finder.rb +25 -0
- data/lib/devise/strategies/authenticatable.rb +2 -0
- data/lib/devise/strategies/base.rb +2 -0
- data/lib/devise/strategies/database_authenticatable.rb +2 -0
- data/lib/devise/strategies/rememberable.rb +2 -0
- data/lib/devise/test/controller_helpers.rb +4 -1
- data/lib/devise/test/integration_helpers.rb +2 -0
- data/lib/devise/test_helpers.rb +3 -1
- data/lib/devise/time_inflector.rb +2 -0
- data/lib/devise/token_generator.rb +2 -0
- data/lib/devise/version.rb +3 -1
- data/lib/devise.rb +17 -2
- data/lib/generators/active_record/devise_generator.rb +15 -2
- data/lib/generators/active_record/templates/migration.rb +3 -1
- data/lib/generators/active_record/templates/migration_existing.rb +2 -0
- data/lib/generators/devise/controllers_generator.rb +2 -0
- data/lib/generators/devise/devise_generator.rb +4 -2
- data/lib/generators/devise/install_generator.rb +2 -0
- data/lib/generators/devise/orm_helpers.rb +7 -1
- data/lib/generators/devise/views_generator.rb +7 -8
- data/lib/generators/mongoid/devise_generator.rb +2 -0
- data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
- data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +2 -0
- data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
- data/lib/generators/templates/controllers/registrations_controller.rb +4 -2
- data/lib/generators/templates/controllers/sessions_controller.rb +3 -1
- data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
- data/lib/generators/templates/devise.rb +10 -1
- data/lib/generators/templates/markerb/email_changed.markerb +7 -0
- data/lib/generators/templates/markerb/password_change.markerb +2 -2
- data/test/controllers/custom_registrations_controller_test.rb +2 -0
- data/test/controllers/custom_strategy_test.rb +2 -0
- data/test/controllers/helper_methods_test.rb +2 -0
- data/test/controllers/helpers_test.rb +5 -3
- data/test/controllers/inherited_controller_i18n_messages_test.rb +2 -0
- data/test/controllers/internal_helpers_test.rb +2 -0
- data/test/controllers/load_hooks_controller_test.rb +2 -0
- data/test/controllers/passwords_controller_test.rb +2 -0
- data/test/controllers/sessions_controller_test.rb +2 -0
- data/test/controllers/url_helpers_test.rb +2 -0
- data/test/delegator_test.rb +2 -0
- data/test/devise_test.rb +2 -0
- data/test/failure_app_test.rb +2 -0
- data/test/generators/active_record_generator_test.rb +47 -0
- data/test/generators/controllers_generator_test.rb +2 -0
- data/test/generators/devise_generator_test.rb +2 -0
- data/test/generators/install_generator_test.rb +2 -0
- data/test/generators/mongoid_generator_test.rb +2 -0
- data/test/generators/views_generator_test.rb +2 -0
- data/test/helpers/devise_helper_test.rb +2 -0
- data/test/integration/authenticatable_test.rb +10 -2
- data/test/integration/confirmable_test.rb +2 -0
- data/test/integration/database_authenticatable_test.rb +2 -0
- data/test/integration/http_authenticatable_test.rb +8 -0
- data/test/integration/lockable_test.rb +5 -3
- data/test/integration/mounted_engine_test.rb +2 -0
- data/test/integration/omniauthable_test.rb +13 -0
- data/test/integration/recoverable_test.rb +2 -0
- data/test/integration/registerable_test.rb +2 -0
- data/test/integration/rememberable_test.rb +9 -1
- data/test/integration/timeoutable_test.rb +2 -0
- data/test/integration/trackable_test.rb +7 -0
- data/test/mailers/confirmation_instructions_test.rb +2 -0
- data/test/mailers/email_changed_test.rb +132 -0
- data/test/mailers/mailer_test.rb +20 -0
- data/test/mailers/reset_password_instructions_test.rb +2 -0
- data/test/mailers/unlock_instructions_test.rb +2 -0
- data/test/mapping_test.rb +2 -0
- data/test/models/authenticatable_test.rb +2 -0
- data/test/models/confirmable_test.rb +30 -0
- data/test/models/database_authenticatable_test.rb +15 -1
- data/test/models/lockable_test.rb +2 -0
- data/test/models/omniauthable_test.rb +2 -0
- data/test/models/recoverable_test.rb +13 -1
- data/test/models/registerable_test.rb +2 -0
- data/test/models/rememberable_test.rb +2 -0
- data/test/models/serializable_test.rb +6 -0
- data/test/models/timeoutable_test.rb +2 -0
- data/test/models/trackable_test.rb +21 -0
- data/test/models/validatable_test.rb +4 -2
- data/test/models_test.rb +2 -0
- data/test/omniauth/config_test.rb +11 -7
- data/test/omniauth/url_helpers_test.rb +2 -0
- data/test/orm/active_record.rb +9 -2
- data/test/orm/mongoid.rb +3 -1
- data/test/parameter_sanitizer_test.rb +2 -0
- data/test/rails_app/app/active_record/admin.rb +2 -0
- data/test/rails_app/app/active_record/shim.rb +2 -0
- data/test/rails_app/app/active_record/user.rb +14 -1
- data/test/rails_app/app/active_record/user_on_engine.rb +2 -0
- data/test/rails_app/app/active_record/user_on_main_app.rb +2 -0
- data/test/rails_app/app/active_record/user_with_validations.rb +12 -0
- data/test/rails_app/app/active_record/user_without_email.rb +2 -0
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +2 -0
- data/test/rails_app/app/controllers/admins_controller.rb +2 -0
- data/test/rails_app/app/controllers/application_controller.rb +2 -0
- data/test/rails_app/app/controllers/application_with_fake_engine.rb +2 -0
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +2 -0
- data/test/rails_app/app/controllers/home_controller.rb +3 -1
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +3 -1
- data/test/rails_app/app/controllers/users_controller.rb +5 -3
- data/test/rails_app/app/helpers/application_helper.rb +2 -0
- data/test/rails_app/app/mailers/users/from_proc_mailer.rb +2 -0
- data/test/rails_app/app/mailers/users/mailer.rb +2 -0
- data/test/rails_app/app/mailers/users/reply_to_mailer.rb +2 -0
- data/test/rails_app/app/mongoid/admin.rb +2 -0
- data/test/rails_app/app/mongoid/shim.rb +2 -0
- data/test/rails_app/app/mongoid/user.rb +11 -0
- data/test/rails_app/app/mongoid/user_on_engine.rb +2 -0
- data/test/rails_app/app/mongoid/user_on_main_app.rb +2 -0
- data/test/rails_app/app/mongoid/user_with_validations.rb +37 -0
- data/test/rails_app/app/mongoid/user_without_email.rb +2 -0
- data/test/rails_app/config/application.rb +6 -2
- data/test/rails_app/config/boot.rb +16 -3
- data/test/rails_app/config/environment.rb +2 -0
- data/test/rails_app/config/environments/development.rb +2 -0
- data/test/rails_app/config/environments/production.rb +2 -0
- data/test/rails_app/config/environments/test.rb +2 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +2 -0
- data/test/rails_app/config/initializers/devise.rb +2 -0
- data/test/rails_app/config/initializers/inflections.rb +2 -0
- data/test/rails_app/config/initializers/secret_token.rb +2 -0
- data/test/rails_app/config/initializers/session_store.rb +2 -0
- data/test/rails_app/config/routes.rb +2 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -0
- data/test/rails_app/db/schema.rb +2 -0
- data/test/rails_app/lib/shared_admin.rb +7 -1
- data/test/rails_app/lib/shared_user.rb +2 -0
- data/test/rails_app/lib/shared_user_without_email.rb +2 -0
- data/test/rails_app/lib/shared_user_without_omniauth.rb +2 -0
- data/test/rails_test.rb +2 -0
- data/test/routes_test.rb +7 -5
- data/test/secret_key_finder_test.rb +97 -0
- data/test/support/action_controller/record_identifier.rb +2 -0
- data/test/support/assertions.rb +2 -0
- data/test/support/helpers.rb +6 -0
- data/test/support/http_method_compatibility.rb +2 -0
- data/test/support/integration.rb +3 -0
- data/test/support/webrat/integrations/rails.rb +2 -0
- data/test/test/controller_helpers_test.rb +16 -1
- data/test/test/integration_helpers_test.rb +2 -0
- data/test/test_helper.rb +2 -0
- data/test/test_models.rb +2 -0
- metadata +23 -5
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Controllers
|
3
5
|
# Provide sign in and sign out functionality.
|
4
6
|
# Included by default in all controllers.
|
5
7
|
module SignInOut
|
6
8
|
# Return true if the given scope is signed in session. If no scope given, return
|
7
|
-
# true if any scope is signed in.
|
9
|
+
# true if any scope is signed in. This will run authentication hooks, which may
|
10
|
+
# cause exceptions to be thrown from this method; if you simply want to check
|
11
|
+
# if a scope has already previously been authenticated without running
|
12
|
+
# authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
|
8
13
|
def signed_in?(scope=nil)
|
9
14
|
[scope || Devise.mappings.keys].flatten.any? do |_scope|
|
10
15
|
warden.authenticate?(scope: _scope)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "uri"
|
2
4
|
|
3
5
|
module Devise
|
@@ -29,16 +31,13 @@ module Devise
|
|
29
31
|
# Example:
|
30
32
|
#
|
31
33
|
# store_location_for(:user, dashboard_path)
|
32
|
-
# redirect_to
|
34
|
+
# redirect_to user_facebook_omniauth_authorize_path
|
33
35
|
#
|
34
36
|
def store_location_for(resource_or_scope, location)
|
35
37
|
session_key = stored_location_key_for(resource_or_scope)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
path = [path, uri.fragment].compact.join('#')
|
40
|
-
session[session_key] = path
|
41
|
-
end
|
38
|
+
|
39
|
+
path = extract_path_from_location(location)
|
40
|
+
session[session_key] = path if path
|
42
41
|
end
|
43
42
|
|
44
43
|
private
|
@@ -53,6 +52,25 @@ module Devise
|
|
53
52
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
54
53
|
"#{scope}_return_to"
|
55
54
|
end
|
55
|
+
|
56
|
+
def extract_path_from_location(location)
|
57
|
+
uri = parse_uri(location)
|
58
|
+
|
59
|
+
if uri
|
60
|
+
path = remove_domain_from_uri(uri)
|
61
|
+
path = add_fragment_back_to_path(uri, path)
|
62
|
+
|
63
|
+
path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def remove_domain_from_uri(uri)
|
68
|
+
[uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_fragment_back_to_path(uri, path)
|
72
|
+
[path, uri.fragment].compact.join('#')
|
73
|
+
end
|
56
74
|
end
|
57
75
|
end
|
58
76
|
end
|
data/lib/devise/delegator.rb
CHANGED
data/lib/devise/encryptor.rb
CHANGED
data/lib/devise/failure_app.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_controller/metal"
|
2
4
|
|
3
5
|
module Devise
|
4
6
|
# Failure application that will be called every time :warden is thrown from
|
5
|
-
# any strategy or hook.
|
6
|
-
# page based on current scope and mapping. If no scope is given,
|
7
|
-
# to the default_url.
|
7
|
+
# any strategy or hook. It is responsible for redirecting the user to the sign
|
8
|
+
# in page based on current scope and mapping. If no scope is given, it
|
9
|
+
# redirects to the default_url.
|
8
10
|
class FailureApp < ActionController::Metal
|
9
11
|
include ActionController::UrlFor
|
10
12
|
include ActionController::Redirecting
|
@@ -160,12 +162,12 @@ module Devise
|
|
160
162
|
%w(html */*).include? request_format.to_s
|
161
163
|
end
|
162
164
|
|
163
|
-
# Choose whether we should respond in
|
165
|
+
# Choose whether we should respond in an HTTP authentication fashion,
|
164
166
|
# including 401 and optional headers.
|
165
167
|
#
|
166
|
-
# This method allows the user to explicitly disable
|
167
|
-
# on
|
168
|
-
# handling the errors on their own. This is useful in case your
|
168
|
+
# This method allows the user to explicitly disable HTTP authentication
|
169
|
+
# on AJAX requests in case they want to redirect on failures instead of
|
170
|
+
# handling the errors on their own. This is useful in case your AJAX API
|
169
171
|
# is the same as your public API and uses a format like JSON (so you
|
170
172
|
# cannot mark JSON as a navigational format).
|
171
173
|
def http_auth?
|
@@ -176,7 +178,7 @@ module Devise
|
|
176
178
|
end
|
177
179
|
end
|
178
180
|
|
179
|
-
# It
|
181
|
+
# It doesn't make sense to send authenticate headers in AJAX requests
|
180
182
|
# or if the user disabled them.
|
181
183
|
def http_auth_header?
|
182
184
|
scope_class.http_authenticatable && !request.xhr?
|
@@ -225,10 +227,10 @@ module Devise
|
|
225
227
|
warden_options[:attempted_path]
|
226
228
|
end
|
227
229
|
|
228
|
-
# Stores requested
|
229
|
-
# scoped session provided by warden here, since the user is not
|
230
|
-
# yet, but we still need to store the
|
231
|
-
# would never use the same
|
230
|
+
# Stores requested URI to redirect the user after signing in. We can't use
|
231
|
+
# the scoped session provided by warden here, since the user is not
|
232
|
+
# authenticated yet, but we still need to store the URI based on scope, so
|
233
|
+
# different scopes would never use the same URI to redirect.
|
232
234
|
def store_location!
|
233
235
|
store_location_for(scope, attempted_path) if request.get? && !http_auth?
|
234
236
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# After each sign in, if resource responds to failed_attempts, sets it to 0
|
2
4
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
5
|
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
4
6
|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
|
5
|
-
|
7
|
+
unless record.failed_attempts.to_i.zero?
|
8
|
+
record.failed_attempts = 0
|
9
|
+
record.save(validate: false)
|
10
|
+
end
|
6
11
|
end
|
7
12
|
end
|
data/lib/devise/hooks/proxy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Mailers
|
3
5
|
module Helpers
|
@@ -5,15 +7,16 @@ module Devise
|
|
5
7
|
|
6
8
|
included do
|
7
9
|
include Devise::Controllers::ScopedViews
|
8
|
-
attr_reader :scope_name, :resource
|
9
10
|
end
|
10
11
|
|
11
12
|
protected
|
12
13
|
|
14
|
+
attr_reader :scope_name, :resource
|
15
|
+
|
13
16
|
# Configure default email options
|
14
|
-
def devise_mail(record, action, opts={})
|
17
|
+
def devise_mail(record, action, opts = {}, &block)
|
15
18
|
initialize_from_record(record)
|
16
|
-
mail headers_for(action, opts)
|
19
|
+
mail headers_for(action, opts), &block
|
17
20
|
end
|
18
21
|
|
19
22
|
def initialize_from_record(record)
|
data/lib/devise/mapping.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_model/version'
|
2
4
|
require 'devise/hooks/activatable'
|
3
5
|
require 'devise/hooks/csrf_cleaner'
|
@@ -102,7 +104,7 @@ module Devise
|
|
102
104
|
# and passing a new list of attributes you want to exempt. All attributes
|
103
105
|
# given to :except will simply add names to exempt to Devise internal list.
|
104
106
|
def serializable_hash(options = nil)
|
105
|
-
options
|
107
|
+
options = options.try(:dup) || {}
|
106
108
|
options[:except] = Array(options[:except])
|
107
109
|
|
108
110
|
if options[:force_except]
|
@@ -256,7 +258,7 @@ module Devise
|
|
256
258
|
# end
|
257
259
|
#
|
258
260
|
# Finally, notice that Devise also queries for users in other scenarios
|
259
|
-
# besides authentication, for example when retrieving
|
261
|
+
# besides authentication, for example when retrieving a user to send
|
260
262
|
# an e-mail for password reset. In such cases, find_for_authentication
|
261
263
|
# is not called.
|
262
264
|
def find_for_authentication(tainted_conditions)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Models
|
3
5
|
# Confirmable is responsible to verify if an account is already confirmed to
|
@@ -26,7 +28,9 @@ module Devise
|
|
26
28
|
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
27
29
|
# db field to be set up (t.reconfirmable in migrations). Until confirmed, new email is
|
28
30
|
# stored in unconfirmed email column, and copied to email column on successful
|
29
|
-
# confirmation.
|
31
|
+
# confirmation. Also, when used in conjunction with `send_email_changed_notification`,
|
32
|
+
# the notification is sent to the original email when the change is requested,
|
33
|
+
# not when the unconfirmed email is confirmed.
|
30
34
|
# * +confirm_within+: the time before a sent confirmation token becomes invalid.
|
31
35
|
# You can use this to force the user to confirm within a set period of time.
|
32
36
|
# Confirmable will not generate a new token if a repeat confirmation is requested
|
@@ -44,7 +48,7 @@ module Devise
|
|
44
48
|
included do
|
45
49
|
before_create :generate_confirmation_token, if: :confirmation_required?
|
46
50
|
after_create :skip_reconfirmation_in_callback!, if: :send_confirmation_notification?
|
47
|
-
if
|
51
|
+
if defined?(ActiveRecord) && self < ActiveRecord::Base # ActiveRecord
|
48
52
|
after_commit :send_on_create_confirmation_instructions, on: :create, if: :send_confirmation_notification?
|
49
53
|
after_commit :send_reconfirmation_instructions, on: :update, if: :reconfirmation_required?
|
50
54
|
else # Mongoid
|
@@ -223,7 +227,7 @@ module Devise
|
|
223
227
|
# confirmation_period_expired? # will always return false
|
224
228
|
#
|
225
229
|
def confirmation_period_expired?
|
226
|
-
self.class.confirm_within && self.confirmation_sent_at && (Time.now > self.confirmation_sent_at + self.class.confirm_within)
|
230
|
+
self.class.confirm_within && self.confirmation_sent_at && (Time.now.utc > self.confirmation_sent_at.utc + self.class.confirm_within)
|
227
231
|
end
|
228
232
|
|
229
233
|
# Checks whether the record requires any confirmation.
|
@@ -251,22 +255,44 @@ module Devise
|
|
251
255
|
generate_confirmation_token && save(validate: false)
|
252
256
|
end
|
253
257
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
258
|
+
if Devise.activerecord51?
|
259
|
+
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
|
260
|
+
@reconfirmation_required = true
|
261
|
+
self.unconfirmed_email = self.email
|
262
|
+
self.email = self.email_in_database
|
263
|
+
self.confirmation_token = nil
|
264
|
+
generate_confirmation_token
|
265
|
+
end
|
266
|
+
else
|
267
|
+
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
|
268
|
+
@reconfirmation_required = true
|
269
|
+
self.unconfirmed_email = self.email
|
270
|
+
self.email = self.email_was
|
271
|
+
self.confirmation_token = nil
|
272
|
+
generate_confirmation_token
|
273
|
+
end
|
260
274
|
end
|
261
275
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
276
|
+
if Devise.activerecord51?
|
277
|
+
def postpone_email_change?
|
278
|
+
postpone = self.class.reconfirmable &&
|
279
|
+
will_save_change_to_email? &&
|
280
|
+
!@bypass_confirmation_postpone &&
|
281
|
+
self.email.present? &&
|
282
|
+
(!@skip_reconfirmation_in_callback || !self.email_in_database.nil?)
|
283
|
+
@bypass_confirmation_postpone = false
|
284
|
+
postpone
|
285
|
+
end
|
286
|
+
else
|
287
|
+
def postpone_email_change?
|
288
|
+
postpone = self.class.reconfirmable &&
|
289
|
+
email_changed? &&
|
290
|
+
!@bypass_confirmation_postpone &&
|
291
|
+
self.email.present? &&
|
292
|
+
(!@skip_reconfirmation_in_callback || !self.email_was.nil?)
|
293
|
+
@bypass_confirmation_postpone = false
|
294
|
+
postpone
|
295
|
+
end
|
270
296
|
end
|
271
297
|
|
272
298
|
def reconfirmation_required?
|
@@ -277,6 +303,16 @@ module Devise
|
|
277
303
|
confirmation_required? && !@skip_confirmation_notification && self.email.present?
|
278
304
|
end
|
279
305
|
|
306
|
+
# With reconfirmable, notify the original email when the user first
|
307
|
+
# requests the email change, instead of when the change is confirmed.
|
308
|
+
def send_email_changed_notification?
|
309
|
+
if self.class.reconfirmable
|
310
|
+
self.class.send_email_changed_notification && reconfirmation_required?
|
311
|
+
else
|
312
|
+
super
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
280
316
|
# A callback initiated after successfully confirming. This can be
|
281
317
|
# used to insert your own logic that is only run after the user successfully
|
282
318
|
# confirms.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'devise/strategies/database_authenticatable'
|
2
4
|
|
3
5
|
module Devise
|
@@ -10,10 +12,14 @@ module Devise
|
|
10
12
|
# DatabaseAuthenticatable adds the following options to devise_for:
|
11
13
|
#
|
12
14
|
# * +pepper+: a random string used to provide a more secure hash. Use
|
13
|
-
# `
|
15
|
+
# `rails secret` to generate new keys.
|
14
16
|
#
|
15
17
|
# * +stretches+: the cost given to bcrypt.
|
16
18
|
#
|
19
|
+
# * +send_email_changed_notification+: notify original email when it changes.
|
20
|
+
#
|
21
|
+
# * +send_password_change_notification+: notify email when password changes.
|
22
|
+
#
|
17
23
|
# == Examples
|
18
24
|
#
|
19
25
|
# User.find(1).valid_password?('password123') # returns true/false
|
@@ -22,6 +28,7 @@ module Devise
|
|
22
28
|
extend ActiveSupport::Concern
|
23
29
|
|
24
30
|
included do
|
31
|
+
after_update :send_email_changed_notification, if: :send_email_changed_notification?
|
25
32
|
after_update :send_password_change_notification, if: :send_password_change_notification?
|
26
33
|
|
27
34
|
attr_reader :password, :current_password
|
@@ -132,6 +139,19 @@ module Devise
|
|
132
139
|
encrypted_password[0,29] if encrypted_password
|
133
140
|
end
|
134
141
|
|
142
|
+
if Devise.activerecord51?
|
143
|
+
# Send notification to user when email changes.
|
144
|
+
def send_email_changed_notification
|
145
|
+
send_devise_notification(:email_changed, to: email_before_last_save)
|
146
|
+
end
|
147
|
+
else
|
148
|
+
# Send notification to user when email changes.
|
149
|
+
def send_email_changed_notification
|
150
|
+
send_devise_notification(:email_changed, to: email_was)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Send notification to user when password changes.
|
135
155
|
def send_password_change_notification
|
136
156
|
send_devise_notification(:password_change)
|
137
157
|
end
|
@@ -147,12 +167,28 @@ module Devise
|
|
147
167
|
Devise::Encryptor.digest(self.class, password)
|
148
168
|
end
|
149
169
|
|
150
|
-
|
151
|
-
|
170
|
+
if Devise.activerecord51?
|
171
|
+
def send_email_changed_notification?
|
172
|
+
self.class.send_email_changed_notification && saved_change_to_email?
|
173
|
+
end
|
174
|
+
else
|
175
|
+
def send_email_changed_notification?
|
176
|
+
self.class.send_email_changed_notification && email_changed?
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
if Devise.activerecord51?
|
181
|
+
def send_password_change_notification?
|
182
|
+
self.class.send_password_change_notification && saved_change_to_encrypted_password?
|
183
|
+
end
|
184
|
+
else
|
185
|
+
def send_password_change_notification?
|
186
|
+
self.class.send_password_change_notification && encrypted_password_changed?
|
187
|
+
end
|
152
188
|
end
|
153
189
|
|
154
190
|
module ClassMethods
|
155
|
-
Devise::Models.config(self, :pepper, :stretches, :send_password_change_notification)
|
191
|
+
Devise::Models.config(self, :pepper, :stretches, :send_email_changed_notification, :send_password_change_notification)
|
156
192
|
|
157
193
|
# We assume this method already gets the sanitized values from the
|
158
194
|
# DatabaseAuthenticatable strategy. If you are using this method on
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "devise/hooks/lockable"
|
2
4
|
|
3
5
|
module Devise
|
@@ -99,8 +101,7 @@ module Devise
|
|
99
101
|
if super && !access_locked?
|
100
102
|
true
|
101
103
|
else
|
102
|
-
|
103
|
-
self.failed_attempts += 1
|
104
|
+
increment_failed_attempts
|
104
105
|
if attempts_exceeded?
|
105
106
|
lock_access! unless access_locked?
|
106
107
|
else
|
@@ -109,6 +110,11 @@ module Devise
|
|
109
110
|
false
|
110
111
|
end
|
111
112
|
end
|
113
|
+
|
114
|
+
def increment_failed_attempts
|
115
|
+
self.failed_attempts ||= 0
|
116
|
+
self.failed_attempts += 1
|
117
|
+
end
|
112
118
|
|
113
119
|
def unauthenticated_message
|
114
120
|
# If set to paranoid mode, do not show the locked message because it
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Models
|
3
5
|
|
@@ -33,10 +35,14 @@ module Devise
|
|
33
35
|
# Update password saving the record and clearing token. Returns true if
|
34
36
|
# the passwords are valid and the record was saved, false otherwise.
|
35
37
|
def reset_password(new_password, new_password_confirmation)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
if new_password.present?
|
39
|
+
self.password = new_password
|
40
|
+
self.password_confirmation = new_password_confirmation
|
41
|
+
save
|
42
|
+
else
|
43
|
+
errors.add(:password, :blank)
|
44
|
+
false
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
# Resets reset password token and send reset password instructions by email.
|
@@ -93,13 +99,24 @@ module Devise
|
|
93
99
|
send_devise_notification(:reset_password_instructions, token, {})
|
94
100
|
end
|
95
101
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
102
|
+
if Devise.activerecord51?
|
103
|
+
def clear_reset_password_token?
|
104
|
+
encrypted_password_changed = respond_to?(:will_save_change_to_encrypted_password?) && will_save_change_to_encrypted_password?
|
105
|
+
authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
|
106
|
+
respond_to?("will_save_change_to_#{attribute}?") && send("will_save_change_to_#{attribute}?")
|
107
|
+
end
|
108
|
+
|
109
|
+
authentication_keys_changed || encrypted_password_changed
|
100
110
|
end
|
111
|
+
else
|
112
|
+
def clear_reset_password_token?
|
113
|
+
encrypted_password_changed = respond_to?(:encrypted_password_changed?) && encrypted_password_changed?
|
114
|
+
authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
|
115
|
+
respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?")
|
116
|
+
end
|
101
117
|
|
102
|
-
|
118
|
+
authentication_keys_changed || encrypted_password_changed
|
119
|
+
end
|
103
120
|
end
|
104
121
|
|
105
122
|
module ClassMethods
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'devise/strategies/rememberable'
|
2
4
|
require 'devise/hooks/rememberable'
|
3
5
|
require 'devise/hooks/forgetable'
|
4
6
|
|
5
7
|
module Devise
|
6
8
|
module Models
|
7
|
-
# Rememberable manages generating and clearing token for
|
9
|
+
# Rememberable manages generating and clearing token for remembering the user
|
8
10
|
# from a saved cookie. Rememberable also has utility methods for dealing
|
9
11
|
# with serializing the user into the cookie and back from the cookie, trying
|
10
12
|
# to lookup the record based on the saved information.
|
@@ -74,7 +76,7 @@ module Devise
|
|
74
76
|
elsif respond_to?(:authenticatable_salt) && (salt = authenticatable_salt.presence)
|
75
77
|
salt
|
76
78
|
else
|
77
|
-
raise "
|
79
|
+
raise "authenticatable_salt returned nil for the #{self.class.name} model. " \
|
78
80
|
"In order to use rememberable, you must ensure a password is always set " \
|
79
81
|
"or have a remember_token column in your model or implement your own " \
|
80
82
|
"rememberable_value in the model with custom logic."
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'devise/hooks/trackable'
|
2
4
|
|
3
5
|
module Devise
|
@@ -29,6 +31,11 @@ module Devise
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def update_tracked_fields!(request)
|
34
|
+
# We have to check if the user is already persisted before running
|
35
|
+
# `save` here because invalid users can be saved if we don't.
|
36
|
+
# See https://github.com/plataformatec/devise/issues/4673 for more details.
|
37
|
+
return if new_record?
|
38
|
+
|
32
39
|
update_tracked_fields(request)
|
33
40
|
save(validate: false)
|
34
41
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Models
|
3
5
|
# Validatable creates all needed validations for a user email and password.
|
@@ -10,7 +12,7 @@ module Devise
|
|
10
12
|
# Validatable adds the following options to devise_for:
|
11
13
|
#
|
12
14
|
# * +email_regexp+: the regular expression used to validate e-mails;
|
13
|
-
# * +password_length+: a range expressing password length. Defaults to
|
15
|
+
# * +password_length+: a range expressing password length. Defaults to 6..128.
|
14
16
|
#
|
15
17
|
module Validatable
|
16
18
|
# All validations used by this module.
|
@@ -27,8 +29,13 @@ module Devise
|
|
27
29
|
|
28
30
|
base.class_eval do
|
29
31
|
validates_presence_of :email, if: :email_required?
|
30
|
-
|
31
|
-
|
32
|
+
if Devise.activerecord51?
|
33
|
+
validates_uniqueness_of :email, allow_blank: true, if: :will_save_change_to_email?
|
34
|
+
validates_format_of :email, with: email_regexp, allow_blank: true, if: :will_save_change_to_email?
|
35
|
+
else
|
36
|
+
validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
|
37
|
+
validates_format_of :email, with: email_regexp, allow_blank: true, if: :email_changed?
|
38
|
+
end
|
32
39
|
|
33
40
|
validates_presence_of :password, if: :password_required?
|
34
41
|
validates_confirmation_of :password, if: :password_required?
|