devise 4.7.2 → 4.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66728973d95b80cb0029344f3ea6e86d0c01d692f8a363e54e85e2ebe29bcdb4
4
- data.tar.gz: b41344b9a521d72d48f8b1e8618767ddb237a10f81b9d272376e9c09afc1da54
3
+ metadata.gz: 073edbd8314be8f7b4da9e8f1b2eb07f4f25faf77a4400b6ef91f6a7d6905fda
4
+ data.tar.gz: 96ba453ccdf7f73d76c40525644d867fe8a699efa7f0b3ab58f5e520af44f0d7
5
5
  SHA512:
6
- metadata.gz: '03294fe66db7023bac9f5940ccf4aecd65af65329485e4eb7cb864b71729feffc965b144125310c4b5654273e1b2275b31b260b09040d5c58c6e0e907de347a1'
7
- data.tar.gz: f599102d1558b3dcf1ccc68f8665b3229400f6e4d4da861c67173bbcddb9b6c0b15e6f36d43ff48eb8f89edcd8bf15d3767c4f3252a8739926aca979002336de
6
+ metadata.gz: 3e86e75d88256721b32dc38b9ace70d25ccbdff76885c4a942452da0d01a92f7179c4e4800c55f91a1f535e4a9ecf9cce696523651b94aa4f5ee75b0016c4132
7
+ data.tar.gz: 2a42ad0db913c2aa1ae782a06edd48096b0b3bd4dbe47a243cce6a7f923663240ca3e8ad9459aa0148623fa366fa89d3a30959b1bd2e7b399343ebc207beb7bf
data/CHANGELOG.md CHANGED
@@ -1,4 +1,31 @@
1
- ### 4.7.1 - 2020-06-10
1
+ ### 4.8.1
2
+
3
+ * enhancements
4
+ * Add support for Rails 7.0. Please note that Turbo integration is not fully supported by Devise yet.
5
+
6
+ ### 4.8.0 - 2021-04-29
7
+
8
+ * enhancements
9
+ * Devise now enables the upgrade of OmniAuth 2+. Previously Devise would raise an error if you'd try to upgrade. Please note that OmniAuth 2 is considered a security upgrade and recommended to everyone. You can read more about the details (and possible necessary changes to your app as part of the upgrade) in [their release notes](https://github.com/omniauth/omniauth/releases/tag/v2.0.0). [Devise's OmniAuth Overview wiki](https://github.com/heartcombo/devise/wiki/OmniAuth:-Overview) was also updated to cover OmniAuth 2.0 requirements.
10
+ - Note that the upgrade required Devise shared links that initiate the OmniAuth flow to be changed to `method: :post`, which is now a requirement for OmniAuth, part of the security improvement. If you have copied and customized the Devise shared links partial to your app, or if you have other links in your app that initiate the OmniAuth flow, they will have to be updated to use `method: :post`, or changed to use buttons (e.g. `button_to`) to work with OmniAuth 2. (if you're using links with `method: :post`, make sure your app has `rails-ujs` or `jquery-ujs` included in order for these links to work properly.)
11
+ - As part of the OmniAuth 2.0 upgrade you might also need to add the [`omniauth-rails_csrf_protection`](https://github.com/cookpad/omniauth-rails_csrf_protection) gem to your app if you don't have it already. (and you don't want to roll your own code to verify requests.) Check the OmniAuth v2 release notes for more info.
12
+ * Introduce `Lockable#reset_failed_attempts!` model method to reset failed attempts counter to 0 after the user signs in.
13
+ - This logic existed inside the lockable warden hook and is triggered automatically after the user signs in. The new model method is an extraction to allow you to override it in the application to implement things like switching to a write database if you're using the new multi-DB infrastructure from Rails for example, similar to how it's already possible with `Trackable#update_tracked_fields!`.
14
+ * Add support for Ruby 3.
15
+ * Add support for Rails 6.1.
16
+ * Move CI to GitHub Actions.
17
+
18
+ * deprecations
19
+ * `Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION` is deprecated in favor of `Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION` (@hanachin)
20
+
21
+ ### 4.7.3 - 2020-09-20
22
+
23
+ * bug fixes
24
+ * Do not modify `:except` option given to `#serializable_hash`. (by @dpep)
25
+ * Fix thor deprecation when running the devise generator. (by @deivid-rodriguez)
26
+ * Fix hanging tests for streaming controllers using Devise. (by @afn)
27
+
28
+ ### 4.7.2 - 2020-06-10
2
29
 
3
30
  * enhancements
4
31
  * Increase default stretches to 12 (by @sergey-alekseev)
data/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  ![Devise Logo](https://raw.github.com/heartcombo/devise/master/devise.png)
2
2
 
3
- [![Build Status](https://api.travis-ci.org/heartcombo/devise.svg?branch=master)](http://travis-ci.org/heartcombo/devise)
4
3
  [![Code Climate](https://codeclimate.com/github/heartcombo/devise.svg)](https://codeclimate.com/github/heartcombo/devise)
5
4
 
6
5
  Devise is a flexible authentication solution for Rails based on Warden. It:
@@ -54,7 +53,6 @@ It's composed of 10 modules:
54
53
  - [Other ORMs](#other-orms)
55
54
  - [Rails API mode](#rails-api-mode)
56
55
  - [Additional information](#additional-information)
57
- - [Heroku](#heroku)
58
56
  - [Warden](#warden)
59
57
  - [Contributors](#contributors)
60
58
  - [License](#license)
@@ -119,8 +117,8 @@ You will usually want to write tests for your changes. To run the test suite, g
119
117
  Devise works with multiple Ruby and Rails versions, and ActiveRecord and Mongoid ORMs, which means you can run the test suite with some modifiers: `DEVISE_ORM` and `BUNDLE_GEMFILE`.
120
118
 
121
119
  ### DEVISE_ORM
122
- Since Devise support both Mongoid and ActiveRecord, we rely on this variable to run specific code for each ORM.
123
- The default value of `DEVISE_ORM` is `active_record`. To run the tests for mongoid, you can pass `mongoid`:
120
+ Since Devise supports both Mongoid and ActiveRecord, we rely on this variable to run specific code for each ORM.
121
+ The default value of `DEVISE_ORM` is `active_record`. To run the tests for Mongoid, you can pass `mongoid`:
124
122
  ```
125
123
  DEVISE_ORM=mongoid bin/test
126
124
 
@@ -132,7 +130,7 @@ Please note that the command output will show the variable value being used.
132
130
 
133
131
  ### BUNDLE_GEMFILE
134
132
  We can use this variable to tell bundler what Gemfile it should use (instead of the one in the current directory).
135
- Inside the [gemfiles](https://github.com/heartcombo/devise/tree/master/gemfiles) directory, we have one for each version of Rails we support. When you send us a pull request, it may happen that the test suite breaks on Travis using some of them. If that's the case, you can simulate the same environment using the `BUNDLE_GEMFILE` variable.
133
+ Inside the [gemfiles](https://github.com/heartcombo/devise/tree/master/gemfiles) directory, we have one for each version of Rails we support. When you send us a pull request, it may happen that the test suite breaks using some of them. If that's the case, you can simulate the same environment using the `BUNDLE_GEMFILE` variable.
136
134
  For example, if the tests broke using Ruby 2.4.2 and Rails 4.1, you can do the following:
137
135
  ```bash
138
136
  rbenv shell 2.4.2 # or rvm use 2.4.2
@@ -273,7 +271,7 @@ Besides `:stretches`, you can define `:pepper`, `:encryptor`, `:confirm_within`,
273
271
 
274
272
  ### Strong Parameters
275
273
 
276
- ![The Parameter Sanitizer API has changed for Devise 4](http://messages.hellobits.com/warning.svg?message=The%20Parameter%20Sanitizer%20API%20has%20changed%20for%20Devise%204)
274
+ The Parameter Sanitizer API has changed for Devise 4 :warning:
277
275
 
278
276
  *For previous Devise versions see https://github.com/heartcombo/devise/tree/3-stable#strong-parameters*
279
277
 
@@ -313,7 +311,7 @@ class ApplicationController < ActionController::Base
313
311
  end
314
312
  ```
315
313
 
316
- Devise allows you to completely change Devise defaults or invoke custom behaviour by passing a block:
314
+ Devise allows you to completely change Devise defaults or invoke custom behavior by passing a block:
317
315
 
318
316
  To permit simple scalar values for username and email, use this
319
317
 
@@ -436,7 +434,7 @@ If the customization at the views level is not enough, you can customize each co
436
434
  end
437
435
  ```
438
436
 
439
- Or you can simply add new behaviour to it:
437
+ Or you can simply add new behavior to it:
440
438
 
441
439
  ```ruby
442
440
  class Users::SessionsController < Devise::SessionsController
@@ -686,7 +684,7 @@ If you enable the [Recoverable](http://rubydoc.info/github/heartcombo/devise/mas
686
684
  1. Action Mailer logs the entire contents of all outgoing emails to the DEBUG level. Password reset tokens delivered to users in email will be leaked.
687
685
  2. Active Job logs all arguments to every enqueued job at the INFO level. If you configure Devise to use `deliver_later` to send password reset emails, password reset tokens will be leaked.
688
686
 
689
- Rails sets the production logger level to DEBUG by default. Consider changing your production logger level to WARN if you wish to prevent tokens from being leaked into your logs. In `config/environments/production.rb`:
687
+ Rails sets the production logger level to INFO by default. Consider changing your production logger level to WARN if you wish to prevent tokens from being leaked into your logs. In `config/environments/production.rb`:
690
688
 
691
689
  ```ruby
692
690
  config.log_level = :warn
@@ -741,6 +739,6 @@ https://github.com/heartcombo/devise/graphs/contributors
741
739
 
742
740
  ## License
743
741
 
744
- MIT License. Copyright 2020 Rafael França, Leaonardo Tegon, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
742
+ MIT License. Copyright 2020 Rafael França, Leonardo Tegon, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
745
743
 
746
744
  The Devise logo is licensed under [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](https://creativecommons.org/licenses/by-nc-nd/4.0/).
@@ -1,14 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeviseHelper
4
- # Retain this method for backwards compatibility, deprecated in favour of modifying the
5
- # devise/shared/error_messages partial
4
+ # Retain this method for backwards compatibility, deprecated in favor of modifying the
5
+ # devise/shared/error_messages partial.
6
6
  def devise_error_messages!
7
7
  ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
8
- [Devise] `DeviseHelper.devise_error_messages!`
9
- is deprecated and it will be removed in the next major version.
10
- To customize the errors styles please run `rails g devise:views` and modify the
11
- `devise/shared/error_messages` partial.
8
+ [Devise] `DeviseHelper#devise_error_messages!` is deprecated and will be
9
+ removed in the next major version.
10
+
11
+ Devise now uses a partial under "devise/shared/error_messages" to display
12
+ error messages by default, and make them easier to customize. Update your
13
+ views changing calls from:
14
+
15
+ <%= devise_error_messages! %>
16
+
17
+ to:
18
+
19
+ <%= render "devise/shared/error_messages", resource: resource %>
20
+
21
+ To start customizing how errors are displayed, you can copy the partial
22
+ from devise to your `app/views` folder. Alternatively, you can run
23
+ `rails g devise:views` which will copy all of them again to your app.
12
24
  DEPRECATION
13
25
 
14
26
  return "" if resource.errors.empty?
@@ -4,26 +4,26 @@ if defined?(ActionMailer)
4
4
  class Devise::Mailer < Devise.parent_mailer.constantize
5
5
  include Devise::Mailers::Helpers
6
6
 
7
- def confirmation_instructions(record, token, opts={})
7
+ def confirmation_instructions(record, token, opts = {})
8
8
  @token = token
9
9
  devise_mail(record, :confirmation_instructions, opts)
10
10
  end
11
11
 
12
- def reset_password_instructions(record, token, opts={})
12
+ def reset_password_instructions(record, token, opts = {})
13
13
  @token = token
14
14
  devise_mail(record, :reset_password_instructions, opts)
15
15
  end
16
16
 
17
- def unlock_instructions(record, token, opts={})
17
+ def unlock_instructions(record, token, opts = {})
18
18
  @token = token
19
19
  devise_mail(record, :unlock_instructions, opts)
20
20
  end
21
21
 
22
- def email_changed(record, opts={})
22
+ def email_changed(record, opts = {})
23
23
  devise_mail(record, :email_changed, opts)
24
24
  end
25
25
 
26
- def password_change(record, opts={})
26
+ def password_change(record, opts = {})
27
27
  devise_mail(record, :password_change, opts)
28
28
  end
29
29
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  <%- if devise_mapping.omniauthable? %>
22
22
  <%- resource_class.omniauth_providers.each do |provider| %>
23
- <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
23
+ <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
24
24
  <% end %>
25
25
  <% end %>
@@ -44,7 +44,7 @@ en:
44
44
  signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
45
45
  update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
46
46
  updated: "Your account has been updated successfully."
47
- updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again"
47
+ updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again."
48
48
  sessions:
49
49
  signed_in: "Signed in successfully."
50
50
  signed_out: "Signed out successfully."
@@ -36,14 +36,14 @@ module Devise
36
36
  # before_action ->{ authenticate_blogger! :admin } # Redirects to the admin login page
37
37
  # current_blogger :user # Preferably returns a User if one is signed in
38
38
  #
39
- def devise_group(group_name, opts={})
39
+ def devise_group(group_name, opts = {})
40
40
  mappings = "[#{ opts[:contains].map { |m| ":#{m}" }.join(',') }]"
41
41
 
42
42
  class_eval <<-METHODS, __FILE__, __LINE__ + 1
43
- def authenticate_#{group_name}!(favourite=nil, opts={})
43
+ def authenticate_#{group_name}!(favorite = nil, opts = {})
44
44
  unless #{group_name}_signed_in?
45
45
  mappings = #{mappings}
46
- mappings.unshift mappings.delete(favourite.to_sym) if favourite
46
+ mappings.unshift mappings.delete(favorite.to_sym) if favorite
47
47
  mappings.each do |mapping|
48
48
  opts[:scope] = mapping
49
49
  warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
@@ -57,9 +57,9 @@ module Devise
57
57
  end
58
58
  end
59
59
 
60
- def current_#{group_name}(favourite=nil)
60
+ def current_#{group_name}(favorite = nil)
61
61
  mappings = #{mappings}
62
- mappings.unshift mappings.delete(favourite.to_sym) if favourite
62
+ mappings.unshift mappings.delete(favorite.to_sym) if favorite
63
63
  mappings.each do |mapping|
64
64
  current = warden.authenticate(scope: mapping)
65
65
  return current if current
@@ -113,7 +113,7 @@ module Devise
113
113
  mapping = mapping.name
114
114
 
115
115
  class_eval <<-METHODS, __FILE__, __LINE__ + 1
116
- def authenticate_#{mapping}!(opts={})
116
+ def authenticate_#{mapping}!(opts = {})
117
117
  opts[:scope] = :#{mapping}
118
118
  warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
119
119
  end
@@ -252,7 +252,7 @@ module Devise
252
252
  # Overwrite Rails' handle unverified request to sign out all scopes,
253
253
  # clear run strategies and remove cached variables.
254
254
  def handle_unverified_request
255
- super # call the default behaviour which resets/nullifies/raises
255
+ super # call the default behavior which resets/nullifies/raises
256
256
  request.env["devise.skip_storage"] = true
257
257
  sign_out_all_scopes(false)
258
258
  end
@@ -10,7 +10,7 @@ module Devise
10
10
  # cause exceptions to be thrown from this method; if you simply want to check
11
11
  # if a scope has already previously been authenticated without running
12
12
  # authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
13
- def signed_in?(scope=nil)
13
+ def signed_in?(scope = nil)
14
14
  [scope || Devise.mappings.keys].flatten.any? do |_scope|
15
15
  warden.authenticate?(scope: _scope)
16
16
  end
@@ -77,7 +77,7 @@ module Devise
77
77
  # sign_out :user # sign_out(scope)
78
78
  # sign_out @user # sign_out(resource)
79
79
  #
80
- def sign_out(resource_or_scope=nil)
80
+ def sign_out(resource_or_scope = nil)
81
81
  return sign_out_all_scopes unless resource_or_scope
82
82
  scope = Devise::Mapping.find_scope!(resource_or_scope)
83
83
  user = warden.user(scope: scope, run_callbacks: false) # If there is no user
@@ -92,7 +92,7 @@ module Devise
92
92
  # Sign out all active users or scopes. This helper is useful for signing out all roles
93
93
  # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
94
94
  # and false if there was no user logged in on all scopes.
95
- def sign_out_all_scopes(lock=true)
95
+ def sign_out_all_scopes(lock = true)
96
96
  users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
97
97
 
98
98
  warden.logout
@@ -106,10 +106,12 @@ module Devise
106
106
  private
107
107
 
108
108
  def expire_data_after_sign_in!
109
+ # TODO: remove once Rails 5.2+ and forward are only supported.
109
110
  # session.keys will return an empty array if the session is not yet loaded.
110
111
  # This is a bug in both Rack and Rails.
111
112
  # A call to #empty? forces the session to be loaded.
112
113
  session.empty?
114
+
113
115
  session.keys.grep(/^devise\./).each { |k| session.delete(k) }
114
116
  end
115
117
 
@@ -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
 
@@ -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
@@ -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)
@@ -272,17 +276,17 @@ module Devise
272
276
  find_first_by_auth_conditions(tainted_conditions)
273
277
  end
274
278
 
275
- def find_first_by_auth_conditions(tainted_conditions, opts={})
279
+ def find_first_by_auth_conditions(tainted_conditions, opts = {})
276
280
  to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
277
281
  end
278
282
 
279
283
  # Find or initialize a record setting an error if it can't be found.
280
- 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:
281
285
  find_or_initialize_with_errors([attribute], { attribute => value }, error)
282
286
  end
283
287
 
284
288
  # Find or initialize a record with group of attributes based on a list of required attributes.
285
- 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:
286
290
  attributes.try(:permit!)
287
291
  attributes = attributes.to_h.with_indifferent_access
288
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)
@@ -13,7 +13,7 @@ module Devise
13
13
  #
14
14
  # == Options
15
15
  #
16
- # DatabaseAuthenticatable adds the following options to devise_for:
16
+ # DatabaseAuthenticatable adds the following options to +devise+:
17
17
  #
18
18
  # * +pepper+: a random string used to provide a more secure hash. Use
19
19
  # `rails secret` to generate new keys.
@@ -42,7 +42,7 @@ module Devise
42
42
  def initialize(*args, &block)
43
43
  @skip_email_changed_notification = false
44
44
  @skip_password_change_notification = false
45
- super
45
+ super
46
46
  end
47
47
 
48
48
  # Skips sending the email changed notification after_update
@@ -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
@@ -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
  #
@@ -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)))
@@ -143,7 +143,7 @@ module Devise
143
143
  @controller.response.headers.merge!(headers)
144
144
  @controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
145
145
  @controller.status = status
146
- @controller.response.body = response.body
146
+ @controller.response_body = response.body
147
147
  nil # causes process return @response
148
148
  end
149
149
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Devise
4
- VERSION = "4.7.2".freeze
4
+ VERSION = "4.8.1".freeze
5
5
  end
data/lib/devise.rb CHANGED
@@ -313,12 +313,20 @@ module Devise
313
313
  end
314
314
 
315
315
  def get
316
- 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
317
322
  end
318
323
  end
319
324
 
320
325
  def self.ref(arg)
321
- 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
322
330
  Getter.new(arg)
323
331
  end
324
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, type: :boolean
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]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.2
4
+ version: 4.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - José Valim
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-06-10 00:00:00.000000000 Z
12
+ date: 2021-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: warden
@@ -155,6 +155,7 @@ files:
155
155
  - lib/devise/parameter_filter.rb
156
156
  - lib/devise/parameter_sanitizer.rb
157
157
  - lib/devise/rails.rb
158
+ - lib/devise/rails/deprecated_constant_accessor.rb
158
159
  - lib/devise/rails/routes.rb
159
160
  - lib/devise/rails/warden_compat.rb
160
161
  - lib/devise/secret_key_finder.rb
@@ -201,7 +202,13 @@ files:
201
202
  homepage: https://github.com/heartcombo/devise
202
203
  licenses:
203
204
  - MIT
204
- metadata: {}
205
+ metadata:
206
+ homepage_uri: https://github.com/heartcombo/devise
207
+ documentation_uri: https://rubydoc.info/github/heartcombo/devise
208
+ changelog_uri: https://github.com/heartcombo/devise/blob/master/CHANGELOG.md
209
+ source_code_uri: https://github.com/heartcombo/devise
210
+ bug_tracker_uri: https://github.com/heartcombo/devise/issues
211
+ wiki_uri: https://github.com/heartcombo/devise/wiki
205
212
  post_install_message:
206
213
  rdoc_options: []
207
214
  require_paths:
@@ -217,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
224
  - !ruby/object:Gem::Version
218
225
  version: '0'
219
226
  requirements: []
220
- rubygems_version: 3.0.3
227
+ rubygems_version: 3.1.6
221
228
  signing_key:
222
229
  specification_version: 4
223
230
  summary: Flexible authentication solution for Rails with Warden