devise 3.2.4 → 4.7.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 (235) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +259 -994
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +336 -99
  5. data/app/controllers/devise/confirmations_controller.rb +9 -3
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  7. data/app/controllers/devise/passwords_controller.rb +19 -6
  8. data/app/controllers/devise/registrations_controller.rb +55 -22
  9. data/app/controllers/devise/sessions_controller.rb +44 -14
  10. data/app/controllers/devise/unlocks_controller.rb +7 -2
  11. data/app/controllers/devise_controller.rb +65 -29
  12. data/app/helpers/devise_helper.rb +12 -19
  13. data/app/mailers/devise/mailer.rb +10 -0
  14. data/app/views/devise/confirmations/new.html.erb +8 -4
  15. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  16. data/app/views/devise/mailer/password_change.html.erb +3 -0
  17. data/app/views/devise/passwords/edit.html.erb +15 -6
  18. data/app/views/devise/passwords/new.html.erb +8 -4
  19. data/app/views/devise/registrations/edit.html.erb +27 -13
  20. data/app/views/devise/registrations/new.html.erb +19 -8
  21. data/app/views/devise/sessions/new.html.erb +18 -9
  22. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  23. data/app/views/devise/shared/{_links.erb → _links.html.erb} +9 -9
  24. data/app/views/devise/unlocks/new.html.erb +8 -4
  25. data/config/locales/en.yml +22 -16
  26. data/lib/devise/controllers/helpers.rb +109 -29
  27. data/lib/devise/controllers/rememberable.rb +12 -3
  28. data/lib/devise/controllers/scoped_views.rb +2 -0
  29. data/lib/devise/controllers/sign_in_out.rb +36 -20
  30. data/lib/devise/controllers/store_location.rb +31 -5
  31. data/lib/devise/controllers/url_helpers.rb +9 -7
  32. data/lib/devise/delegator.rb +2 -0
  33. data/lib/devise/encryptor.rb +24 -0
  34. data/lib/devise/failure_app.rb +116 -36
  35. data/lib/devise/hooks/activatable.rb +5 -4
  36. data/lib/devise/hooks/csrf_cleaner.rb +5 -1
  37. data/lib/devise/hooks/forgetable.rb +2 -0
  38. data/lib/devise/hooks/lockable.rb +6 -1
  39. data/lib/devise/hooks/proxy.rb +3 -1
  40. data/lib/devise/hooks/rememberable.rb +2 -0
  41. data/lib/devise/hooks/timeoutable.rb +15 -8
  42. data/lib/devise/hooks/trackable.rb +2 -0
  43. data/lib/devise/mailers/helpers.rb +7 -4
  44. data/lib/devise/mapping.rb +8 -2
  45. data/lib/devise/models/authenticatable.rb +76 -51
  46. data/lib/devise/models/confirmable.rb +129 -34
  47. data/lib/devise/models/database_authenticatable.rb +107 -30
  48. data/lib/devise/models/lockable.rb +19 -9
  49. data/lib/devise/models/omniauthable.rb +2 -0
  50. data/lib/devise/models/recoverable.rb +62 -26
  51. data/lib/devise/models/registerable.rb +4 -0
  52. data/lib/devise/models/rememberable.rb +58 -29
  53. data/lib/devise/models/timeoutable.rb +2 -6
  54. data/lib/devise/models/trackable.rb +20 -4
  55. data/lib/devise/models/validatable.rb +12 -5
  56. data/lib/devise/models.rb +3 -1
  57. data/lib/devise/modules.rb +2 -0
  58. data/lib/devise/omniauth/config.rb +2 -0
  59. data/lib/devise/omniauth/url_helpers.rb +14 -5
  60. data/lib/devise/omniauth.rb +2 -0
  61. data/lib/devise/orm/active_record.rb +5 -1
  62. data/lib/devise/orm/mongoid.rb +6 -2
  63. data/lib/devise/parameter_filter.rb +4 -0
  64. data/lib/devise/parameter_sanitizer.rb +139 -65
  65. data/lib/devise/rails/routes.rb +80 -61
  66. data/lib/devise/rails/warden_compat.rb +3 -10
  67. data/lib/devise/rails.rb +8 -17
  68. data/lib/devise/secret_key_finder.rb +27 -0
  69. data/lib/devise/strategies/authenticatable.rb +18 -7
  70. data/lib/devise/strategies/base.rb +2 -0
  71. data/lib/devise/strategies/database_authenticatable.rb +13 -5
  72. data/lib/devise/strategies/rememberable.rb +15 -3
  73. data/lib/devise/test/controller_helpers.rb +165 -0
  74. data/lib/devise/test/integration_helpers.rb +63 -0
  75. data/lib/devise/test_helpers.rb +7 -124
  76. data/lib/devise/time_inflector.rb +2 -0
  77. data/lib/devise/token_generator.rb +3 -41
  78. data/lib/devise/version.rb +3 -1
  79. data/lib/devise.rb +106 -79
  80. data/lib/generators/active_record/devise_generator.rb +44 -7
  81. data/lib/generators/active_record/templates/migration.rb +5 -3
  82. data/lib/generators/active_record/templates/migration_existing.rb +5 -3
  83. data/lib/generators/devise/controllers_generator.rb +46 -0
  84. data/lib/generators/devise/devise_generator.rb +4 -2
  85. data/lib/generators/devise/install_generator.rb +17 -0
  86. data/lib/generators/devise/orm_helpers.rb +10 -21
  87. data/lib/generators/devise/views_generator.rb +21 -11
  88. data/lib/generators/mongoid/devise_generator.rb +7 -5
  89. data/lib/generators/templates/README +2 -9
  90. data/lib/generators/templates/controllers/README +14 -0
  91. data/lib/generators/templates/controllers/confirmations_controller.rb +30 -0
  92. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +30 -0
  93. data/lib/generators/templates/controllers/passwords_controller.rb +34 -0
  94. data/lib/generators/templates/controllers/registrations_controller.rb +62 -0
  95. data/lib/generators/templates/controllers/sessions_controller.rb +27 -0
  96. data/lib/generators/templates/controllers/unlocks_controller.rb +30 -0
  97. data/lib/generators/templates/devise.rb +69 -30
  98. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  99. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  100. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  101. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  102. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  103. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
  104. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +10 -2
  105. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +4 -1
  106. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
  107. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
  108. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +9 -4
  109. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
  110. metadata +31 -259
  111. data/.gitignore +0 -11
  112. data/.travis.yml +0 -28
  113. data/.yardopts +0 -9
  114. data/CONTRIBUTING.md +0 -14
  115. data/Gemfile +0 -29
  116. data/Gemfile.lock +0 -160
  117. data/Rakefile +0 -35
  118. data/devise.gemspec +0 -27
  119. data/devise.png +0 -0
  120. data/gemfiles/Gemfile.rails-3.2-stable +0 -29
  121. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
  122. data/gemfiles/Gemfile.rails-head +0 -29
  123. data/test/controllers/custom_strategy_test.rb +0 -62
  124. data/test/controllers/helpers_test.rb +0 -276
  125. data/test/controllers/internal_helpers_test.rb +0 -123
  126. data/test/controllers/passwords_controller_test.rb +0 -31
  127. data/test/controllers/sessions_controller_test.rb +0 -103
  128. data/test/controllers/url_helpers_test.rb +0 -59
  129. data/test/delegator_test.rb +0 -19
  130. data/test/devise_test.rb +0 -94
  131. data/test/failure_app_test.rb +0 -232
  132. data/test/generators/active_record_generator_test.rb +0 -103
  133. data/test/generators/devise_generator_test.rb +0 -39
  134. data/test/generators/install_generator_test.rb +0 -13
  135. data/test/generators/mongoid_generator_test.rb +0 -23
  136. data/test/generators/views_generator_test.rb +0 -96
  137. data/test/helpers/devise_helper_test.rb +0 -51
  138. data/test/integration/authenticatable_test.rb +0 -713
  139. data/test/integration/confirmable_test.rb +0 -284
  140. data/test/integration/database_authenticatable_test.rb +0 -84
  141. data/test/integration/http_authenticatable_test.rb +0 -105
  142. data/test/integration/lockable_test.rb +0 -239
  143. data/test/integration/omniauthable_test.rb +0 -133
  144. data/test/integration/recoverable_test.rb +0 -334
  145. data/test/integration/registerable_test.rb +0 -349
  146. data/test/integration/rememberable_test.rb +0 -167
  147. data/test/integration/timeoutable_test.rb +0 -183
  148. data/test/integration/trackable_test.rb +0 -92
  149. data/test/mailers/confirmation_instructions_test.rb +0 -115
  150. data/test/mailers/reset_password_instructions_test.rb +0 -96
  151. data/test/mailers/unlock_instructions_test.rb +0 -91
  152. data/test/mapping_test.rb +0 -127
  153. data/test/models/authenticatable_test.rb +0 -13
  154. data/test/models/confirmable_test.rb +0 -454
  155. data/test/models/database_authenticatable_test.rb +0 -249
  156. data/test/models/lockable_test.rb +0 -316
  157. data/test/models/omniauthable_test.rb +0 -7
  158. data/test/models/recoverable_test.rb +0 -184
  159. data/test/models/registerable_test.rb +0 -7
  160. data/test/models/rememberable_test.rb +0 -183
  161. data/test/models/serializable_test.rb +0 -49
  162. data/test/models/timeoutable_test.rb +0 -51
  163. data/test/models/trackable_test.rb +0 -13
  164. data/test/models/validatable_test.rb +0 -127
  165. data/test/models_test.rb +0 -144
  166. data/test/omniauth/config_test.rb +0 -57
  167. data/test/omniauth/url_helpers_test.rb +0 -54
  168. data/test/orm/active_record.rb +0 -10
  169. data/test/orm/mongoid.rb +0 -13
  170. data/test/parameter_sanitizer_test.rb +0 -81
  171. data/test/rails_app/Rakefile +0 -6
  172. data/test/rails_app/app/active_record/admin.rb +0 -6
  173. data/test/rails_app/app/active_record/shim.rb +0 -2
  174. data/test/rails_app/app/active_record/user.rb +0 -6
  175. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  176. data/test/rails_app/app/controllers/admins_controller.rb +0 -11
  177. data/test/rails_app/app/controllers/application_controller.rb +0 -9
  178. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  179. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  180. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  181. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  182. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  183. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  184. data/test/rails_app/app/mailers/users/mailer.rb +0 -12
  185. data/test/rails_app/app/mongoid/admin.rb +0 -29
  186. data/test/rails_app/app/mongoid/shim.rb +0 -23
  187. data/test/rails_app/app/mongoid/user.rb +0 -39
  188. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  189. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  190. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  191. data/test/rails_app/app/views/home/index.html.erb +0 -1
  192. data/test/rails_app/app/views/home/join.html.erb +0 -1
  193. data/test/rails_app/app/views/home/private.html.erb +0 -1
  194. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  195. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  196. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  197. data/test/rails_app/app/views/users/index.html.erb +0 -1
  198. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  199. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  200. data/test/rails_app/bin/bundle +0 -3
  201. data/test/rails_app/bin/rails +0 -4
  202. data/test/rails_app/bin/rake +0 -4
  203. data/test/rails_app/config/application.rb +0 -40
  204. data/test/rails_app/config/boot.rb +0 -14
  205. data/test/rails_app/config/database.yml +0 -18
  206. data/test/rails_app/config/environment.rb +0 -5
  207. data/test/rails_app/config/environments/development.rb +0 -30
  208. data/test/rails_app/config/environments/production.rb +0 -80
  209. data/test/rails_app/config/environments/test.rb +0 -36
  210. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  211. data/test/rails_app/config/initializers/devise.rb +0 -181
  212. data/test/rails_app/config/initializers/inflections.rb +0 -2
  213. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  214. data/test/rails_app/config/initializers/session_store.rb +0 -1
  215. data/test/rails_app/config/routes.rb +0 -105
  216. data/test/rails_app/config.ru +0 -4
  217. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  218. data/test/rails_app/db/schema.rb +0 -55
  219. data/test/rails_app/lib/shared_admin.rb +0 -17
  220. data/test/rails_app/lib/shared_user.rb +0 -29
  221. data/test/rails_app/public/404.html +0 -26
  222. data/test/rails_app/public/422.html +0 -26
  223. data/test/rails_app/public/500.html +0 -26
  224. data/test/rails_app/public/favicon.ico +0 -0
  225. data/test/routes_test.rb +0 -262
  226. data/test/support/action_controller/record_identifier.rb +0 -10
  227. data/test/support/assertions.rb +0 -40
  228. data/test/support/helpers.rb +0 -70
  229. data/test/support/integration.rb +0 -92
  230. data/test/support/locale/en.yml +0 -8
  231. data/test/support/mongoid.yml +0 -6
  232. data/test/support/webrat/integrations/rails.rb +0 -24
  233. data/test/test_helper.rb +0 -27
  234. data/test/test_helpers_test.rb +0 -173
  235. data/test/test_models.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::ConfirmationsController < DeviseController
