devise 4.6.0 → 4.9.4

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.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +122 -3
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +108 -61
  5. data/app/controllers/devise/confirmations_controller.rb +1 -0
  6. data/app/controllers/devise/passwords_controller.rb +2 -2
  7. data/app/controllers/devise/registrations_controller.rb +1 -1
  8. data/app/controllers/devise/sessions_controller.rb +2 -2
  9. data/app/controllers/devise/unlocks_controller.rb +1 -0
  10. data/app/controllers/devise_controller.rb +16 -2
  11. data/app/helpers/devise_helper.rb +19 -7
  12. data/app/mailers/devise/mailer.rb +5 -5
  13. data/app/views/devise/passwords/edit.html.erb +1 -1
  14. data/app/views/devise/registrations/edit.html.erb +1 -1
  15. data/app/views/devise/shared/_error_messages.html.erb +1 -1
  16. data/app/views/devise/shared/_links.html.erb +1 -1
  17. data/config/locales/en.yml +3 -3
  18. data/lib/devise/controllers/helpers.rb +9 -7
  19. data/lib/devise/controllers/responder.rb +35 -0
  20. data/lib/devise/controllers/sign_in_out.rb +7 -5
  21. data/lib/devise/controllers/url_helpers.rb +1 -1
  22. data/lib/devise/failure_app.rb +22 -16
  23. data/lib/devise/hooks/csrf_cleaner.rb +6 -1
  24. data/lib/devise/hooks/lockable.rb +2 -5
  25. data/lib/devise/hooks/timeoutable.rb +2 -2
  26. data/lib/devise/mapping.rb +1 -1
  27. data/lib/devise/models/authenticatable.rb +13 -9
  28. data/lib/devise/models/confirmable.rb +30 -39
  29. data/lib/devise/models/database_authenticatable.rb +18 -34
  30. data/lib/devise/models/lockable.rb +11 -3
  31. data/lib/devise/models/omniauthable.rb +2 -2
  32. data/lib/devise/models/recoverable.rb +8 -19
  33. data/lib/devise/models/rememberable.rb +2 -2
  34. data/lib/devise/models/timeoutable.rb +1 -1
  35. data/lib/devise/models/trackable.rb +1 -1
  36. data/lib/devise/models/validatable.rb +4 -9
  37. data/lib/devise/models.rb +1 -0
  38. data/lib/devise/omniauth.rb +2 -5
  39. data/lib/devise/orm.rb +71 -0
  40. data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
  41. data/lib/devise/rails/routes.rb +6 -6
  42. data/lib/devise/rails.rb +4 -0
  43. data/lib/devise/strategies/authenticatable.rb +1 -1
  44. data/lib/devise/test/controller_helpers.rb +4 -2
  45. data/lib/devise/test/integration_helpers.rb +1 -1
  46. data/lib/devise/test_helpers.rb +1 -1
  47. data/lib/devise/version.rb +1 -1
  48. data/lib/devise.rb +35 -12
  49. data/lib/generators/active_record/devise_generator.rb +17 -2
  50. data/lib/generators/devise/devise_generator.rb +1 -1
  51. data/lib/generators/devise/install_generator.rb +1 -5
  52. data/lib/generators/devise/views_generator.rb +1 -1
  53. data/lib/generators/templates/README +9 -1
  54. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +1 -1
  55. data/lib/generators/templates/devise.rb +25 -11
  56. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -1
  57. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +1 -1
  58. metadata +21 -16
@@ -7,9 +7,13 @@ module Devise
7
7
  # Authenticatable Module, responsible for hashing the password and
8
8
  # validating the authenticity of a user while signing in.
9
9
  #
10
+ # This module defines a `password=` method. This method will hash the argument
11
+ # and store it in the `encrypted_password` column, bypassing any pre-existing
12
+ # `password` column if it exists.
13
+ #
10
14
  # == Options
11
15
  #
12
- # DatabaseAuthenticatable adds the following options to devise_for:
16
+ # DatabaseAuthenticatable adds the following options to +devise+:
13
17
  #
14
18
  # * +pepper+: a random string used to provide a more secure hash. Use
15
19
  # `rails secret` to generate new keys.
@@ -38,7 +42,7 @@ module Devise
38
42
  def initialize(*args, &block)
