devise 4.7.0 → 4.8.1

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 (41) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +45 -4
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +68 -61
  5. data/app/controllers/devise_controller.rb +2 -2
  6. data/app/helpers/devise_helper.rb +18 -6
  7. data/app/mailers/devise/mailer.rb +5 -5
  8. data/app/views/devise/shared/_links.html.erb +1 -1
  9. data/config/locales/en.yml +3 -3
  10. data/lib/devise/controllers/helpers.rb +7 -7
  11. data/lib/devise/controllers/sign_in_out.rb +6 -4
  12. data/lib/devise/controllers/url_helpers.rb +1 -1
  13. data/lib/devise/failure_app.rb +2 -3
  14. data/lib/devise/hooks/lockable.rb +2 -5
  15. data/lib/devise/hooks/timeoutable.rb +2 -2
  16. data/lib/devise/mapping.rb +1 -1
  17. data/lib/devise/models/authenticatable.rb +13 -8
  18. data/lib/devise/models/confirmable.rb +14 -2
  19. data/lib/devise/models/database_authenticatable.rb +7 -3
  20. data/lib/devise/models/lockable.rb +10 -2
  21. data/lib/devise/models/omniauthable.rb +2 -2
  22. data/lib/devise/models/recoverable.rb +3 -3
  23. data/lib/devise/models/rememberable.rb +2 -2
  24. data/lib/devise/models/timeoutable.rb +1 -1
  25. data/lib/devise/models/trackable.rb +1 -1
  26. data/lib/devise/models/validatable.rb +1 -1
  27. data/lib/devise/omniauth.rb +2 -5
  28. data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
  29. data/lib/devise/rails/routes.rb +4 -4
  30. data/lib/devise/test/controller_helpers.rb +3 -1
  31. data/lib/devise/test/integration_helpers.rb +1 -1
  32. data/lib/devise/version.rb +1 -1
  33. data/lib/devise.rb +11 -7
  34. data/lib/generators/active_record/devise_generator.rb +17 -2
  35. data/lib/generators/devise/devise_generator.rb +1 -1
  36. data/lib/generators/devise/install_generator.rb +1 -5
  37. data/lib/generators/devise/views_generator.rb +1 -1
  38. data/lib/generators/templates/README +9 -1
  39. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +1 -1
  40. data/lib/generators/templates/devise.rb +15 -3
  41. metadata +16 -10
@@ -34,7 +34,7 @@ module Devise
34
34
  end
35
35
  end
36
36
 
37
- def self.generate_helpers!(routes=nil)
37
+ def self.generate_helpers!(routes = nil)
38
38
  routes ||= begin
39
39
  mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
40
40
  Devise::URL_HELPERS.slice(*mappings)
@@ -71,7 +71,6 @@ module Devise
71
71
  end
72
72
 
73
73
  flash.now[:alert] = i18n_message(:invalid) if is_flashing_format?
74
- # self.response = recall_app(warden_options[:recall]).call(env)
75
74
  self.response = recall_app(warden_options[:recall]).call(request.env)
76
75
  end
77
76
 
@@ -107,7 +106,7 @@ module Devise
107
106
  options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
108
107
  options = i18n_options(options)
109
108
 
110
- I18n.t(:"#{scope}.#{message}", options)
109
+ I18n.t(:"#{scope}.#{message}", **options)
111
110
  else
112
111
  message.to_s
113
112
  end
@@ -152,7 +151,7 @@ module Devise
152
151
 
153
152
  # We need to add the rootpath to `script_name` manually for applications that use a Rails
154
153
  # version lower than 5.1. Otherwise, it is going to generate a wrong path for Engines
155
- # that use Devise. Remove it when the support of Rails 5.0 is droped.
154
+ # that use Devise. Remove it when the support of Rails 5.0 is dropped.
156
155
  elsif root_path_defined?(context) && !rails_51_and_up?
157
156
  rootpath = context.routes.url_helpers.root_path
158
157
  opts[:script_name] = rootpath.chomp('/') if rootpath.length > 1
@@ -3,10 +3,7 @@
3
3
  # After each sign in, if resource responds to failed_attempts, sets it to 0
4
4
  # This is only triggered when the user is explicitly set (with set_user)
5
5
  Warden::Manager.after_set_user except: :fetch do |record, warden, options|
6
- if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
7
- unless record.failed_attempts.to_i.zero?
8
- record.failed_attempts = 0
9
- record.save(validate: false)
10
- end
6
+ if record.respond_to?(:reset_failed_attempts!) && warden.authenticated?(options[:scope])
7
+ record.reset_failed_attempts!
11
8
  end