2
4
  # GET /resource/confirmation/new
3
5
  def new
@@ -22,7 +24,7 @@ class Devise::ConfirmationsController < DeviseController
22
24
  yield resource if block_given?
23
25
 
24
26
  if resource.errors.empty?
25
- set_flash_message(:notice, :confirmed) if is_flashing_format?
27
+ set_flash_message!(:notice, :confirmed)
26
28
  respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
27
29
  else
28
30
  respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
@@ -33,15 +35,19 @@ class Devise::ConfirmationsController < DeviseController
33
35
 
34
36
  # The path used after resending confirmation instructions.
35
37
  def after_resending_confirmation_instructions_path_for(resource_name)
36
- new_session_path(resource_name) if is_navigational_format?
38
+ is_navigational_format? ? new_session_path(resource_name) : '/'
37
39
  end
38
40
 
39
41
  # The path used after confirmation.
40
42
  def after_confirmation_path_for(resource_name, resource)
41
- if signed_in?
43
+ if signed_in?(resource_name)
42
44
  signed_in_root_path(resource)
43
45
  else
44
46
  new_session_path(resource_name)
45
47
  end
46
48
  end
49
+
50
+ def translation_scope
51
+ 'devise.confirmations'
52
+ end
47
53
  end
@@ -1,30 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::OmniauthCallbacksController < DeviseController
2
- prepend_before_filter { request.env["devise.skip_timeout"] = true }
4
+ prepend_before_action { request.env["devise.skip_timeout"] = true }
3
5
 