39
43
  @skip_email_changed_notification = false
40
44
  @skip_password_change_notification = false
41
- super
45
+ super
42
46
  end
43
47
 
44
48
  # Skips sending the email changed notification after_update
@@ -60,7 +64,7 @@ module Devise
60
64
  # the hashed password.
61
65
  def password=(new_password)
62
66
  @password = new_password
63
- self.encrypted_password = password_digest(@password)
67
+ self.encrypted_password = password_digest(@password) if @password.present?
64
68
  end
65
69
 
66
70
  # Verifies whether a password (ie from sign in) is the user password.
@@ -70,7 +74,7 @@ module Devise
70
74
 
71
75
  # Set password and password confirmation to nil
72
76
  def clean_up_passwords
73
- @password = @password_confirmation = nil
77
+ self.password = self.password_confirmation = nil
74
78
  end
75
79
 
76
80
  # Update record attributes when :current_password matches, otherwise
@@ -82,7 +86,7 @@ module Devise
82
86
  # is also rejected as long as it is also blank.
83
87
  def update_with_password(params, *options)
84
88
  if options.present?
85
- ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
89
+ Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
86
90
  [Devise] The second argument of `DatabaseAuthenticatable#update_with_password`
87
91
  (`options`) is deprecated and it will be removed in the next major version.
88
92
  It was added to support a feature deprecated in Rails 4, so you can safely remove it
@@ -124,7 +128,7 @@ module Devise
124
128
  #
125
129
  def update_without_password(params, *options)
126
130
  if options.present?
127
- ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
131
+ Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
128
132
  [Devise] The second argument of `DatabaseAuthenticatable#update_without_password`
129
133
  (`options`) is deprecated and it will be removed in the next major version.
130
134
  It was added to support a feature deprecated in Rails 4, so you can safely remove it
@@ -173,16 +177,9 @@ module Devise
173
177
  encrypted_password[0,29] if encrypted_password
174
178
  end
175
179
 
176
- if Devise.activerecord51?
177
- # Send notification to user when email changes.
178
- def send_email_changed_notification
179
- send_devise_notification(:email_changed, to: email_before_last_save)
180
- end
181
- else
182
- # Send notification to user when email changes.
183
- def send_email_changed_notification
184
- send_devise_notification(:email_changed, to: email_was)
185
- end
180
+ # Send notification to user when email changes.
181
+ def send_email_changed_notification
182
+ send_devise_notification(:email_changed, to: devise_email_before_last_save)
186
183
  end
187
184
 
188
185
  # Send notification to user when password changes.
@@ -195,31 +192,18 @@ module Devise
195
192
  # Hashes the password using bcrypt. Custom hash functions should override
196
193
  # this method to apply their own algorithm.
197
194
  #
198
- # See https://github.com/plataformatec/devise-encryptable for examples
195
+ # See https://github.com/heartcombo/devise-encryptable for examples
199
196
  # of other hashing engines.
200
197
  def password_digest(password)
201
- return if password.blank?
202
198
  Devise::Encryptor.digest(self.class, password)
203
199
  end
204
200
 
205
- if Devise.activerecord51?
206
- def send_email_changed_notification?
207
- self.class.send_email_changed_notification && saved_change_to_email? && !@skip_email_changed_notification
208
- end
209
- else
210
- def send_email_changed_notification?
211
- self.class.send_email_changed_notification && email_changed? && !@skip_email_changed_notification
212
- end
201
+ def send_email_changed_notification?
202
+ self.class.send_email_changed_notification && devise_saved_change_to_email? && !@skip_email_changed_notification
213
203
  end
214
204
 
215
- if Devise.activerecord51?
216
- def send_password_change_notification?
217
- self.class.send_password_change_notification && saved_change_to_encrypted_password? && !@skip_password_change_notification
218
- end
219
- else
220
- def send_password_change_notification?
221
- self.class.send_password_change_notification && encrypted_password_changed? && !@skip_password_change_notification
222
- end
205
+ def send_password_change_notification?
206
+ self.class.send_password_change_notification && devise_saved_change_to_encrypted_password? && !@skip_password_change_notification
223
207
  end
224
208
 
225
209
  module ClassMethods
