devise 3.5.1 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +281 -1066
- data/MIT-LICENSE +2 -1
- data/README.md +292 -97
- data/app/controllers/devise/confirmations_controller.rb +3 -1
- data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -6
- data/app/controllers/devise/passwords_controller.rb +10 -7
- data/app/controllers/devise/registrations_controller.rb +39 -18
- data/app/controllers/devise/sessions_controller.rb +9 -7
- data/app/controllers/devise/unlocks_controller.rb +4 -2
- data/app/controllers/devise_controller.rb +25 -12
- data/app/helpers/devise_helper.rb +23 -18
- data/app/mailers/devise/mailer.rb +13 -3
- data/app/views/devise/confirmations/new.html.erb +2 -2
- data/app/views/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/passwords/edit.html.erb +5 -5
- data/app/views/devise/passwords/new.html.erb +2 -2
- data/app/views/devise/registrations/edit.html.erb +9 -5
- data/app/views/devise/registrations/new.html.erb +4 -4
- data/app/views/devise/sessions/new.html.erb +4 -4
- data/app/views/devise/shared/_error_messages.html.erb +15 -0
- data/app/views/devise/shared/_links.html.erb +8 -8
- data/app/views/devise/unlocks/new.html.erb +2 -2
- data/config/locales/en.yml +7 -2
- data/lib/devise/controllers/helpers.rb +42 -33
- data/lib/devise/controllers/rememberable.rb +11 -2
- data/lib/devise/controllers/scoped_views.rb +2 -0
- data/lib/devise/controllers/sign_in_out.rb +40 -21
- data/lib/devise/controllers/store_location.rb +25 -7
- data/lib/devise/controllers/url_helpers.rb +3 -1
- data/lib/devise/delegator.rb +2 -0
- data/lib/devise/encryptor.rb +6 -4
- data/lib/devise/failure_app.rb +84 -28
- data/lib/devise/hooks/activatable.rb +2 -0
- data/lib/devise/hooks/csrf_cleaner.rb +2 -0
- data/lib/devise/hooks/forgetable.rb +2 -0
- data/lib/devise/hooks/lockable.rb +4 -2
- data/lib/devise/hooks/proxy.rb +3 -1
- data/lib/devise/hooks/rememberable.rb +2 -0
- data/lib/devise/hooks/timeoutable.rb +7 -7
- data/lib/devise/hooks/trackable.rb +2 -0
- data/lib/devise/mailers/helpers.rb +7 -4
- data/lib/devise/mapping.rb +3 -1
- data/lib/devise/models/authenticatable.rb +63 -33
- data/lib/devise/models/confirmable.rb +108 -35
- data/lib/devise/models/database_authenticatable.rb +102 -22
- data/lib/devise/models/lockable.rb +24 -6
- data/lib/devise/models/omniauthable.rb +2 -0
- data/lib/devise/models/recoverable.rb +34 -26
- data/lib/devise/models/registerable.rb +4 -0
- data/lib/devise/models/rememberable.rb +42 -26
- data/lib/devise/models/timeoutable.rb +2 -6
- data/lib/devise/models/trackable.rb +15 -1
- data/lib/devise/models/validatable.rb +10 -3
- data/lib/devise/models.rb +3 -1
- data/lib/devise/modules.rb +2 -0
- data/lib/devise/omniauth/config.rb +2 -0
- data/lib/devise/omniauth/url_helpers.rb +14 -5
- data/lib/devise/omniauth.rb +4 -5
- data/lib/devise/orm/active_record.rb +5 -1
- data/lib/devise/orm/mongoid.rb +6 -2
- data/lib/devise/parameter_filter.rb +4 -0
- data/lib/devise/parameter_sanitizer.rb +139 -65
- data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
- data/lib/devise/rails/routes.rb +71 -51
- data/lib/devise/rails/warden_compat.rb +3 -10
- data/lib/devise/rails.rb +7 -16
- data/lib/devise/secret_key_finder.rb +27 -0
- data/lib/devise/strategies/authenticatable.rb +5 -3
- data/lib/devise/strategies/base.rb +2 -0
- data/lib/devise/strategies/database_authenticatable.rb +11 -4
- data/lib/devise/strategies/rememberable.rb +5 -6
- data/lib/devise/test/controller_helpers.rb +167 -0
- data/lib/devise/test/integration_helpers.rb +63 -0
- data/lib/devise/test_helpers.rb +7 -124
- data/lib/devise/time_inflector.rb +2 -0
- data/lib/devise/token_generator.rb +3 -41
- data/lib/devise/version.rb +3 -1
- data/lib/devise.rb +69 -46
- data/lib/generators/active_record/devise_generator.rb +46 -12
- data/lib/generators/active_record/templates/migration.rb +4 -2
- data/lib/generators/active_record/templates/migration_existing.rb +4 -2
- data/lib/generators/devise/controllers_generator.rb +3 -1
- data/lib/generators/devise/devise_generator.rb +5 -3
- data/lib/generators/devise/install_generator.rb +18 -5
- data/lib/generators/devise/orm_helpers.rb +10 -21
- data/lib/generators/devise/views_generator.rb +21 -11
- data/lib/generators/mongoid/devise_generator.rb +7 -5
- data/lib/generators/templates/README +9 -8
- data/lib/generators/templates/controllers/README +1 -1
- data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
- data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +3 -1
- data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
- data/lib/generators/templates/controllers/registrations_controller.rb +6 -4
- data/lib/generators/templates/controllers/sessions_controller.rb +4 -2
- data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
- data/lib/generators/templates/devise.rb +65 -23
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/email_changed.markerb +7 -0
- data/lib/generators/templates/markerb/password_change.markerb +3 -0
- data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
- data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
- data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +10 -2
- data/lib/generators/templates/simple_form_for/passwords/new.html.erb +4 -1
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
- data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
- data/lib/generators/templates/simple_form_for/sessions/new.html.erb +7 -2
- data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
- metadata +21 -306
- data/.gitignore +0 -10
- data/.travis.yml +0 -45
- data/.yardopts +0 -9
- data/CONTRIBUTING.md +0 -14
- data/Gemfile +0 -29
- data/Gemfile.lock +0 -191
- data/Rakefile +0 -36
- data/devise.gemspec +0 -29
- data/devise.png +0 -0
- data/gemfiles/Gemfile.rails-3.2-stable +0 -29
- data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -169
- data/gemfiles/Gemfile.rails-4.0-stable +0 -29
- data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -163
- data/gemfiles/Gemfile.rails-4.1-stable +0 -29
- data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -169
- data/gemfiles/Gemfile.rails-4.2-stable +0 -29
- data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -191
- data/script/cached-bundle +0 -49
- data/script/s3-put +0 -71
- data/test/controllers/custom_registrations_controller_test.rb +0 -40
- data/test/controllers/custom_strategy_test.rb +0 -62
- data/test/controllers/helpers_test.rb +0 -316
- data/test/controllers/inherited_controller_i18n_messages_test.rb +0 -51
- data/test/controllers/internal_helpers_test.rb +0 -129
- data/test/controllers/load_hooks_controller_test.rb +0 -19
- data/test/controllers/passwords_controller_test.rb +0 -31
- data/test/controllers/sessions_controller_test.rb +0 -103
- data/test/controllers/url_helpers_test.rb +0 -65
- data/test/delegator_test.rb +0 -19
- data/test/devise_test.rb +0 -107
- data/test/failure_app_test.rb +0 -298
- data/test/generators/active_record_generator_test.rb +0 -109
- data/test/generators/controllers_generator_test.rb +0 -48
- data/test/generators/devise_generator_test.rb +0 -39
- data/test/generators/install_generator_test.rb +0 -13
- data/test/generators/mongoid_generator_test.rb +0 -23
- data/test/generators/views_generator_test.rb +0 -96
- data/test/helpers/devise_helper_test.rb +0 -49
- data/test/integration/authenticatable_test.rb +0 -729
- data/test/integration/confirmable_test.rb +0 -324
- data/test/integration/database_authenticatable_test.rb +0 -95
- data/test/integration/http_authenticatable_test.rb +0 -105
- data/test/integration/lockable_test.rb +0 -239
- data/test/integration/omniauthable_test.rb +0 -133
- data/test/integration/recoverable_test.rb +0 -347
- data/test/integration/registerable_test.rb +0 -359
- data/test/integration/rememberable_test.rb +0 -176
- data/test/integration/timeoutable_test.rb +0 -189
- data/test/integration/trackable_test.rb +0 -92
- data/test/mailers/confirmation_instructions_test.rb +0 -115
- data/test/mailers/reset_password_instructions_test.rb +0 -96
- data/test/mailers/unlock_instructions_test.rb +0 -91
- data/test/mapping_test.rb +0 -134
- data/test/models/authenticatable_test.rb +0 -23
- data/test/models/confirmable_test.rb +0 -468
- data/test/models/database_authenticatable_test.rb +0 -249
- data/test/models/lockable_test.rb +0 -328
- data/test/models/omniauthable_test.rb +0 -7
- data/test/models/recoverable_test.rb +0 -228
- data/test/models/registerable_test.rb +0 -7
- data/test/models/rememberable_test.rb +0 -204
- data/test/models/serializable_test.rb +0 -49
- data/test/models/timeoutable_test.rb +0 -51
- data/test/models/trackable_test.rb +0 -41
- data/test/models/validatable_test.rb +0 -127
- data/test/models_test.rb +0 -144
- data/test/omniauth/config_test.rb +0 -57
- data/test/omniauth/url_helpers_test.rb +0 -54
- data/test/orm/active_record.rb +0 -10
- data/test/orm/mongoid.rb +0 -13
- data/test/parameter_sanitizer_test.rb +0 -81
- data/test/rails_app/Rakefile +0 -6
- data/test/rails_app/app/active_record/admin.rb +0 -6
- data/test/rails_app/app/active_record/shim.rb +0 -2
- data/test/rails_app/app/active_record/user.rb +0 -6
- data/test/rails_app/app/active_record/user_on_engine.rb +0 -7
- data/test/rails_app/app/active_record/user_on_main_app.rb +0 -7
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
- data/test/rails_app/app/controllers/admins_controller.rb +0 -11
- data/test/rails_app/app/controllers/application_controller.rb +0 -12
- data/test/rails_app/app/controllers/application_with_fake_engine.rb +0 -30
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +0 -31
- data/test/rails_app/app/controllers/home_controller.rb +0 -25
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
- data/test/rails_app/app/controllers/users_controller.rb +0 -31
- data/test/rails_app/app/helpers/application_helper.rb +0 -3
- data/test/rails_app/app/mailers/users/from_proc_mailer.rb +0 -3
- data/test/rails_app/app/mailers/users/mailer.rb +0 -3
- data/test/rails_app/app/mailers/users/reply_to_mailer.rb +0 -4
- data/test/rails_app/app/mongoid/admin.rb +0 -29
- data/test/rails_app/app/mongoid/shim.rb +0 -23
- data/test/rails_app/app/mongoid/user.rb +0 -39
- data/test/rails_app/app/mongoid/user_on_engine.rb +0 -39
- data/test/rails_app/app/mongoid/user_on_main_app.rb +0 -39
- data/test/rails_app/app/views/admins/index.html.erb +0 -1
- data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
- data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
- data/test/rails_app/app/views/home/index.html.erb +0 -1
- data/test/rails_app/app/views/home/join.html.erb +0 -1
- data/test/rails_app/app/views/home/private.html.erb +0 -1
- data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
- data/test/rails_app/app/views/layouts/application.html.erb +0 -24
- data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
- data/test/rails_app/app/views/users/index.html.erb +0 -1
- data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
- data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
- data/test/rails_app/bin/bundle +0 -3
- data/test/rails_app/bin/rails +0 -4
- data/test/rails_app/bin/rake +0 -4
- data/test/rails_app/config/application.rb +0 -40
- data/test/rails_app/config/boot.rb +0 -14
- data/test/rails_app/config/database.yml +0 -18
- data/test/rails_app/config/environment.rb +0 -5
- data/test/rails_app/config/environments/development.rb +0 -30
- data/test/rails_app/config/environments/production.rb +0 -84
- data/test/rails_app/config/environments/test.rb +0 -41
- data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/test/rails_app/config/initializers/devise.rb +0 -180
- data/test/rails_app/config/initializers/inflections.rb +0 -2
- data/test/rails_app/config/initializers/secret_token.rb +0 -8
- data/test/rails_app/config/initializers/session_store.rb +0 -1
- data/test/rails_app/config/routes.rb +0 -122
- data/test/rails_app/config.ru +0 -4
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
- data/test/rails_app/db/schema.rb +0 -55
- data/test/rails_app/lib/shared_admin.rb +0 -17
- data/test/rails_app/lib/shared_user.rb +0 -29
- data/test/rails_app/lib/shared_user_without_omniauth.rb +0 -13
- data/test/rails_app/public/404.html +0 -26
- data/test/rails_app/public/422.html +0 -26
- data/test/rails_app/public/500.html +0 -26
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_test.rb +0 -9
- data/test/routes_test.rb +0 -264
- data/test/support/action_controller/record_identifier.rb +0 -10
- data/test/support/assertions.rb +0 -39
- data/test/support/helpers.rb +0 -73
- data/test/support/integration.rb +0 -92
- data/test/support/locale/en.yml +0 -8
- data/test/support/mongoid.yml +0 -6
- data/test/support/webrat/integrations/rails.rb +0 -24
- data/test/test_helper.rb +0 -34
- data/test/test_helpers_test.rb +0 -178
- data/test/test_models.rb +0 -33
data/lib/devise/failure_app.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_controller/metal"
|
2
4
|
|
3
5
|
module Devise
|
4
6
|
# Failure application that will be called every time :warden is thrown from
|
5
|
-
# any strategy or hook.
|
6
|
-
# page based on current scope and mapping. If no scope is given,
|
7
|
-
# to the default_url.
|
7
|
+
# any strategy or hook. It is responsible for redirecting the user to the sign
|
8
|
+
# in page based on current scope and mapping. If no scope is given, it
|
9
|
+
# redirects to the default_url.
|
8
10
|
class FailureApp < ActionController::Metal
|
9
|
-
include ActionController::RackDelegation
|
10
11
|
include ActionController::UrlFor
|
11
12
|
include ActionController::Redirecting
|
12
13
|
|
@@ -22,9 +23,12 @@ module Devise
|
|
22
23
|
@respond.call(env)
|
23
24
|
end
|
24
25
|
|
26
|
+
# Try retrieving the URL options from the parent controller (usually
|
27
|
+
# ApplicationController). Instance methods are not supported at the moment,
|
28
|
+
# so only the class-level attribute is used.
|
25
29
|
def self.default_url_options(*args)
|
26
|
-
if defined?(
|
27
|
-
|
30
|
+
if defined?(Devise.parent_controller.constantize)
|
31
|
+
Devise.parent_controller.constantize.try(:default_url_options) || {}
|
28
32
|
else
|
29
33
|
{}
|
30
34
|
end
|
@@ -48,9 +52,26 @@ module Devise
|
|
48
52
|
end
|
49
53
|
|
50
54
|
def recall
|
51
|
-
|
55
|
+
header_info = if relative_url_root?
|
56
|
+
base_path = Pathname.new(relative_url_root)
|
57
|
+
full_path = Pathname.new(attempted_path)
|
58
|
+
|
59
|
+
{ "SCRIPT_NAME" => relative_url_root,
|
60
|
+
"PATH_INFO" => '/' + full_path.relative_path_from(base_path).to_s }
|
61
|
+
else
|
62
|
+
{ "PATH_INFO" => attempted_path }
|
63
|
+
end
|
64
|
+
|
65
|
+
header_info.each do | var, value|
|
66
|
+
if request.respond_to?(:set_header)
|
67
|
+
request.set_header(var, value)
|
68
|
+
else
|
69
|
+
request.env[var] = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
52
73
|
flash.now[:alert] = i18n_message(:invalid) if is_flashing_format?
|
53
|
-
self.response = recall_app(warden_options[:recall]).call(env)
|
74
|
+
self.response = recall_app(warden_options[:recall]).call(request.env)
|
54
75
|
end
|
55
76
|
|
56
77
|
def redirect
|
@@ -81,11 +102,11 @@ module Devise
|
|
81
102
|
options[:scope] = "devise.failure"
|
82
103
|
options[:default] = [message]
|
83
104
|
auth_keys = scope_class.authentication_keys
|
84
|
-
keys = auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys
|
105
|
+
keys = (auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys).map { |key| scope_class.human_attribute_name(key) }
|
85
106
|
options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
|
86
107
|
options = i18n_options(options)
|
87
108
|
|
88
|
-
I18n.t(:"#{scope}.#{message}", options)
|
109
|
+
I18n.t(:"#{scope}.#{message}", **options)
|
89
110
|
else
|
90
111
|
message.to_s
|
91
112
|
end
|
@@ -113,18 +134,29 @@ module Devise
|
|
113
134
|
|
114
135
|
def scope_url
|
115
136
|
opts = {}
|
116
|
-
route = route(scope)
|
117
|
-
opts[:format] = request_format unless skip_format?
|
118
137
|
|
119
|
-
|
138
|
+
# Initialize script_name with nil to prevent infinite loops in
|
139
|
+
# authenticated mounted engines in rails 4.2 and 5.0
|
140
|
+
opts[:script_name] = nil
|
120
141
|
|
121
|
-
|
122
|
-
|
123
|
-
|
142
|
+
route = route(scope)
|
143
|
+
|
144
|
+
opts[:format] = request_format unless skip_format?
|
124
145
|
|
125
146
|
router_name = Devise.mappings[scope].router_name || Devise.available_router_name
|
126
147
|
context = send(router_name)
|
127
148
|
|
149
|
+
if relative_url_root?
|
150
|
+
opts[:script_name] = relative_url_root
|
151
|
+
|
152
|
+
# We need to add the rootpath to `script_name` manually for applications that use a Rails
|
153
|
+
# version lower than 5.1. Otherwise, it is going to generate a wrong path for Engines
|
154
|
+
# that use Devise. Remove it when the support of Rails 5.0 is dropped.
|
155
|
+
elsif root_path_defined?(context) && !rails_51_and_up?
|
156
|
+
rootpath = context.routes.url_helpers.root_path
|
157
|
+
opts[:script_name] = rootpath.chomp('/') if rootpath.length > 1
|
158
|
+
end
|
159
|
+
|
128
160
|
if context.respond_to?(route)
|
129
161
|
context.send(route, opts)
|
130
162
|
elsif respond_to?(:root_url)
|
@@ -138,12 +170,12 @@ module Devise
|
|
138
170
|
%w(html */*).include? request_format.to_s
|
139
171
|
end
|
140
172
|
|
141
|
-
# Choose whether we should respond in
|
173
|
+
# Choose whether we should respond in an HTTP authentication fashion,
|
142
174
|
# including 401 and optional headers.
|
143
175
|
#
|
144
|
-
# This method allows the user to explicitly disable
|
145
|
-
# on
|
146
|
-
# handling the errors on their own. This is useful in case your
|
176
|
+
# This method allows the user to explicitly disable HTTP authentication
|
177
|
+
# on AJAX requests in case they want to redirect on failures instead of
|
178
|
+
# handling the errors on their own. This is useful in case your AJAX API
|
147
179
|
# is the same as your public API and uses a format like JSON (so you
|
148
180
|
# cannot mark JSON as a navigational format).
|
149
181
|
def http_auth?
|
@@ -154,7 +186,7 @@ module Devise
|
|
154
186
|
end
|
155
187
|
end
|
156
188
|
|
157
|
-
# It
|
189
|
+
# It doesn't make sense to send authenticate headers in AJAX requests
|
158
190
|
# or if the user disabled them.
|
159
191
|
def http_auth_header?
|
160
192
|
scope_class.http_authenticatable && !request.xhr?
|
@@ -180,11 +212,11 @@ module Devise
|
|
180
212
|
end
|
181
213
|
|
182
214
|
def warden
|
183
|
-
env[
|
215
|
+
request.respond_to?(:get_header) ? request.get_header("warden") : request.env["warden"]
|
184
216
|
end
|
185
217
|
|
186
218
|
def warden_options
|
187
|
-
env[
|
219
|
+
request.respond_to?(:get_header) ? request.get_header("warden.options") : request.env["warden.options"]
|
188
220
|
end
|
189
221
|
|
190
222
|
def warden_message
|
@@ -203,10 +235,10 @@ module Devise
|
|
203
235
|
warden_options[:attempted_path]
|
204
236
|
end
|
205
237
|
|
206
|
-
# Stores requested
|
207
|
-
# scoped session provided by warden here, since the user is not
|
208
|
-
# yet, but we still need to store the
|
209
|
-
# would never use the same
|
238
|
+
# Stores requested URI to redirect the user after signing in. We can't use
|
239
|
+
# the scoped session provided by warden here, since the user is not
|
240
|
+
# authenticated yet, but we still need to store the URI based on scope, so
|
241
|
+
# different scopes would never use the same URI to redirect.
|
210
242
|
def store_location!
|
211
243
|
store_location_for(scope, attempted_path) if request.get? && !http_auth?
|
212
244
|
end
|
@@ -218,11 +250,35 @@ module Devise
|
|
218
250
|
# Check if flash messages should be emitted. Default is to do it on
|
219
251
|
# navigational formats
|
220
252
|
def is_flashing_format?
|
221
|
-
is_navigational_format?
|
253
|
+
request.respond_to?(:flash) && is_navigational_format?
|
222
254
|
end
|
223
255
|
|
224
256
|
def request_format
|
225
257
|
@request_format ||= request.format.try(:ref)
|
226
258
|
end
|
259
|
+
|
260
|
+
def relative_url_root
|
261
|
+
@relative_url_root ||= begin
|
262
|
+
config = Rails.application.config
|
263
|
+
|
264
|
+
config.try(:relative_url_root) || config.action_controller.try(:relative_url_root)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def relative_url_root?
|
269
|
+
relative_url_root.present?
|
270
|
+
end
|
271
|
+
|
272
|
+
ActiveSupport.run_load_hooks(:devise_failure_app, self)
|
273
|
+
|
274
|
+
private
|
275
|
+
|
276
|
+
def root_path_defined?(context)
|
277
|
+
defined?(context.routes) && context.routes.url_helpers.respond_to?(:root_path)
|
278
|
+
end
|
279
|
+
|
280
|
+
def rails_51_and_up?
|
281
|
+
Rails.gem_version >= Gem::Version.new("5.1")
|
282
|
+
end
|
227
283
|
end
|
228
284
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# After each sign in, if resource responds to failed_attempts, sets it to 0
|
2
4
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
5
|
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
4
|
-
if record.respond_to?(:
|
5
|
-
record.
|
6
|
+
if record.respond_to?(:reset_failed_attempts!) && warden.authenticated?(options[:scope])
|
7
|
+
record.reset_failed_attempts!
|
6
8
|
end
|
7
9
|
end
|
data/lib/devise/hooks/proxy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Hooks
|
3
5
|
# A small warden proxy so we can remember, forget and
|
@@ -7,7 +9,7 @@ module Devise
|
|
7
9
|
include Devise::Controllers::SignInOut
|
8
10
|
|
9
11
|
attr_reader :warden
|
10
|
-
delegate :cookies, :
|
12
|
+
delegate :cookies, :request, to: :warden
|
11
13
|
|
12
14
|
def initialize(warden)
|
13
15
|
@warden = warden
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Each time a record is set we check whether its session has already timed out
|
2
4
|
# or not, based on last request time. If so, the record is logged out and
|
3
5
|
# redirected to the sign in page. Also, each time the request comes and the
|
@@ -7,7 +9,8 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
7
9
|
scope = options[:scope]
|
8
10
|
env = warden.request.env
|
9
11
|
|
10
|
-
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) &&
|
12
|
+
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) &&
|
13
|
+
options[:store] != false && !env['devise.skip_timeoutable']
|
11
14
|
last_request_at = warden.session(scope)['last_request_at']
|
12
15
|
|
13
16
|
if last_request_at.is_a? Integer
|
@@ -18,13 +21,10 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
18
21
|
|
19
22
|
proxy = Devise::Hooks::Proxy.new(warden)
|
20
23
|
|
21
|
-
if
|
24
|
+
if !env['devise.skip_timeout'] &&
|
25
|
+
record.timedout?(last_request_at) &&
|
26
|
+
!proxy.remember_me_is_active?(record)
|
22
27
|
Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
|
23
|
-
|
24
|
-
if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
|
25
|
-
record.reset_authentication_token!
|
26
|
-
end
|
27
|
-
|
28
28
|
throw :warden, scope: scope, message: :timeout
|
29
29
|
end
|
30
30
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Mailers
|
3
5
|
module Helpers
|
@@ -5,15 +7,16 @@ module Devise
|
|
5
7
|
|
6
8
|
included do
|
7
9
|
include Devise::Controllers::ScopedViews
|
8
|
-
attr_reader :scope_name, :resource
|
9
10
|
end
|
10
11
|
|
11
12
|
protected
|
12
13
|
|
14
|
+
attr_reader :scope_name, :resource
|
15
|
+
|
13
16
|
# Configure default email options
|
14
|
-
def devise_mail(record, action, opts={})
|
17
|
+
def devise_mail(record, action, opts = {}, &block)
|
15
18
|
initialize_from_record(record)
|
16
|
-
mail headers_for(action, opts)
|
19
|
+
mail headers_for(action, opts), &block
|
17
20
|
end
|
18
21
|
|
19
22
|
def initialize_from_record(record)
|
@@ -64,7 +67,7 @@ module Devise
|
|
64
67
|
template_path
|
65
68
|
end
|
66
69
|
|
67
|
-
#
|
70
|
+
# Set up a subject doing an I18n lookup. At first, it attempts to set a subject
|
68
71
|
# based on the current mapping:
|
69
72
|
#
|
70
73
|
# en:
|
data/lib/devise/mapping.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
# Responsible for handling devise mappings and routes configuration. Each
|
3
5
|
# resource configured by devise_for in routes is actually creating a mapping
|
@@ -44,7 +46,7 @@ module Devise
|
|
44
46
|
raise "Could not find a valid mapping for #{obj.inspect}"
|
45
47
|
end
|
46
48
|
|
47
|
-
def self.find_by_path!(path, path_type
|
49
|
+
def self.find_by_path!(path, path_type = :fullpath)
|
48
50
|
Devise.mappings.each_value { |m| return m if path.include?(m.send(path_type)) }
|
49
51
|
raise "Could not find a valid mapping for path #{path.inspect}"
|
50
52
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'devise/hooks/activatable'
|
3
4
|
require 'devise/hooks/csrf_cleaner'
|
5
|
+
require 'devise/rails/deprecated_constant_accessor'
|
4
6
|
|
5
7
|
module Devise
|
6
8
|
module Models
|
@@ -54,11 +56,14 @@ module Devise
|
|
54
56
|
module Authenticatable
|
55
57
|
extend ActiveSupport::Concern
|
56
58
|
|
57
|
-
|
59
|
+
UNSAFE_ATTRIBUTES_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at,
|
58
60
|
:remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip,
|
59
61
|
:last_sign_in_ip, :password_salt, :confirmation_token, :confirmed_at, :confirmation_sent_at,
|
60
62
|
:remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at]
|
61
63
|
|
64
|
+
include Devise::DeprecatedConstantAccessor
|
65
|
+
deprecate_constant "BLACKLIST_FOR_SERIALIZATION", "Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION"
|
66
|
+
|
62
67
|
included do
|
63
68
|
class_attribute :devise_modules, instance_writer: false
|
64
69
|
self.devise_modules ||= []
|
@@ -102,18 +107,27 @@ module Devise
|
|
102
107
|
# and passing a new list of attributes you want to exempt. All attributes
|
103
108
|
# given to :except will simply add names to exempt to Devise internal list.
|
104
109
|
def serializable_hash(options = nil)
|
105
|
-
options
|
106
|
-
options[:except] = Array(options[:except])
|
110
|
+
options = options.try(:dup) || {}
|
111
|
+
options[:except] = Array(options[:except]).dup
|
107
112
|
|
108
113
|
if options[:force_except]
|
109
114
|
options[:except].concat Array(options[:force_except])
|
110
115
|
else
|
111
|
-
options[:except].concat
|
116
|
+
options[:except].concat UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
|
112
117
|
end
|
113
118
|
|
114
119
|
super(options)
|
115
120
|
end
|
116
121
|
|
122
|
+
# Redefine inspect using serializable_hash, to ensure we don't accidentally
|
123
|
+
# leak passwords into exceptions.
|
124
|
+
def inspect
|
125
|
+
inspection = serializable_hash.collect do |k,v|
|
126
|
+
"#{k}: #{respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : v.inspect}"
|
127
|
+
end
|
128
|
+
"#<#{self.class} #{inspection.join(", ")}>"
|
129
|
+
end
|
130
|
+
|
117
131
|
protected
|
118
132
|
|
119
133
|
def devise_mailer
|
@@ -123,16 +137,18 @@ module Devise
|
|
123
137
|
# This is an internal method called every time Devise needs
|
124
138
|
# to send a notification/mail. This can be overridden if you
|
125
139
|
# need to customize the e-mail delivery logic. For instance,
|
126
|
-
# if you are using a queue to deliver e-mails (
|
127
|
-
# sidekiq, resque, etc), you must add the delivery to the queue
|
140
|
+
# if you are using a queue to deliver e-mails (active job, delayed
|
141
|
+
# job, sidekiq, resque, etc), you must add the delivery to the queue
|
128
142
|
# just after the transaction was committed. To achieve this,
|
129
143
|
# you can override send_devise_notification to store the
|
130
|
-
# deliveries until the after_commit callback is triggered
|
144
|
+
# deliveries until the after_commit callback is triggered.
|
145
|
+
#
|
146
|
+
# The following example uses Active Job's `deliver_later` :
|
131
147
|
#
|
132
148
|
# class User
|
133
149
|
# devise :database_authenticatable, :confirmable
|
134
150
|
#
|
135
|
-
# after_commit :
|
151
|
+
# after_commit :send_pending_devise_notifications
|
136
152
|
#
|
137
153
|
# protected
|
138
154
|
#
|
@@ -140,27 +156,45 @@ module Devise
|
|
140
156
|
# # If the record is new or changed then delay the
|
141
157
|
# # delivery until the after_commit callback otherwise
|
142
158
|
# # send now because after_commit will not be called.
|
143
|
-
#
|
144
|
-
#
|
159
|
+
# # For Rails < 6 use `changed?` instead of `saved_changes?`.
|
160
|
+
# if new_record? || saved_changes?
|
161
|
+
# pending_devise_notifications << [notification, args]
|
145
162
|
# else
|
146
|
-
#
|
163
|
+
# render_and_send_devise_message(notification, *args)
|
147
164
|
# end
|
148
165
|
# end
|
149
166
|
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
167
|
+
# private
|
168
|
+
#
|
169
|
+
# def send_pending_devise_notifications
|
170
|
+
# pending_devise_notifications.each do |notification, args|
|
171
|
+
# render_and_send_devise_message(notification, *args)
|
153
172
|
# end
|
154
173
|
#
|
155
174
|
# # Empty the pending notifications array because the
|
156
175
|
# # after_commit hook can be called multiple times which
|
157
176
|
# # could cause multiple emails to be sent.
|
158
|
-
#
|
177
|
+
# pending_devise_notifications.clear
|
159
178
|
# end
|
160
179
|
#
|
161
|
-
# def
|
162
|
-
# @
|
180
|
+
# def pending_devise_notifications
|
181
|
+
# @pending_devise_notifications ||= []
|
163
182
|
# end
|
183
|
+
#
|
184
|
+
# def render_and_send_devise_message(notification, *args)
|
185
|
+
# message = devise_mailer.send(notification, self, *args)
|
186
|
+
#
|
187
|
+
# # Deliver later with Active Job's `deliver_later`
|
188
|
+
# if message.respond_to?(:deliver_later)
|
189
|
+
# message.deliver_later
|
190
|
+
# # Remove once we move to Rails 4.2+ only, as `deliver` is deprecated.
|
191
|
+
# elsif message.respond_to?(:deliver_now)
|
192
|
+
# message.deliver_now
|
193
|
+
# else
|
194
|
+
# message.deliver
|
195
|
+
# end
|
196
|
+
# end
|
197
|
+
#
|
164
198
|
# end
|
165
199
|
#
|
166
200
|
def send_devise_notification(notification, *args)
|
@@ -235,42 +269,38 @@ module Devise
|
|
235
269
|
# end
|
236
270
|
#
|
237
271
|
# Finally, notice that Devise also queries for users in other scenarios
|
238
|
-
# besides authentication, for example when retrieving
|
272
|
+
# besides authentication, for example when retrieving a user to send
|
239
273
|
# an e-mail for password reset. In such cases, find_for_authentication
|
240
274
|
# is not called.
|
241
275
|
def find_for_authentication(tainted_conditions)
|
242
276
|
find_first_by_auth_conditions(tainted_conditions)
|
243
277
|
end
|
244
278
|
|
245
|
-
def find_first_by_auth_conditions(tainted_conditions, opts={})
|
279
|
+
def find_first_by_auth_conditions(tainted_conditions, opts = {})
|
246
280
|
to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
|
247
281
|
end
|
248
282
|
|
249
283
|
# Find or initialize a record setting an error if it can't be found.
|
250
|
-
def find_or_initialize_with_error_by(attribute, value, error
|
284
|
+
def find_or_initialize_with_error_by(attribute, value, error = :invalid) #:nodoc:
|
251
285
|
find_or_initialize_with_errors([attribute], { attribute => value }, error)
|
252
286
|
end
|
253
287
|
|
254
288
|
# Find or initialize a record with group of attributes based on a list of required attributes.
|
255
|
-
def find_or_initialize_with_errors(required_attributes, attributes, error
|
256
|
-
attributes
|
257
|
-
attributes
|
289
|
+
def find_or_initialize_with_errors(required_attributes, attributes, error = :invalid) #:nodoc:
|
290
|
+
attributes.try(:permit!)
|
291
|
+
attributes = attributes.to_h.with_indifferent_access
|
292
|
+
.slice(*required_attributes)
|
293
|
+
.delete_if { |key, value| value.blank? }
|
258
294
|
|
259
295
|
if attributes.size == required_attributes.size
|
260
|
-
record = find_first_by_auth_conditions(attributes)
|
296
|
+
record = find_first_by_auth_conditions(attributes) and return record
|
261
297
|
end
|
262
298
|
|
263
|
-
|
264
|
-
record = new
|
265
|
-
|
299
|
+
new(devise_parameter_filter.filter(attributes)).tap do |record|
|
266
300
|
required_attributes.each do |key|
|
267
|
-
|
268
|
-
record.send("#{key}=", value)
|
269
|
-
record.errors.add(key, value.present? ? error : :blank)
|
301
|
+
record.errors.add(key, attributes[key].blank? ? :blank : error)
|
270
302
|
end
|
271
303
|
end
|
272
|
-
|
273
|
-
record
|
274
304
|
end
|
275
305
|
|
276
306
|
protected
|