4
6
  def passthru
5
- render status: 404, text: "Not found. Authentication passthru."
7
+ render status: 404, plain: "Not found. Authentication passthru."
6
8
  end
7
9
 
8
10
  def failure
9
- set_flash_message :alert, :failure, kind: OmniAuth::Utils.camelize(failed_strategy.name), reason: failure_message
11
+ set_flash_message! :alert, :failure, kind: OmniAuth::Utils.camelize(failed_strategy.name), reason: failure_message
10
12
  redirect_to after_omniauth_failure_path_for(resource_name)
11
13
  end
12
14
 
13
15
  protected
14
16
 
15
17
  def failed_strategy
16
- env["omniauth.error.strategy"]
18
+ request.respond_to?(:get_header) ? request.get_header("omniauth.error.strategy") : request.env["omniauth.error.strategy"]
17
19
  end
18
20
 
19
21
  def failure_message
20
- exception = env["omniauth.error"]
22
+ exception = request.respond_to?(:get_header) ? request.get_header("omniauth.error") : request.env["omniauth.error"]
21
23
  error = exception.error_reason if exception.respond_to?(:error_reason)
22
24
  error ||= exception.error if exception.respond_to?(:error)
23
- error ||= env["omniauth.error.type"].to_s
25
+ error ||= (request.respond_to?(:get_header) ? request.get_header("omniauth.error.type") : request.env["omniauth.error.type"]).to_s
24
26
  error.to_s.humanize if error