@@ -18,7 +18,7 @@ module Devise
18
18
  # * +maximum_attempts+: how many attempts should be accepted before blocking the user.
19
19
  # * +lock_strategy+: lock the user account by :failed_attempts or :none.
20
20
  # * +unlock_strategy+: unlock the user account by :time, :email, :both or :none.
21
- # * +unlock_in+: the time you want to lock the user after to lock happens. Only available when unlock_strategy is :time or :both.
21
+ # * +unlock_in+: the time you want to unlock the user after lock happens. Only available when unlock_strategy is :time or :both.
22
22
  # * +unlock_keys+: the keys you want to use when locking and unlocking an account
23
23
  #
24
24
  module Lockable
@@ -57,6 +57,14 @@ module Devise
57
57
  save(validate: false)
58
58
  end
59
59
 
60
+ # Resets failed attempts counter to 0.
61
+ def reset_failed_attempts!
62
+ if respond_to?(:failed_attempts) && !failed_attempts.to_i.zero?
63
+ self.failed_attempts = 0
64
+ save(validate: false)
65
+ end
66
+ end
67
+
60
68
  # Verifies whether a user is locked or not.
61
69
  def access_locked?
62
70
  !!locked_at && !lock_expired?
@@ -110,7 +118,7 @@ module Devise
110
118
  false
111
119
  end
112
120
  end
113
-
121
+
114
122
  def increment_failed_attempts
115
123
  self.class.increment_counter(:failed_attempts, id)
116
124
  reload
@@ -168,7 +176,7 @@ module Devise
168
176
  # unlock instructions to it. If not user is found, returns a new user
169
177
  # with an email not found error.
170
178
  # Options must contain the user's unlock keys
171
- def send_unlock_instructions(attributes={})
179
+ def send_unlock_instructions(attributes = {})
172
180
  lockable = find_or_initialize_with_errors(unlock_keys, attributes, :not_found)
173
181
  lockable.resend_unlock_instructions if lockable.persisted?
174
182
  lockable
@@ -8,11 +8,11 @@ module Devise
8
8
  #
9
9
  # == Options
10
10
  #
11
- # Oauthable adds the following options to devise_for:
11
+ # Oauthable adds the following options to +devise+:
12
12
  #
13
13
  # * +omniauth_providers+: Which providers are available to this model. It expects an array:
14
14
  #
15
- # devise_for :database_authenticatable, :omniauthable, omniauth_providers: [:twitter]
15
+ # devise :database_authenticatable, :omniauthable, omniauth_providers: [:twitter]
16
16
  #
17
17
  module Omniauthable
18
18
  extend ActiveSupport::Concern
@@ -7,7 +7,7 @@ module Devise
7
7
  #
8
8
  # ==Options
9
9
  #
10
- # Recoverable adds the following options to devise_for:
10
+ # Recoverable adds the following options to +devise+:
11
11
  #
12
12
  # * +reset_password_keys+: the keys you want to use when recovering the password for an account
13
13
  # * +reset_password_within+: the time period within which the password must be reset or the token expires.
@@ -99,24 +99,13 @@ module Devise
99
99
  send_devise_notification(:reset_password_instructions, token, {})
100
100
  end
101
101
 
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
102
+ def clear_reset_password_token?
103
+ encrypted_password_changed = devise_respond_to_and_will_save_change_to_attribute?(:encrypted_password)
104
+ authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
105
+ devise_respond_to_and_will_save_change_to_attribute?(attribute)
110
106
  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
117
107
 
118
- authentication_keys_changed || encrypted_password_changed
119
- end
108
+ authentication_keys_changed || encrypted_password_changed
120
109
  end
121
110
 
122
111
  module ClassMethods
@@ -131,7 +120,7 @@ module Devise
131
120
  # password instructions to it. If user is not found, returns a new user
132
121
  # with an email not found error.
133
122
  # Attributes must contain the user's email
134
- def send_reset_password_instructions(attributes={})
123
+ def send_reset_password_instructions(attributes = {})
135
124
  recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
136
125
  recoverable.send_reset_password_instructions if recoverable.persisted?
137
126
  recoverable
@@ -142,7 +131,7 @@ module Devise
142
131
  # try saving the record. If not user is found, returns a new user
143
132
  # containing an error in reset_password_token attribute.