12
9
  end
@@ -21,8 +21,8 @@ Warden::Manager.after_set_user do |record, warden, options|
21
21
 
22
22
  proxy = Devise::Hooks::Proxy.new(warden)
23
23
 
24
- if record.timedout?(last_request_at) &&
25
- !env['devise.skip_timeout'] &&
24
+ if !env['devise.skip_timeout'] &&
25
+ record.timedout?(last_request_at) &&
26
26
  !proxy.remember_me_is_active?(record)
27
27
  Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
28
28
  throw :warden, scope: scope, message: :timeout
@@ -46,7 +46,7 @@ module Devise
46
46
  raise "Could not find a valid mapping for #{obj.inspect}"
47
47
  end
48
48
 
49
- def self.find_by_path!(path, path_type=:fullpath)
49
+ def self.find_by_path!(path, path_type = :fullpath)
50
50
  Devise.mappings.each_value { |m| return m if path.include?(m.send(path_type)) }
51
51
  raise "Could not find a valid mapping for path #{path.inspect}"
52
52
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'devise/hooks/activatable'
4
4
  require 'devise/hooks/csrf_cleaner'
5
+ require 'devise/rails/deprecated_constant_accessor'
5
6
 
6
7
  module Devise
7
8
  module Models
@@ -9,7 +10,7 @@ module Devise
9
10
  #
10
11
  # == Options
11
12
  #
12
- # Authenticatable adds the following options to devise_for:
13
+ # Authenticatable adds the following options to +devise+:
13
14
  #
14
15
  # * +authentication_keys+: parameters used for authentication. By default [:email].
15
16
  #
@@ -55,11 +56,14 @@ module Devise
55
56
  module Authenticatable
56
57
  extend ActiveSupport::Concern
57
58
 
58
- BLACKLIST_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at,
59
+ UNSAFE_ATTRIBUTES_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at,
59
60
  :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip,
60
61
  :last_sign_in_ip, :password_salt, :confirmation_token, :confirmed_at, :confirmation_sent_at,
61
62
  :remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at]
62
63
 
64
+ include Devise::DeprecatedConstantAccessor
65
+ deprecate_constant "BLACKLIST_FOR_SERIALIZATION", "Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION"
66
+
63
67
  included do
64
68
  class_attribute :devise_modules, instance_writer: false
65
69
  self.devise_modules ||= []
@@ -104,12 +108,12 @@ module Devise
104
108
  # given to :except will simply add names to exempt to Devise internal list.
105
109
  def serializable_hash(options = nil)
106
110
  options = options.try(:dup) || {}
107
- options[:except] = Array(options[:except])
111
+ options[:except] = Array(options[:except]).dup
108
112
 
109
113
  if options[:force_except]
110
114
  options[:except].concat Array(options[:force_except])
111
115
  else
112
- options[:except].concat BLACKLIST_FOR_SERIALIZATION
116
+ options[:except].concat UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
113
117
  end
114
118
 
115
119
  super(options)
@@ -152,7 +156,8 @@ module Devise
152
156
  # # If the record is new or changed then delay the
153
157
  # # delivery until the after_commit callback otherwise
154
158
  # # send now because after_commit will not be called.
155
- # if new_record? || changed?
159
+ # # For Rails < 6 use `changed?` instead of `saved_changes?`.
160
+ # if new_record? || saved_changes?
156
161
  # pending_devise_notifications << [notification, args]
157
162
  # else
158
163
  # render_and_send_devise_message(notification, *args)
@@ -271,17 +276,17 @@ module Devise
271
276
  find_first_by_auth_conditions(tainted_conditions)
272
277
  end
273
278
 
274
- def find_first_by_auth_conditions(tainted_conditions, opts={})
279
+ def find_first_by_auth_conditions(tainted_conditions, opts = {})
275
280
  to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
276
281
  end
277
282
 
278
283
  # Find or initialize a record setting an error if it can't be found.
279
- def find_or_initialize_with_error_by(attribute, value, error=:invalid) #:nodoc:
284
+ def find_or_initialize_with_error_by(attribute, value, error = :invalid) #:nodoc:
280
285
  find_or_initialize_with_errors([attribute], { attribute => value }, error)
281
286
  end
282
287
 
283
288
  # Find or initialize a record with group of attributes based on a list of required attributes.
284
- def find_or_initialize_with_errors(required_attributes, attributes, error=:invalid) #:nodoc:
289
+ def find_or_initialize_with_errors(required_attributes, attributes, error = :invalid) #:nodoc:
285
290
  attributes.try(:permit!)
286
291
  attributes = attributes.to_h.with_indifferent_access