25
27
  end
26
28
 
27
29
  def after_omniauth_failure_path_for(scope)
28
30
  new_session_path(scope)
29
31
  end
32
+
33
+ def translation_scope
34
+ 'devise.omniauth_callbacks'
35
+ end
30
36
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::PasswordsController < DeviseController
2
- prepend_before_filter :require_no_authentication
4
+ prepend_before_action :require_no_authentication
3
5
  # Render the #edit only if coming from a reset password email link
4
- append_before_filter :assert_reset_token_passed, only: :edit
6
+ append_before_action :assert_reset_token_passed, only: :edit
5
7
 
6
8
  # GET /resource/password/new
7
9
  def new
@@ -23,6 +25,7 @@ class Devise::PasswordsController < DeviseController
23
25
  # GET /resource/password/edit?reset_password_token=abcdef
24
26
  def edit
25
27
  self.resource = resource_class.new
28
+ set_minimum_password_length
26
29
  resource.reset_password_token = params[:reset_password_token]
27
30
  end
28
31
 
@@ -33,18 +36,24 @@ class Devise::PasswordsController < DeviseController
33
36
 
34
37
  if resource.errors.empty?
35
38
  resource.unlock_access! if unlockable?(resource)
36
- flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
37
- set_flash_message(:notice, flash_message) if is_flashing_format?
38
- sign_in(resource_name, resource)
39
+ if Devise.sign_in_after_reset_password
40
+ flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
41
+ set_flash_message!(:notice, flash_message)
42
+ resource.after_database_authentication
43
+ sign_in(resource_name, resource)
44
+ else
45
+ set_flash_message!(:notice, :updated_not_active)
46
+ end
39
47
  respond_with resource, location: after_resetting_password_path_for(resource)
40
48
  else
49
+ set_minimum_password_length
41
50
  respond_with resource
42
51
  end
43
52
  end
44
53
 
45
54
  protected
46
55
  def after_resetting_password_path_for(resource)
47
- after_sign_in_path_for(resource)
56
+ Devise.sign_in_after_reset_password ? after_sign_in_path_for(resource) : new_session_path(resource_name)
48
57
  end
49
58
 
50
59
  # The path used after sending reset password instructions
@@ -67,4 +76,8 @@ class Devise::PasswordsController < DeviseController
67
76
  resource.respond_to?(:unlock_strategy_enabled?) &&