144
133
  # Attributes must contain reset_password_token, password and confirmation
145
- def reset_password_by_token(attributes={})
134
+ def reset_password_by_token(attributes = {})
146
135
  original_token = attributes[:reset_password_token]
147
136
  reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
148
137
 
@@ -15,7 +15,7 @@ module Devise
15
15
  #
16
16
  # == Options
17
17
  #
18
- # Rememberable adds the following options in devise_for:
18
+ # Rememberable adds the following options to +devise+:
19
19
  #
20
20
  # * +remember_for+: the time you want the user will be remembered without
21
21
  # asking for credentials. After this time the user will be blocked and
@@ -102,7 +102,7 @@ module Devise
102
102
 
103
103
  def remember_me?(token, generated_at)
104
104
  # TODO: Normalize the JSON type coercion along with the Timeoutable hook
105
- # in a single place https://github.com/plataformatec/devise/blob/ffe9d6d406e79108cf32a2c6a1d0b3828849c40b/lib/devise/hooks/timeoutable.rb#L14-L18
105
+ # in a single place https://github.com/heartcombo/devise/blob/ffe9d6d406e79108cf32a2c6a1d0b3828849c40b/lib/devise/hooks/timeoutable.rb#L14-L18
106
106
  if generated_at.is_a?(String)
107
107
  generated_at = time_from_json(generated_at)
108
108
  end
@@ -11,7 +11,7 @@ module Devise
11
11
  #
12
12
  # == Options
13
13
  #
14
- # Timeoutable adds the following options to devise_for:
14
+ # Timeoutable adds the following options to +devise+:
15
15
  #
16
16
  # * +timeout_in+: the interval to timeout the user session without activity.
17
17
  #
@@ -33,7 +33,7 @@ module Devise
33
33
  def update_tracked_fields!(request)
34
34
  # We have to check if the user is already persisted before running
35
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.
36
+ # See https://github.com/heartcombo/devise/issues/4673 for more details.
37
37
  return if new_record?
38
38
 
39
39
  update_tracked_fields(request)
@@ -9,7 +9,7 @@ module Devise
9
9
  #
10
10
  # == Options
11
11
  #
12
- # Validatable adds the following options to devise_for:
12
+ # Validatable adds the following options to +devise+:
13
13
  #
14
14
  # * +email_regexp+: the regular expression used to validate e-mails;
15
15
  # * +password_length+: a range expressing password length. Defaults to 6..128.
@@ -29,13 +29,8 @@ module Devise
29
29
 
30
30
  base.class_eval do
31
31
  validates_presence_of :email, if: :email_required?
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
+ validates_uniqueness_of :email, allow_blank: true, case_sensitive: true, if: :devise_will_save_change_to_email?
33
+ validates_format_of :email, with: email_regexp, allow_blank: true, if: :devise_will_save_change_to_email?
39
34
 
40
35
  validates_presence_of :password, if: :password_required?
41
36
  validates_confirmation_of :password, if: :password_required?
@@ -47,7 +42,7 @@ module Devise
47
42
  unavailable_validations = VALIDATIONS.select { |v| !base.respond_to?(v) }
48
43
 
49
44
  unless unavailable_validations.empty?
50
- raise "Could not use :validatable module since #{base} does not respond " <<
45
+ raise "Could not use :validatable module since #{base} does not respond " \
51
46
  "to the following methods: #{unavailable_validations.to_sentence}."
52
47
  end
53
48
  end
data/lib/devise/models.rb CHANGED
@@ -84,6 +84,7 @@ module Devise
84
84
  end
85
85
 
86
86
  devise_modules_hook! do
87
+ include Devise::Orm
87
88
  include Devise::Models::Authenticatable
88
89
 
89
90
  selected_modules.each do |m|
@@ -1,17 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  begin
4
+ gem "omniauth", ">= 1.0.0"
5
+
4
6
  require "omniauth"
5
- require "omniauth/version"
6
7
  rescue LoadError
7
8
  warn "Could not load 'omniauth'. Please ensure you have the omniauth gem >= 1.0.0 installed and listed in your Gemfile."
8
9
  raise
9
10
  end
10
11
 