287
292
  .slice(*required_attributes)
@@ -76,7 +76,7 @@ module Devise
76
76
  # Confirm a user by setting it's confirmed_at to actual time. If the user
77
77
  # is already confirmed, add an error to email field. If the user is invalid
78
78
  # add errors
79
- def confirm(args={})
79
+ def confirm(args = {})
80
80
  pending_any_confirmation do
81
81
  if confirmation_period_expired?
82
82
  self.errors.add(:email, :confirmation_period_expired,
@@ -334,7 +334,7 @@ module Devise
334
334
  # confirmation instructions to it. If not, try searching for a user by unconfirmed_email
335
335
  # field. If no user is found, returns a new user with an email not found error.
336
336
  # Options must contain the user email
337
- def send_confirmation_instructions(attributes={})
337
+ def send_confirmation_instructions(attributes = {})
338
338
  confirmable = find_by_unconfirmed_email_with_errors(attributes) if reconfirmable
339
339
  unless confirmable.try(:persisted?)
340
340
  confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
@@ -348,7 +348,19 @@ module Devise
348
348
  # If the user is already confirmed, create an error for the user
349
349
  # Options must have the confirmation_token
350
350
  def confirm_by_token(confirmation_token)
351
+ # When the `confirmation_token` parameter is blank, if there are any users with a blank
352
+ # `confirmation_token` in the database, the first one would be confirmed here.
353
+ # The error is being manually added here to ensure no users are confirmed by mistake.
354
+ # This was done in the model for convenience, since validation errors are automatically
355
+ # displayed in the view.
356
+ if confirmation_token.blank?
357
+ confirmable = new
358
+ confirmable.errors.add(:confirmation_token, :blank)
359
+ return confirmable
360
+ end
361
+
351
362
  confirmable = find_first_by_auth_conditions(confirmation_token: confirmation_token)
363
+
352
364
  unless confirmable
353
365
  confirmation_digest = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
354
366
  confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_digest)
@@ -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
@@ -195,7 +199,7 @@ module Devise
195
199
  # Hashes the password using bcrypt. Custom hash functions should override
196
200
  # this method to apply their own algorithm.
197
201
  #
198
- # See https://github.com/plataformatec/devise-encryptable for examples
202
+ # See https://github.com/heartcombo/devise-encryptable for examples
199
203
  # of other hashing engines.
200
204
  def password_digest(password)
201
205
  Devise::Encryptor.digest(self.class, password)
@@ -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.
@@ -131,7 +131,7 @@ module Devise
131
131
  # password instructions to it. If user is not found, returns a new user
132
132
  # with an email not found error.
133
133
  # Attributes must contain the user's email
134
- def send_reset_password_instructions(attributes={})
134
+ def send_reset_password_instructions(attributes = {})
135
135
  recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
136
136
  recoverable.send_reset_password_instructions if recoverable.persisted?
137
137
  recoverable
@@ -142,7 +142,7 @@ module Devise
142
142
  # try saving the record. If not user is found, returns a new user
143
143
  # containing an error in reset_password_token attribute.
144
144
  # Attributes must contain reset_password_token, password and confirmation
145
- def reset_password_by_token(attributes={})
145
+ def reset_password_by_token(attributes = {})
146
146
  original_token = attributes[:reset_password_token]
147
147
  reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
148
148
 
@@ -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.
@@ -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
 
@@ -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: ActiveSupport::Deprecation.instance)
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
@@ -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)))
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Devise
4
- VERSION = "4.7.0".freeze
4
+ VERSION = "4.8.1".freeze
5
5
  end
data/lib/devise.rb CHANGED
@@ -71,7 +71,7 @@ module Devise
71
71
 
72
72
  # The number of times to hash the password.
73
73
  mattr_accessor :stretches
74
- @@stretches = 11
74
+ @@stretches = 12
75
75
 
76
76
  # The default key used when authenticating over http auth.
77
77
  mattr_accessor :http_authentication_key
@@ -297,10 +297,6 @@ module Devise
297
297
  mattr_accessor :sign_in_after_change_password
298
298
  @@sign_in_after_change_password = true
299
299
 
300
- def self.rails51? # :nodoc:
301
- Rails.gem_version >= Gem::Version.new("5.1.x")
302
- end
303
-
304
300
  def self.activerecord51? # :nodoc:
305
301
  defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
306
302
  end
@@ -317,12 +313,20 @@ module Devise
317
313
  end
318
314
 
319
315
  def get