68
77
  resource.unlock_strategy_enabled?(:email)
69
78
  end
79
+
80
+ def translation_scope
81
+ 'devise.passwords'
82
+ end
70
83
  end
@@ -1,30 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::RegistrationsController < DeviseController
2
- prepend_before_filter :require_no_authentication, only: [ :new, :create, :cancel ]
3
- prepend_before_filter :authenticate_scope!, only: [:edit, :update, :destroy]
4
+ prepend_before_action :require_no_authentication, only: [:new, :create, :cancel]
5
+ prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]
6
+ prepend_before_action :set_minimum_password_length, only: [:new, :edit]
4
7
 
5
8
  # GET /resource/sign_up
6
9
  def new
7
- build_resource({})
8
- respond_with self.resource
10
+ build_resource
11
+ yield resource if block_given?
12
+ respond_with resource
9
13
  end
10
14
 
11
15
  # POST /resource
12
16
  def create
13
17
  build_resource(sign_up_params)
14
18
 
15
- if resource.save
16
- yield resource if block_given?
19
+ resource.save
20
+ yield resource if block_given?
21
+ if resource.persisted?
17
22
  if resource.active_for_authentication?
18
- set_flash_message :notice, :signed_up if is_flashing_format?
23
+ set_flash_message! :notice, :signed_up
19
24
  sign_up(resource_name, resource)
20
25
  respond_with resource, location: after_sign_up_path_for(resource)
21
26
  else
22
- set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
27
+ set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
23
28
  expire_data_after_sign_in!
24
29
  respond_with resource, location: after_inactive_sign_up_path_for(resource)
25
30
  end
26
31
  else
27
32
  clean_up_passwords resource
33
+ set_minimum_password_length
28
34
  respond_with resource
29
35
  end
30
36
  end
@@ -41,17 +47,16 @@ class Devise::RegistrationsController < DeviseController
41
47
  self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
42
48
  prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
43
49
 
44
- if update_resource(resource, account_update_params)
45
- yield resource if block_given?
46
- if is_flashing_format?
47
- flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
48
- :update_needs_confirmation : :updated
49
- set_flash_message :notice, flash_key
50
- end
51
- sign_in resource_name, resource, bypass: true
50
+ resource_updated = update_resource(resource, account_update_params)
51
+ yield resource if block_given?
52
+ if resource_updated
53
+ set_flash_message_for_update(resource, prev_unconfirmed_email)
54
+ bypass_sign_in resource, scope: resource_name if sign_in_after_change_password?
55
+
52
56
  respond_with resource, location: after_update_path_for(resource)
53
57
  else
54
58
  clean_up_passwords resource
59
+ set_minimum_password_length
55
60
  respond_with resource
56
61
  end
57
62
  end
@@ -60,7 +65,7 @@ class Devise::RegistrationsController < DeviseController
60
65
  def destroy
61
66
  resource.destroy
62
67
  Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
63
- set_flash_message :notice, :destroyed if is_flashing_format?
68
+ set_flash_message! :notice, :destroyed
64
69
  yield resource if block_given?
65
70
  respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
66
71
  end
@@ -91,8 +96,8 @@ class Devise::RegistrationsController < DeviseController
91
96
 
92
97
  # Build a devise resource passing in the session. Useful to move
93
98
  # temporary session data to the newly created user.
94
- def build_resource(hash=nil)
95
- self.resource = resource_class.new_with_session(hash || {}, session)
99
+ def build_resource(hash = {})
100
+ self.resource = resource_class.new_with_session(hash, session)
96
101
  end
97
102
 
98
103
  # Signs in a user on sign up. You can overwrite this method in your own
@@ -104,19 +109,22 @@ class Devise::RegistrationsController < DeviseController
104
109
  # The path used after sign up. You need to overwrite this method
105
110
  # in your own RegistrationsController.
106
111
  def after_sign_up_path_for(resource)
107
- after_sign_in_path_for(resource)
112
+ after_sign_in_path_for(resource) if is_navigational_format?
108
113
  end
109
114
 
110
115
  # The path used after sign up for inactive accounts. You need to overwrite
111
116
  # this method in your own RegistrationsController.
112
117
  def after_inactive_sign_up_path_for(resource)
113
- respond_to?(:root_path) ? root_path : "/"
118
+ scope = Devise::Mapping.find_scope!(resource)
119
+ router_name = Devise.mappings[scope].router_name
120
+ context = router_name ? send(router_name) : self
121
+ context.respond_to?(:root_path) ? context.root_path : "/"
114
122
  end
115
123
 
116
124
  # The default url to be used after updating a resource. You need to overwrite
117
125
  # this method in your own RegistrationsController.