11
- unless OmniAuth::VERSION =~ /^1\./
12
- raise "You are using an old OmniAuth version, please ensure you have 1.0.0.pr2 version or later installed."
13
- end
14
-
15
12
  # Clean up the default path_prefix. It will be automatically set by Devise.
16
13
  OmniAuth.config.path_prefix = nil
17
14
 
data/lib/devise/orm.rb ADDED
@@ -0,0 +1,71 @@
1
+ module Devise
2
+ module Orm # :nodoc:
3
+ def self.active_record?(model)
4
+ defined?(ActiveRecord) && model < ActiveRecord::Base
5
+ end
6
+
7
+ def self.active_record_51?(model)
8
+ active_record?(model) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
9
+ end
10
+
11
+ def self.included(model)
12
+ if Devise::Orm.active_record_51?(model)
13
+ model.include DirtyTrackingNewMethods
14
+ else
15
+ model.include DirtyTrackingOldMethods
16
+ end
17
+ end
18
+
19
+ module DirtyTrackingNewMethods
20
+ def devise_email_before_last_save
21
+ email_before_last_save
22
+ end
23
+
24
+ def devise_email_in_database
25
+ email_in_database
26
+ end
27
+
28
+ def devise_saved_change_to_email?
29
+ saved_change_to_email?
30
+ end
31
+
32
+ def devise_saved_change_to_encrypted_password?
33
+ saved_change_to_encrypted_password?
34
+ end
35
+
36
+ def devise_will_save_change_to_email?
37
+ will_save_change_to_email?
38
+ end
39
+
40
+ def devise_respond_to_and_will_save_change_to_attribute?(attribute)
41
+ respond_to?("will_save_change_to_#{attribute}?") && send("will_save_change_to_#{attribute}?")
42
+ end
43
+ end
44
+
45
+ module DirtyTrackingOldMethods
46
+ def devise_email_before_last_save
47
+ email_was
48
+ end
49
+
50
+ def devise_email_in_database
51
+ email_was
52
+ end
53
+
54
+ def devise_saved_change_to_email?
55
+ email_changed?
56
+ end
57
+
58
+ def devise_saved_change_to_encrypted_password?
59
+ encrypted_password_changed?
60
+ end
61
+
62
+ def devise_will_save_change_to_email?
63
+ email_changed?
64
+ end
65
+
66
+ def devise_respond_to_and_will_save_change_to_attribute?(attribute)
67
+ respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'active_support/deprecation/constant_accessor'
5
+
6
+ module Devise
7
+ DeprecatedConstantAccessor = ActiveSupport::Deprecation::DeprecatedConstantAccessor #:nodoc:
8
+ end
9
+ rescue LoadError
10
+
11
+ # Copy of constant deprecation module from Rails / Active Support version 6, so we can use it
12
+ # with Rails <= 5.0 versions. This can be removed once we support only Rails 5.1 or greater.
13
+ module Devise
14
+ module DeprecatedConstantAccessor #:nodoc:
15
+ def self.included(base)
16
+ require "active_support/inflector/methods"
17
+
18
+ extension = Module.new do
19
+ def const_missing(missing_const_name)
20
+ if class_variable_defined?(:@@_deprecated_constants)
21
+ if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s])
22
+ replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", Rails::VERSION::MAJOR == 4 ? caller : caller_locations)
23
+ return ActiveSupport::Inflector.constantize(replacement[:new].to_s)
24
+ end
25
+ end
26
+ super
27
+ end
28
+
29
+ def deprecate_constant(const_name, new_constant, message: nil, deprecator: Devise.deprecator)
30
+ class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
31
+ class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator }
32
+ end
33
+ end
34
+ base.singleton_class.prepend extension
35
+ end
36
+ end
37
+ end
38
+
39
+ end
@@ -135,10 +135,10 @@ module ActionDispatch::Routing
135
135
  # * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
136
136
  # are also allowed as parameter.
137
137
  #
138
- # * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :get),
138
+ # * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :delete),
139
139
  # if you wish to restrict this to accept only :post or :delete requests you should do:
140
140
  #
141
- # devise_for :users, sign_out_via: [:post, :delete]
141
+ # devise_for :users, sign_out_via: [:get, :post]
142
142
  #
143
143
  # You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
144
144
  #
@@ -287,7 +287,7 @@ module ActionDispatch::Routing
287
287
  # root to: "admin/dashboard#show", as: :user_root