320
- ActiveSupport::Dependencies.constantize(@name)
316
+ # TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
317
+ if ActiveSupport::Dependencies.respond_to?(:constantize)
318
+ ActiveSupport::Dependencies.constantize(@name)
319
+ else
320
+ @name.constantize
321
+ end
321
322
  end
322
323
  end
323
324
 
324
325
  def self.ref(arg)
325
- ActiveSupport::Dependencies.reference(arg)
326
+ # TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
327
+ if ActiveSupport::Dependencies.respond_to?(:reference)
328
+ ActiveSupport::Dependencies.reference(arg)
329
+ end
326
330
  Getter.new(arg)
327
331
  end
328
332
 
@@ -86,9 +86,24 @@ RUBY
86
86
  Rails::VERSION::MAJOR >= 5
87
87
  end
88
88
 
89
+ def rails61_and_up?
90
+ Rails::VERSION::MAJOR > 6 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1)
91
+ end
92
+
89
93
  def postgresql?
90
- config = ActiveRecord::Base.configurations[Rails.env]
91
- config && config['adapter'] == 'postgresql'
94
+ ar_config && ar_config['adapter'] == 'postgresql'
95
+ end
96
+
97
+ def ar_config
98
+ if ActiveRecord::Base.configurations.respond_to?(:configs_for)
99
+ if rails61_and_up?
100
+ ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: "primary").configuration_hash
101
+ else
102
+ ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: "primary").config
103
+ end
104
+ else
105
+ ActiveRecord::Base.configurations[Rails.env]
106
+ end
92
107
  end
93
108
 
94
109
  def migration_version
@@ -13,7 +13,7 @@ module Devise
13
13
  desc "Generates a model with the given NAME (if one does not exist) with devise " \
14
14
  "configuration plus a migration file and devise routes."
15
15
 
16
- hook_for :orm
16
+ hook_for :orm, required: true
17
17
 
18
18
  class_option :routes, desc: "Generate routes", type: :boolean, default: true
19
19
 
@@ -11,7 +11,7 @@ module Devise
11
11
  source_root File.expand_path("../../templates", __FILE__)
12
12
 
13
13
  desc "Creates a Devise initializer and copy locale files to your application."
14
- class_option :orm
14
+ class_option :orm, required: true
15
15
 
16
16
  def copy_initializer
17
17
  unless options[:orm]
@@ -37,10 +37,6 @@ module Devise
37
37
  def show_readme
38
38
  readme "README" if behavior == :invoke
39
39
  end
40
-
41
- def rails_4?
42
- Rails::VERSION::MAJOR == 4
43
- end
44
40
  end
45
41
  end
46
42
  end
@@ -42,7 +42,7 @@ module Devise
42
42
  def view_directory(name, _target_path = nil)
43
43
  directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
44
44
  if scope
45
- content.gsub "devise/shared/links", "#{plural_scope}/shared/links"
45
+ content.gsub("devise/shared", "#{plural_scope}/shared")
46
46
  else
47
47
  content
48
48
  end
@@ -1,6 +1,6 @@
1
1
  ===============================================================================
2
2
 
3
- Some setup you must do manually if you haven't yet:
3
+ Depending on your application's configuration some manual setup may be required:
4
4
 
5
5
  1. Ensure you have defined default url options in your environments files. Here
6
6
  is an example of default_url_options appropriate for a development environment
@@ -10,10 +10,14 @@ Some setup you must do manually if you haven't yet:
10
10
 
11
11
  In production, :host should be set to the actual host of your application.
12
12
 
13
+ * Required for all applications. *
14
+
13
15
  2. Ensure you have defined root_url to *something* in your config/routes.rb.
14
16
  For example:
15
17
 
16
18
  root to: "home#index"
19
+
20
+ * Not required for API-only Applications *
17
21
 
18
22
  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
19
23
  For example:
@@ -21,8 +25,12 @@ Some setup you must do manually if you haven't yet:
21
25
  <p class="notice"><%= notice %></p>
22
26
  <p class="alert"><%= alert %></p>
23
27
 
28
+ * Not required for API-only Applications *
29
+
24
30
  4. You can copy Devise views (for customization) to your app by running:
25
31
 
26
32
  rails g devise:views
33
+
34
+ * Not required *
27
35
 
28
36
  ===============================================================================
@@ -9,7 +9,7 @@ class <%= @scope_prefix %>OmniauthCallbacksController < Devise::OmniauthCallback
9
9
  # end
10
10
 
11
11
  # More info at:
12
- # https://github.com/plataformatec/devise#omniauth
12
+ # https://github.com/heartcombo/devise#omniauth
13
13
 
14
14
  # GET|POST /resource/auth/twitter
15
15
  # def passthru