118
126
  def after_update_path_for(resource)
119
- signed_in_root_path(resource)
127
+ sign_in_after_change_password? ? signed_in_root_path(resource) : new_session_path(resource_name)
120
128
  end
121
129
 
122
130
  # Authenticates the current scope and gets the current resource from the session.
@@ -132,4 +140,29 @@ class Devise::RegistrationsController < DeviseController
132
140
  def account_update_params
133
141
  devise_parameter_sanitizer.sanitize(:account_update)
134
142
  end
143
+
144
+ def translation_scope
145
+ 'devise.registrations'
146
+ end
147
+
148
+ private
149
+
150
+ def set_flash_message_for_update(resource, prev_unconfirmed_email)
151
+ return unless is_flashing_format?
152
+
153
+ flash_key = if update_needs_confirmation?(resource, prev_unconfirmed_email)
154
+ :update_needs_confirmation
155
+ elsif sign_in_after_change_password?
156
+ :updated
157
+ else
158
+ :updated_but_not_signed_in
159
+ end
160
+ set_flash_message :notice, flash_key
161
+ end
162
+
163
+ def sign_in_after_change_password?
164
+ return true if account_update_params[:password].blank?
165
+
166
+ Devise.sign_in_after_change_password
167
+ end
135
168
  end
@@ -1,19 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::SessionsController < DeviseController
2
- prepend_before_filter :require_no_authentication, only: [ :new, :create ]
3
- prepend_before_filter :allow_params_authentication!, only: :create
4
- prepend_before_filter only: [ :create, :destroy ] { request.env["devise.skip_timeout"] = true }
4
+ prepend_before_action :require_no_authentication, only: [:new, :create]
5
+ prepend_before_action :allow_params_authentication!, only: :create
6
+ prepend_before_action :verify_signed_out_user, only: :destroy
7
+ prepend_before_action(only: [:create, :destroy]) { request.env["devise.skip_timeout"] = true }
5
8
 
6
9
  # GET /resource/sign_in
7
10
  def new
8
11
  self.resource = resource_class.new(sign_in_params)
9
12
  clean_up_passwords(resource)
13
+ yield resource if block_given?
10
14
  respond_with(resource, serialize_options(resource))
11
15
  end
12
16
 
13
17
  # POST /resource/sign_in
14
18
  def create
15
19
  self.resource = warden.authenticate!(auth_options)
16
- set_flash_message(:notice, :signed_in) if is_flashing_format?
20
+ set_flash_message!(:notice, :signed_in)
17
21
  sign_in(resource_name, resource)
18
22
  yield resource if block_given?
19
23
  respond_with resource, location: after_sign_in_path_for(resource)
@@ -21,17 +25,10 @@ class Devise::SessionsController < DeviseController
21
25
 
22
26
  # DELETE /resource/sign_out
23
27
  def destroy
24
- redirect_path = after_sign_out_path_for(resource_name)
25
28
  signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
26
- set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
27
- yield resource if block_given?
28
-
29
- # We actually need to hardcode this as Rails default responder doesn't
30
- # support returning empty response on GET request
31
- respond_to do |format|
32
- format.all { head :no_content }
33
- format.any(*navigational_formats) { redirect_to redirect_path }
34
- end
29
+ set_flash_message! :notice, :signed_out if signed_out
30
+ yield if block_given?
31
+ respond_to_on_destroy
35
32
  end
36
33
 
37
34
  protected
@@ -50,4 +47,37 @@ class Devise::SessionsController < DeviseController
50
47
  def auth_options
51
48
  { scope: resource_name, recall: "#{controller_path}#new" }
52
49
  end
50
+
51
+ def translation_scope
52
+ 'devise.sessions'
53
+ end
54
+
55
+ private
56
+
57
+ # Check if there is no signed in user before doing the sign out.
58
+ #
59
+ # If there is no signed in user, it will set the flash message and redirect
60
+ # to the after_sign_out path.
61
+ def verify_signed_out_user
62
+ if all_signed_out?
63
+ set_flash_message! :notice, :already_signed_out
64
+
65
+ respond_to_on_destroy
66
+ end
67
+ end
68
+
69
+ def all_signed_out?
70
+ users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
71
+
72
+ users.all?(&:blank?)
73
+ end
74
+
75
+ def respond_to_on_destroy
76
+ # We actually need to hardcode this as Rails default responder doesn't
77
+ # support returning empty response on GET request
78
+ respond_to do |format|
79
+ format.all { head :no_content }
80
+ format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
81
+ end
82
+ end
53
83
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::UnlocksController < DeviseController
2
- prepend_before_filter :require_no_authentication
4
+ prepend_before_action :require_no_authentication
3
5
 