288
288
  # end
289
289
  #
290
- def authenticate(scope=nil, block=nil)
290
+ def authenticate(scope = nil, block = nil)
291
291
  constraints_for(:authenticate!, scope, block) do
292
292
  yield
293
293
  end
@@ -311,7 +311,7 @@ module ActionDispatch::Routing
311
311
  #
312
312
  # root to: 'landing#show'
313
313
  #
314
- def authenticated(scope=nil, block=nil)
314
+ def authenticated(scope = nil, block = nil)
315
315
  constraints_for(:authenticate?, scope, block) do
316
316
  yield
317
317
  end
@@ -328,7 +328,7 @@ module ActionDispatch::Routing
328
328
  #
329
329
  # root to: 'dashboard#show'
330
330
  #
331
- def unauthenticated(scope=nil)
331
+ def unauthenticated(scope = nil)
332
332
  constraint = lambda do |request|
333
333
  not request.env["warden"].authenticate? scope: scope
334
334
  end
@@ -474,7 +474,7 @@ ERROR
474
474
  @scope = current_scope
475
475
  end
476
476
 
477
- def constraints_for(method_to_apply, scope=nil, block=nil)
477
+ def constraints_for(method_to_apply, scope = nil, block = nil)
478
478
  constraint = lambda do |request|
479
479
  request.env['warden'].send(method_to_apply, scope: scope) &&
480
480
  (block.nil? || block.call(request.env["warden"].user(scope)))
data/lib/devise/rails.rb CHANGED
@@ -17,6 +17,10 @@ module Devise
17
17
  app.reload_routes! if Devise.reload_routes
18
18
  end
19
19
 
20
+ initializer "devise.deprecator" do |app|
21
+ app.deprecators[:devise] = Devise.deprecator if app.respond_to?(:deprecators)
22
+ end
23
+
20
24
  initializer "devise.url_helpers" do
21
25
  Devise.include_helpers(Devise::Controllers)
22
26
  end
@@ -28,7 +28,7 @@ module Devise
28
28
  private
29
29
 
30
30
  # Receives a resource and check if it is valid by calling valid_for_authentication?
31
- # An optional block that will be triggered while validating can be optionally
31
+ # A block that will be triggered while validating can be optionally
32
32
  # given as parameter. Check Devise::Models::Authenticatable.valid_for_authentication?
33
33
  # for more information.
34
34
  #
@@ -37,6 +37,8 @@ module Devise
37
37
  @response
38
38
  end
39
39
 
40
+ ruby2_keywords(:process) if respond_to?(:ruby2_keywords, true)
41
+
40
42
  # We need to set up the environment variables and the response in the controller.
41
43
  def setup_controller_for_warden #:nodoc:
42
44
  @request.env['action_controller.instance'] = @controller
@@ -67,7 +69,7 @@ module Devise
67
69
  scope = resource
68
70
  resource = deprecated
69
71
 
70
- ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
72
+ Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
71
73
  [Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise.
72
74
  Please use sign_in(resource, scope: :#{scope}) instead.
73
75
  DEPRECATION
@@ -141,7 +143,7 @@ module Devise
141
143
  @controller.response.headers.merge!(headers)
142
144
  @controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
143
145
  @controller.status = status
144
- @controller.response.body = response.body
146
+ @controller.response_body = response.body
145
147
  nil # causes process return @response
146
148
  end
147
149
 
@@ -28,7 +28,7 @@ module Devise
28
28
  end
29
29
  end
30
30
 
31
- # Signs in a specific resource, mimicking a successfull sign in
31
+ # Signs in a specific resource, mimicking a successful sign in
32
32
  # operation through +Devise::SessionsController#create+.
33
33
  #
34
34
  # * +resource+ - The resource that should be authenticated
@@ -4,7 +4,7 @@ module Devise
4
4
  module TestHelpers
5
5
  def self.included(base)
6
6
  base.class_eval do
7
- ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
7
+ Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
8
8
  [Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
9
9
  For controller tests, please include `Devise::Test::ControllerHelpers` instead.
10
10
  DEPRECATION
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Devise
4
- VERSION = "4.6.0".freeze
4
+ VERSION = "4.9.4".freeze
5
5
  end
data/lib/devise.rb CHANGED
@@ -13,6 +13,7 @@ module Devise
13
13
  autoload :Encryptor, 'devise/encryptor'
14
14
  autoload :FailureApp, 'devise/failure_app'
15
15
  autoload :OmniAuth, 'devise/omniauth'
16
+ autoload :Orm, 'devise/orm'
16
17
  autoload :ParameterFilter, 'devise/parameter_filter'
17
18
  autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
18
19
  autoload :TestHelpers, 'devise/test_helpers'
@@ -23,6 +24,7 @@ module Devise
23
24
  module Controllers
24
25
  autoload :Helpers, 'devise/controllers/helpers'
25
26
  autoload :Rememberable, 'devise/controllers/rememberable'
27
+ autoload :Responder, 'devise/controllers/responder'
26
28
  autoload :ScopedViews, 'devise/controllers/scoped_views'
27
29
  autoload :SignInOut, 'devise/controllers/sign_in_out'
28
30
  autoload :StoreLocation, 'devise/controllers/store_location'
@@ -71,7 +73,7 @@ module Devise
71
73
 
72
74
  # The number of times to hash the password.
73
75
  mattr_accessor :stretches
74
- @@stretches = 11
76
+ @@stretches = 12
75
77
 
76
78
  # The default key used when authenticating over http auth.
77
79
  mattr_accessor :http_authentication_key
@@ -217,7 +219,16 @@ module Devise
217
219
 
218
220
  # Which formats should be treated as navigational.
219
221
  mattr_accessor :navigational_formats
220
- @@navigational_formats = ["*/*", :html]
222
+ @@navigational_formats = ["*/*", :html, :turbo_stream]
223
+
224
+ # The default responder used by Devise, used to customize status codes with:
225
+ #
226
+ # `config.responder.error_status`
227
+ # `config.responder.redirect_status`
228
+ #
229
+ # Can be replaced by a custom application responder.
230
+ mattr_accessor :responder
231
+ @@responder = Devise::Controllers::Responder
221
232
 
222
233
  # When set to true, signing out a user signs out all other scopes.
223
234
  mattr_accessor :sign_out_all_scopes
@@ -297,14 +308,6 @@ module Devise
297
308
  mattr_accessor :sign_in_after_change_password
298
309
  @@sign_in_after_change_password = true
299
310
 
300
- def self.rails51? # :nodoc:
301
- Rails.gem_version >= Gem::Version.new("5.1.x")
302
- end
303
-
304
- def self.activerecord51? # :nodoc:
305
- defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
306
- end
307
-
308
311
  # Default way to set up Devise. Run rails generate devise_install to create
309
312
  # a fresh initializer with all configuration values.
310
313
  def self.setup
@@ -317,12 +320,20 @@ module Devise
317
320
  end
318
321
 
319
322
  def get
320
- ActiveSupport::Dependencies.constantize(@name)
323
+ # TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
324
+ if ActiveSupport::Dependencies.respond_to?(:constantize)
325
+ ActiveSupport::Dependencies.constantize(@name)
326
+ else
327
+ @name.constantize
328
+ end
321
329
  end
322
330
  end
323
331
 
324
332
  def self.ref(arg)
325
- ActiveSupport::Dependencies.reference(arg)
333
+ # TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
334
+ if ActiveSupport::Dependencies.respond_to?(:reference)
335
+ ActiveSupport::Dependencies.reference(arg)
336
+ end
326
337
  Getter.new(arg)
327
338
  end
328
339
 
@@ -509,6 +520,18 @@ module Devise
509
520
  b.each_byte { |byte| res |= byte ^ l.shift }
510
521
  res == 0
511
522
  end
523
+
524
+ def self.deprecator
525
+ @deprecator ||= ActiveSupport::Deprecation.new("5.0", "Devise")
526
+ end
527
+
528
+ def self.activerecord51? # :nodoc:
529
+ deprecator.warn <<-DEPRECATION.strip_heredoc
530
+ [Devise] `Devise.activerecord51?` is deprecated and will be removed in the next major version.
531
+ It is a non-public method that's no longer used internally, but that other libraries have been relying on.
532
+ DEPRECATION
533
+ defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
534
+ end
512
535
  end
513
536
 
514
537
  require 'warden'