4
6
  # GET /resource/unlock/new
5
7
  def new
@@ -24,7 +26,7 @@ class Devise::UnlocksController < DeviseController
24
26
  yield resource if block_given?
25
27
 
26
28
  if resource.errors.empty?
27
- set_flash_message :notice, :unlocked if is_flashing_format?
29
+ set_flash_message! :notice, :unlocked
28
30
  respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
29
31
  else
30
32
  respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
@@ -43,4 +45,7 @@ class Devise::UnlocksController < DeviseController
43
45
  new_session_path(resource) if is_navigational_format?
44
46
  end
45
47
 
48
+ def translation_scope
49
+ 'devise.unlocks'
50
+ end
46
51
  end
@@ -1,17 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # All Devise controllers are inherited from here.
2
4
  class DeviseController < Devise.parent_controller.constantize
3
5
  include Devise::Controllers::ScopedViews
4
6
 
5
- helper DeviseHelper
7
+ if respond_to?(:helper)
8
+ helper DeviseHelper
9
+ end
6
10
 
7
- helpers = %w(resource scope_name resource_name signed_in_resource
8
- resource_class resource_params devise_mapping)
9
- hide_action *helpers
10
- helper_method *helpers
11
+ if respond_to?(:helper_method)
12
+ helpers = %w(resource scope_name resource_name signed_in_resource
13
+ resource_class resource_params devise_mapping)
14
+ helper_method(*helpers)
15
+ end
11
16
 
12
- prepend_before_filter :assert_is_devise_resource!
17
+ prepend_before_action :assert_is_devise_resource!
13
18
  respond_to :html if mimes_for_respond_to.empty?
14
19
 
20
+ # Override prefixes to consider the scoped view.
21
+ # Notice we need to check for the request due to a bug in
22
+ # Action Controller tests that forces _prefixes to be
23
+ # loaded before even having a request object.
24
+ #
25
+ # This method should be public as it is in ActionPack
26
+ # itself. Changing its visibility may break other gems.
27
+ def _prefixes #:nodoc:
28
+ @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
29
+ ["#{devise_mapping.scoped_path}/#{controller_name}"] + super
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ protected
36
+
15
37
  # Gets the actual resource stored in the instance variable
16
38
  def resource
17
39
  instance_variable_get(:"@#{resource_name}")
@@ -38,22 +60,6 @@ class DeviseController < Devise.parent_controller.constantize
38
60
  @devise_mapping ||= request.env["devise.mapping"]
39
61
  end
40
62
 
41
- # Override prefixes to consider the scoped view.
42
- # Notice we need to check for the request due to a bug in
43
- # Action Controller tests that forces _prefixes to be
44
- # loaded before even having a request object.
45
- def _prefixes #:nodoc:
46
- @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
47
- super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
48
- else
49
- super
50
- end
51
- end
52
-
53
- hide_action :_prefixes
54
-
55
- protected
56
-
57
63
  # Checks whether it's a devise mapped resource or not.
58
64
  def assert_is_devise_resource! #:nodoc:
59
65
  unknown_action! <<-MESSAGE unless devise_mapping
@@ -89,10 +95,10 @@ MESSAGE
89
95
  instance_variable_set(:"@#{resource_name}", new_resource)
90
96
  end
91
97
 
92
- # Helper for use in before_filters where no authentication is required.
98
+ # Helper for use in before_actions where no authentication is required.
93
99
  #
94
100
  # Example:
95
- # before_filter :require_no_authentication, only: :new
101
+ # before_action :require_no_authentication, only: :new
96
102
  def require_no_authentication
97
103
  assert_is_devise_resource!
98
104
  return unless is_navigational_format?
@@ -123,14 +129,17 @@ MESSAGE
123
129
  end
124
130
 
125
131
  if notice
126
- set_flash_message :notice, notice if is_flashing_format?
132
+ set_flash_message! :notice, notice
127
133
  true
128
134
  end
129
135
  end
130
136
 
131
137
  # Sets the flash message with :key, using I18n. By default you are able
132
- # to setup your messages using specific resource scope, and if no one is
133
- # found we look to default scope.
138
+ # to set up your messages using specific resource scope, and if no message is
139
+ # found we look to the default scope. Set the "now" options key to a true
140
+ # value to populate the flash.now hash in lieu of the default flash hash (so
141
+ # the flash message will be available to the current action instead of the
142
+ # next action).
134
143
  # Example (i18n locale file):
135
144
  #
136
145
  # en:
@@ -144,7 +153,25 @@ MESSAGE
144
153
  # available.
145
154
  def set_flash_message(key, kind, options = {})
146
155
  message = find_message(kind, options)
147
- flash[key] = message if message.present?
156
+ if options[:now]
157
+ flash.now[key] = message if message.present?
158
+ else
159
+ flash[key] = message if message.present?
160
+ end
161
+ end
162
+
163
+ # Sets flash message if is_flashing_format? equals true
164
+ def set_flash_message!(key, kind, options = {})
165
+ if is_flashing_format?
166
+ set_flash_message(key, kind, options)
167
+ end
168
+ end
169
+
170
+ # Sets minimum password length to show to user
171
+ def set_minimum_password_length
172
+ if devise_mapping.validatable?
173
+ @minimum_password_length = resource_class.password_length.min
174
+ end
148
175
  end
149
176
 
150
177
  def devise_i18n_options(options)
@@ -153,13 +180,20 @@ MESSAGE
153
180
 
154
181
  # Get message for given
155
182
  def find_message(kind, options = {})
156
- options[:scope] = "devise.#{controller_name}"
183
+ options[:scope] ||= translation_scope
157
184
  options[:default] = Array(options[:default]).unshift(kind.to_sym)
158
185
  options[:resource_name] = resource_name
159
186
  options = devise_i18n_options(options)
160
187
  I18n.t("#{options[:resource_name]}.#{kind}", options)
161
188
  end
162
189
 
190
+ # Controllers inheriting DeviseController are advised to override this
191
+ # method so that other controllers inheriting from them would use
192
+ # existing translations.
193
+ def translation_scope
194
+ "devise.#{controller_name}"
195
+ end
196
+
163
197
  def clean_up_passwords(object)
164
198
  object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
165
199
  end
@@ -173,4 +207,6 @@ MESSAGE
173
207
  def resource_params
174
208
  params.fetch(resource_name, {})
175
209
  end
210
+
211
+ ActiveSupport.run_load_hooks(:devise_controller, self)
176
212
  end
@@ -1,25 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DeviseHelper
2
- # A simple way to show error messages for the current devise resource. If you need
3
- # to customize this method, you can either overwrite it in your application helpers or
4
- # copy the views to your application.
5
- #
6
- # This method is intended to stay simple and it is unlikely that we are going to change
7
- # it to add more behavior or options.
4
+ # Retain this method for backwards compatibility, deprecated in favour of modifying the
5
+ # devise/shared/error_messages partial
8
6
  def devise_error_messages!
9
- return "" if resource.errors.empty?
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.
12
+ DEPRECATION
10
13
 
11
- messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
12
- sentence = I18n.t("errors.messages.not_saved",
13
- count: resource.errors.count,
14
- resource: resource.class.model_name.human.downcase)
15
-
16
- html = <<-HTML
17
- <div id="error_explanation">
18
- <h2>#{sentence}</h2>
19
- <ul>#{messages}</ul>
20
- </div>
21
- HTML
14
+ return "" if resource.errors.empty?
22
15
 
23
- html.html_safe
16
+ render "devise/shared/error_messages", resource: resource
24
17
  end
25
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if defined?(ActionMailer)
2
4
  class Devise::Mailer < Devise.parent_mailer.constantize
3
5
  include Devise::Mailers::Helpers
@@ -16,5 +18,13 @@ if defined?(ActionMailer)
16
18
  @token = token
17
19
  devise_mail(record, :unlock_instructions, opts)
18
20
  end
21
+
22
+ def email_changed(record, opts={})
23
+ devise_mail(record, :email_changed, opts)
24
+ end
25
+
26
+ def password_change(record, opts={})
27
+ devise_mail(record, :password_change, opts)
28
+ end
19
29
  end
20
30
  end
@@ -1,12 +1,16 @@
1
1
  <h2>Resend confirmation instructions</h2>
2
2
 
3
3
  <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4
- <%= devise_error_messages! %>
4
+ <%= render "devise/shared/error_messages", resource: resource %>
5
5
 
6
- <div><%= f.label :email %><br />
7
- <%= f.email_field :email, autofocus: true %></div>
6
+ <div class="field">
7
+ <%= f.label :email %><br />
8
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
9
+ </div>
8
10
 
9
- <div><%= f.submit "Resend confirmation instructions" %></div>
11
+ <div class="actions">
12
+ <%= f.submit "Resend confirmation instructions" %>
13
+ </div>
10
14
  <% end %>
11
15
 
12
16
  <%= render "devise/shared/links" %>
@@ -0,0 +1,7 @@
1
+ <p>Hello <%= @email %>!</p>
2
+
3
+ <% if @resource.try(:unconfirmed_email?) %>
4
+ <p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
5
+ <% else %>
6
+ <p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
7
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>We're contacting you to notify you that your password has been changed.</p>