devise 3.2.4 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +33 -17
  4. data/CHANGELOG.md +57 -1033
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +2 -0
  7. data/Gemfile +5 -5
  8. data/Gemfile.lock +138 -115
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +124 -65
  11. data/Rakefile +2 -1
  12. data/app/controllers/devise/confirmations_controller.rb +7 -3
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -4
  14. data/app/controllers/devise/passwords_controller.rb +16 -6
  15. data/app/controllers/devise/registrations_controller.rb +22 -10
  16. data/app/controllers/devise/sessions_controller.rb +42 -14
  17. data/app/controllers/devise/unlocks_controller.rb +5 -2
  18. data/app/controllers/devise_controller.rb +63 -29
  19. data/app/mailers/devise/mailer.rb +4 -0
  20. data/app/views/devise/confirmations/new.html.erb +7 -3
  21. data/app/views/devise/mailer/password_change.html.erb +3 -0
  22. data/app/views/devise/passwords/edit.html.erb +14 -5
  23. data/app/views/devise/passwords/new.html.erb +7 -3
  24. data/app/views/devise/registrations/edit.html.erb +19 -9
  25. data/app/views/devise/registrations/new.html.erb +18 -7
  26. data/app/views/devise/sessions/new.html.erb +16 -7
  27. data/app/views/devise/shared/{_links.erb → _links.html.erb} +2 -2
  28. data/app/views/devise/unlocks/new.html.erb +7 -3
  29. data/bin/test +13 -0
  30. data/config/locales/en.yml +19 -16
  31. data/devise.gemspec +3 -4
  32. data/gemfiles/{Gemfile.rails-3.2-stable → Gemfile.rails-4.1-stable} +6 -6
  33. data/gemfiles/Gemfile.rails-4.1-stable.lock +167 -0
  34. data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.2-stable} +6 -6
  35. data/gemfiles/Gemfile.rails-4.2-stable.lock +189 -0
  36. data/gemfiles/Gemfile.rails-5.0-beta +37 -0
  37. data/gemfiles/Gemfile.rails-5.0-beta.lock +199 -0
  38. data/lib/devise/controllers/helpers.rb +94 -27
  39. data/lib/devise/controllers/rememberable.rb +9 -2
  40. data/lib/devise/controllers/sign_in_out.rb +2 -9
  41. data/lib/devise/controllers/store_location.rb +11 -3
  42. data/lib/devise/controllers/url_helpers.rb +7 -7
  43. data/lib/devise/encryptor.rb +22 -0
  44. data/lib/devise/failure_app.rb +72 -23
  45. data/lib/devise/hooks/activatable.rb +3 -4
  46. data/lib/devise/hooks/csrf_cleaner.rb +3 -1
  47. data/lib/devise/hooks/timeoutable.rb +13 -8
  48. data/lib/devise/mailers/helpers.rb +1 -1
  49. data/lib/devise/mapping.rb +6 -2
  50. data/lib/devise/models/authenticatable.rb +32 -28
  51. data/lib/devise/models/confirmable.rb +55 -22
  52. data/lib/devise/models/database_authenticatable.rb +32 -19
  53. data/lib/devise/models/lockable.rb +5 -5
  54. data/lib/devise/models/recoverable.rb +44 -20
  55. data/lib/devise/models/rememberable.rb +54 -27
  56. data/lib/devise/models/timeoutable.rb +0 -6
  57. data/lib/devise/models/trackable.rb +5 -3
  58. data/lib/devise/models/validatable.rb +3 -3
  59. data/lib/devise/models.rb +1 -1
  60. data/lib/devise/omniauth/url_helpers.rb +62 -4
  61. data/lib/devise/parameter_sanitizer.rb +176 -61
  62. data/lib/devise/rails/routes.rb +76 -59
  63. data/lib/devise/rails/warden_compat.rb +1 -10
  64. data/lib/devise/rails.rb +2 -11
  65. data/lib/devise/strategies/authenticatable.rb +15 -6
  66. data/lib/devise/strategies/database_authenticatable.rb +5 -4
  67. data/lib/devise/strategies/rememberable.rb +13 -3
  68. data/lib/devise/test_helpers.rb +12 -7
  69. data/lib/devise/token_generator.rb +1 -41
  70. data/lib/devise/version.rb +1 -1
  71. data/lib/devise.rb +150 -58
  72. data/lib/generators/active_record/devise_generator.rb +28 -4
  73. data/lib/generators/active_record/templates/migration.rb +3 -3
  74. data/lib/generators/active_record/templates/migration_existing.rb +3 -3
  75. data/lib/generators/devise/controllers_generator.rb +44 -0
  76. data/lib/generators/devise/install_generator.rb +15 -0
  77. data/lib/generators/devise/orm_helpers.rb +1 -18
  78. data/lib/generators/devise/views_generator.rb +14 -3
  79. data/lib/generators/templates/README +1 -1
  80. data/lib/generators/templates/controllers/README +14 -0
  81. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  82. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  83. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  84. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  85. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  86. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  87. data/lib/generators/templates/devise.rb +36 -28
  88. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  89. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  90. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  91. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  92. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  93. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  94. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
  95. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  96. data/test/controllers/custom_strategy_test.rb +7 -5
  97. data/test/controllers/helper_methods_test.rb +22 -0
  98. data/test/controllers/helpers_test.rb +41 -1
  99. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  100. data/test/controllers/internal_helpers_test.rb +19 -15
  101. data/test/controllers/load_hooks_controller_test.rb +19 -0
  102. data/test/controllers/passwords_controller_test.rb +5 -4
  103. data/test/controllers/sessions_controller_test.rb +24 -21
  104. data/test/controllers/url_helpers_test.rb +7 -1
  105. data/test/devise_test.rb +48 -8
  106. data/test/failure_app_test.rb +107 -19
  107. data/test/generators/active_record_generator_test.rb +6 -26
  108. data/test/generators/controllers_generator_test.rb +48 -0
  109. data/test/generators/install_generator_test.rb +14 -3
  110. data/test/generators/views_generator_test.rb +8 -1
  111. data/test/helpers/devise_helper_test.rb +10 -12
  112. data/test/integration/authenticatable_test.rb +37 -21
  113. data/test/integration/confirmable_test.rb +54 -14
  114. data/test/integration/database_authenticatable_test.rb +12 -1
  115. data/test/integration/http_authenticatable_test.rb +4 -5
  116. data/test/integration/lockable_test.rb +10 -9
  117. data/test/integration/omniauthable_test.rb +13 -11
  118. data/test/integration/recoverable_test.rb +28 -15
  119. data/test/integration/registerable_test.rb +41 -33
  120. data/test/integration/rememberable_test.rb +51 -7
  121. data/test/integration/timeoutable_test.rb +23 -22
  122. data/test/integration/trackable_test.rb +3 -3
  123. data/test/mailers/confirmation_instructions_test.rb +10 -10
  124. data/test/mailers/reset_password_instructions_test.rb +8 -8
  125. data/test/mailers/unlock_instructions_test.rb +8 -8
  126. data/test/mapping_test.rb +7 -0
  127. data/test/models/authenticatable_test.rb +11 -1
  128. data/test/models/confirmable_test.rb +91 -42
  129. data/test/models/database_authenticatable_test.rb +26 -6
  130. data/test/models/lockable_test.rb +29 -17
  131. data/test/models/recoverable_test.rb +74 -7
  132. data/test/models/rememberable_test.rb +68 -94
  133. data/test/models/trackable_test.rb +28 -0
  134. data/test/models/validatable_test.rb +9 -17
  135. data/test/models_test.rb +15 -6
  136. data/test/omniauth/url_helpers_test.rb +4 -7
  137. data/test/orm/active_record.rb +6 -1
  138. data/test/parameter_sanitizer_test.rb +103 -53
  139. data/test/rails_app/app/active_record/user.rb +1 -0
  140. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  141. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  142. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  143. data/test/rails_app/app/controllers/admins_controller.rb +1 -6
  144. data/test/rails_app/app/controllers/application_controller.rb +5 -2
  145. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  146. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  147. data/test/rails_app/app/controllers/home_controller.rb +5 -1
  148. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +3 -3
  149. data/test/rails_app/app/controllers/users_controller.rb +6 -6
  150. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  151. data/test/rails_app/app/mailers/users/mailer.rb +0 -9
  152. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  153. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  154. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  155. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  156. data/test/rails_app/config/application.rb +3 -3
  157. data/test/rails_app/config/boot.rb +4 -4
  158. data/test/rails_app/config/environments/production.rb +6 -2
  159. data/test/rails_app/config/environments/test.rb +13 -3
  160. data/test/rails_app/config/initializers/devise.rb +15 -16
  161. data/test/rails_app/config/initializers/secret_token.rb +1 -6
  162. data/test/rails_app/config/routes.rb +23 -3
  163. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
  164. data/test/rails_app/lib/shared_user.rb +1 -1
  165. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  166. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  167. data/test/rails_test.rb +9 -0
  168. data/test/routes_test.rb +33 -16
  169. data/test/support/assertions.rb +2 -3
  170. data/test/support/helpers.rb +13 -6
  171. data/test/support/http_method_compatibility.rb +51 -0
  172. data/test/support/integration.rb +4 -4
  173. data/test/support/webrat/integrations/rails.rb +9 -0
  174. data/test/test_helper.rb +7 -0
  175. data/test/test_helpers_test.rb +43 -38
  176. data/test/test_models.rb +3 -3
  177. metadata +77 -23
  178. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
@@ -1,10 +1,12 @@
1
1
  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]
2
+ prepend_before_action :require_no_authentication, only: [:new, :create, :cancel]
3
+ prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]
4
4
 
5
5
  # GET /resource/sign_up
6
6
  def new
7
7
  build_resource({})
8
+ set_minimum_password_length
9
+ yield resource if block_given?
8
10
  respond_with self.resource
9
11
  end
10
12
 
@@ -12,19 +14,21 @@ class Devise::RegistrationsController < DeviseController
12
14
  def create
13
15
  build_resource(sign_up_params)
14
16
 
15
- if resource.save
16
- yield resource if block_given?
17
+ resource.save
18
+ yield resource if block_given?
19
+ if resource.persisted?
17
20
  if resource.active_for_authentication?
18
- set_flash_message :notice, :signed_up if is_flashing_format?
21
+ set_flash_message! :notice, :signed_up
19
22
  sign_up(resource_name, resource)
20
23
  respond_with resource, location: after_sign_up_path_for(resource)
21
24
  else
22
- set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
25
+ set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
23
26
  expire_data_after_sign_in!
24
27
  respond_with resource, location: after_inactive_sign_up_path_for(resource)
25
28
  end
26
29
  else
27
30
  clean_up_passwords resource
31
+ set_minimum_password_length
28
32
  respond_with resource
29
33
  end
30
34
  end
@@ -41,8 +45,9 @@ class Devise::RegistrationsController < DeviseController
41
45
  self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
42
46
  prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
43
47
 
44
- if update_resource(resource, account_update_params)
45
- yield resource if block_given?
48
+ resource_updated = update_resource(resource, account_update_params)
49
+ yield resource if block_given?
50
+ if resource_updated
46
51
  if is_flashing_format?
47
52
  flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
48
53
  :update_needs_confirmation : :updated
@@ -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
@@ -110,7 +115,10 @@ class Devise::RegistrationsController < DeviseController
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
@@ -132,4 +140,8 @@ 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
135
147
  end
@@ -1,19 +1,21 @@
1
1
  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 }
2
+ prepend_before_action :require_no_authentication, only: [:new, :create]
3
+ prepend_before_action :allow_params_authentication!, only: :create
4
+ prepend_before_action :verify_signed_out_user, only: :destroy
5
+ prepend_before_action only: [:create, :destroy] { request.env["devise.skip_timeout"] = true }
5
6
 
6
7
  # GET /resource/sign_in
7
8
  def new
8
9
  self.resource = resource_class.new(sign_in_params)
9
10
  clean_up_passwords(resource)
11
+ yield resource if block_given?
10
12
  respond_with(resource, serialize_options(resource))
11
13
  end
12
14
 
13
15
  # POST /resource/sign_in
14
16
  def create
15
17
  self.resource = warden.authenticate!(auth_options)
16
- set_flash_message(:notice, :signed_in) if is_flashing_format?
18
+ set_flash_message!(:notice, :signed_in)
17
19
  sign_in(resource_name, resource)
18
20
  yield resource if block_given?
19
21
  respond_with resource, location: after_sign_in_path_for(resource)
@@ -21,17 +23,10 @@ class Devise::SessionsController < DeviseController
21
23
 
22
24
  # DELETE /resource/sign_out
23
25
  def destroy
24
- redirect_path = after_sign_out_path_for(resource_name)
25
26
  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
27
+ set_flash_message! :notice, :signed_out if signed_out
28
+ yield if block_given?
29
+ respond_to_on_destroy
35
30
  end
36
31
 
37
32
  protected
@@ -50,4 +45,37 @@ class Devise::SessionsController < DeviseController
50
45
  def auth_options
51
46
  { scope: resource_name, recall: "#{controller_path}#new" }
52
47
  end
48
+
49
+ def translation_scope
50
+ 'devise.sessions'
51
+ end
52
+
53
+ private
54
+
55
+ # Check if there is no signed in user before doing the sign out.
56
+ #
57
+ # If there is no signed in user, it will set the flash message and redirect
58
+ # to the after_sign_out path.
59
+ def verify_signed_out_user
60
+ if all_signed_out?
61
+ set_flash_message! :notice, :already_signed_out
62
+
63
+ respond_to_on_destroy
64
+ end
65
+ end
66
+
67
+ def all_signed_out?
68
+ users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
69
+
70
+ users.all?(&:blank?)
71
+ end
72
+
73
+ def respond_to_on_destroy
74
+ # We actually need to hardcode this as Rails default responder doesn't
75
+ # support returning empty response on GET request
76
+ respond_to do |format|
77
+ format.all { head :no_content }
78
+ format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
79
+ end
80
+ end
53
81
  end
@@ -1,5 +1,5 @@
1
1
  class Devise::UnlocksController < DeviseController
2
- prepend_before_filter :require_no_authentication
2
+ prepend_before_action :require_no_authentication
3
3
 
4
4
  # GET /resource/unlock/new
5
5
  def new
@@ -24,7 +24,7 @@ class Devise::UnlocksController < DeviseController
24
24
  yield resource if block_given?
25
25
 
26
26
  if resource.errors.empty?
27
- set_flash_message :notice, :unlocked if is_flashing_format?
27
+ set_flash_message! :notice, :unlocked
28
28
  respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
29
29
  else
30
30
  respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
@@ -43,4 +43,7 @@ class Devise::UnlocksController < DeviseController
43
43
  new_session_path(resource) if is_navigational_format?
44
44
  end
45
45
 
46
+ def translation_scope
47
+ 'devise.unlocks'
48
+ end
46
49
  end
@@ -2,16 +2,36 @@
2
2
  class DeviseController < Devise.parent_controller.constantize
3
3
  include Devise::Controllers::ScopedViews
4
4
 
5
- helper DeviseHelper
5
+ if respond_to?(:helper)
6
+ helper DeviseHelper
7
+ end
6
8
 
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
9
+ if respond_to?(:helper_method)
10
+ helpers = %w(resource scope_name resource_name signed_in_resource
11
+ resource_class resource_params devise_mapping)
12
+ helper_method(*helpers)
13
+ end
11
14
 
12
- prepend_before_filter :assert_is_devise_resource!
15
+ prepend_before_action :assert_is_devise_resource!
13
16
  respond_to :html if mimes_for_respond_to.empty?
14
17
 
18
+ # Override prefixes to consider the scoped view.
19
+ # Notice we need to check for the request due to a bug in
20
+ # Action Controller tests that forces _prefixes to be
21
+ # loaded before even having a request object.
22
+ #
23
+ # This method should be public as it is is in ActionPack
24
+ # itself. Changing its visibility may break other gems.
25
+ def _prefixes #:nodoc:
26
+ @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
27
+ ["#{devise_mapping.scoped_path}/#{controller_name}"] + super
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ protected
34
+
15
35
  # Gets the actual resource stored in the instance variable
16
36
  def resource
17
37
  instance_variable_get(:"@#{resource_name}")
@@ -38,22 +58,6 @@ class DeviseController < Devise.parent_controller.constantize
38
58
  @devise_mapping ||= request.env["devise.mapping"]
39
59
  end
40
60
 
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
61
  # Checks whether it's a devise mapped resource or not.
58
62
  def assert_is_devise_resource! #:nodoc:
59
63
  unknown_action! <<-MESSAGE unless devise_mapping
@@ -89,10 +93,10 @@ MESSAGE
89
93
  instance_variable_set(:"@#{resource_name}", new_resource)
90
94
  end
91
95
 
92
- # Helper for use in before_filters where no authentication is required.
96
+ # Helper for use in before_actions where no authentication is required.
93
97
  #
94
98
  # Example:
95
- # before_filter :require_no_authentication, only: :new
99
+ # before_action :require_no_authentication, only: :new
96
100
  def require_no_authentication
97
101
  assert_is_devise_resource!
98
102
  return unless is_navigational_format?
@@ -123,14 +127,17 @@ MESSAGE
123
127
  end
124
128
 
125
129
  if notice
126
- set_flash_message :notice, notice if is_flashing_format?
130
+ set_flash_message! :notice, notice
127
131
  true
128
132
  end
129
133
  end
130
134
 
131
135
  # 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.
136
+ # to set up your messages using specific resource scope, and if no message is
137
+ # found we look to the default scope. Set the "now" options key to a true
138
+ # value to populate the flash.now hash in lieu of the default flash hash (so
139
+ # the flash message will be available to the current action instead of the
140
+ # next action).
134
141
  # Example (i18n locale file):
135
142
  #
136
143
  # en:
@@ -144,7 +151,25 @@ MESSAGE
144
151
  # available.
145
152
  def set_flash_message(key, kind, options = {})
146
153
  message = find_message(kind, options)
147
- flash[key] = message if message.present?
154
+ if options[:now]
155
+ flash.now[key] = message if message.present?
156
+ else
157
+ flash[key] = message if message.present?
158
+ end
159
+ end
160
+
161
+ # Sets flash message if is_flashing_format? equals true
162
+ def set_flash_message!(key, kind, options = {})
163
+ if is_flashing_format?
164
+ set_flash_message(key, kind, options)
165
+ end
166
+ end
167
+
168
+ # Sets minimum password length to show to user
169
+ def set_minimum_password_length
170
+ if devise_mapping.validatable?
171
+ @minimum_password_length = resource_class.password_length.min
172
+ end
148
173
  end
149
174
 
150
175
  def devise_i18n_options(options)
@@ -153,13 +178,20 @@ MESSAGE
153
178
 
154
179
  # Get message for given
155
180
  def find_message(kind, options = {})
156
- options[:scope] = "devise.#{controller_name}"
181
+ options[:scope] ||= translation_scope
157
182
  options[:default] = Array(options[:default]).unshift(kind.to_sym)
158
183
  options[:resource_name] = resource_name
159
184
  options = devise_i18n_options(options)
160
185
  I18n.t("#{options[:resource_name]}.#{kind}", options)
161
186
  end
162
187
 
188
+ # Controllers inheriting DeviseController are advised to override this
189
+ # method so that other controllers inheriting from them would use
190
+ # existing translations.
191
+ def translation_scope
192
+ "devise.#{controller_name}"
193
+ end
194
+
163
195
  def clean_up_passwords(object)
164
196
  object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
165
197
  end
@@ -173,4 +205,6 @@ MESSAGE
173
205
  def resource_params
174
206
  params.fetch(resource_name, {})
175
207
  end
208
+
209
+ ActiveSupport.run_load_hooks(:devise_controller, self)
176
210
  end
@@ -16,5 +16,9 @@ if defined?(ActionMailer)
16
16
  @token = token
17
17
  devise_mail(record, :unlock_instructions, opts)
18
18
  end
19
+
20
+ def password_change(record, opts={})
21
+ devise_mail(record, :password_change, opts)
22
+ end
19
23
  end
20
24
  end
@@ -3,10 +3,14 @@
3
3
  <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
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, 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,3 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>We're contacting you to notify you that your password has been changed.</p>
@@ -4,13 +4,22 @@
4
4
  <%= devise_error_messages! %>
5
5
  <%= f.hidden_field :reset_password_token %>
6
6
 
7
- <div><%= f.label :password, "New password" %><br />
8
- <%= f.password_field :password, autofocus: true, autocomplete: "off" %></div>
7
+ <div class="field">
8
+ <%= f.label :password, "New password" %><br />
9
+ <% if @minimum_password_length %>
10
+ <em>(<%= @minimum_password_length %> characters minimum)</em><br />
11
+ <% end %>
12
+ <%= f.password_field :password, autofocus: true, autocomplete: "off" %>
13
+ </div>
9
14
 
10
- <div><%= f.label :password_confirmation, "Confirm new password" %><br />
11
- <%= f.password_field :password_confirmation, autocomplete: "off" %></div>
15
+ <div class="field">
16
+ <%= f.label :password_confirmation, "Confirm new password" %><br />
17
+ <%= f.password_field :password_confirmation, autocomplete: "off" %>
18
+ </div>
12
19
 
13
- <div><%= f.submit "Change my password" %></div>
20
+ <div class="actions">
21
+ <%= f.submit "Change my password" %>
22
+ </div>
14
23
  <% end %>
15
24
 
16
25
  <%= render "devise/shared/links" %>
@@ -3,10 +3,14 @@
3
3
  <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
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 %>
9
+ </div>
8
10
 
9
- <div><%= f.submit "Send me reset password instructions" %></div>
11
+ <div class="actions">
12
+ <%= f.submit "Send me reset password instructions" %>
13
+ </div>
10
14
  <% end %>
11
15
 
12
16
  <%= render "devise/shared/links" %>
@@ -3,23 +3,33 @@
3
3
  <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
4
4
  <%= devise_error_messages! %>
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 %>
9
+ </div>
8
10
 
9
11
  <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
10
12
  <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
11
13
  <% end %>
12
14
 
13
- <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
14
- <%= f.password_field :password, autocomplete: "off" %></div>
15
+ <div class="field">
16
+ <%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
17
+ <%= f.password_field :password, autocomplete: "off" %>
18
+ </div>
15
19
 
16
- <div><%= f.label :password_confirmation %><br />
17
- <%= f.password_field :password_confirmation, autocomplete: "off" %></div>
20
+ <div class="field">
21
+ <%= f.label :password_confirmation %><br />
22
+ <%= f.password_field :password_confirmation, autocomplete: "off" %>
23
+ </div>
18
24
 
19
- <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
20
- <%= f.password_field :current_password, autocomplete: "off" %></div>
25
+ <div class="field">
26
+ <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
27
+ <%= f.password_field :current_password, autocomplete: "off" %>
28
+ </div>
21
29
 
22
- <div><%= f.submit "Update" %></div>
30
+ <div class="actions">
31
+ <%= f.submit "Update" %>
32
+ </div>
23
33
  <% end %>
24
34
 
25
35
  <h3>Cancel my account</h3>
@@ -3,16 +3,27 @@
3
3
  <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
4
4
  <%= devise_error_messages! %>
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 %>
9
+ </div>
8
10
 
9
- <div><%= f.label :password %><br />
10
- <%= f.password_field :password, autocomplete: "off" %></div>
11
+ <div class="field">
12
+ <%= f.label :password %>
13
+ <% if @minimum_password_length %>
14
+ <em>(<%= @minimum_password_length %> characters minimum)</em>
15
+ <% end %><br />
16
+ <%= f.password_field :password, autocomplete: "off" %>
17
+ </div>
11
18
 
12
- <div><%= f.label :password_confirmation %><br />
13
- <%= f.password_field :password_confirmation, autocomplete: "off" %></div>
19
+ <div class="field">
20
+ <%= f.label :password_confirmation %><br />
21
+ <%= f.password_field :password_confirmation, autocomplete: "off" %>
22
+ </div>
14
23
 
15
- <div><%= f.submit "Sign up" %></div>
24
+ <div class="actions">
25
+ <%= f.submit "Sign up" %>
26
+ </div>
16
27
  <% end %>
17
28
 
18
29
  <%= render "devise/shared/links" %>
@@ -1,17 +1,26 @@
1
- <h2>Sign in</h2>
1
+ <h2>Log in</h2>
2
2
 
3
3
  <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
- <div><%= f.label :email %><br />
5
- <%= f.email_field :email, autofocus: true %></div>
4
+ <div class="field">
5
+ <%= f.label :email %><br />
6
+ <%= f.email_field :email, autofocus: true %>
7
+ </div>
6
8
 
7
- <div><%= f.label :password %><br />
8
- <%= f.password_field :password, autocomplete: "off" %></div>
9
+ <div class="field">
10
+ <%= f.label :password %><br />
11
+ <%= f.password_field :password, autocomplete: "off" %>
12
+ </div>
9
13
 
10
14
  <% if devise_mapping.rememberable? -%>
11
- <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
15
+ <div class="field">
16
+ <%= f.check_box :remember_me %>
17
+ <%= f.label :remember_me %>
18
+ </div>
12
19
  <% end -%>
13
20
 
14
- <div><%= f.submit "Sign in" %></div>
21
+ <div class="actions">
22
+ <%= f.submit "Log in" %>
23
+ </div>
15
24
  <% end %>
16
25
 
17
26
  <%= render "devise/shared/links" %>
@@ -1,5 +1,5 @@
1
1
  <%- if controller_name != 'sessions' %>
2
- <%= link_to "Sign in", new_session_path(resource_name) %><br />
2
+ <%= link_to "Log in", new_session_path(resource_name) %><br />
3
3
  <% end -%>
4
4
 
5
5
  <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
@@ -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 #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
23
+ <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
24
24
  <% end -%>
25
25
  <% end -%>
@@ -3,10 +3,14 @@
3
3
  <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
4
4
  <%= devise_error_messages! %>
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 %>
9
+ </div>
8
10
 
9
- <div><%= f.submit "Resend unlock instructions" %></div>
11
+ <div class="actions">
12
+ <%= f.submit "Resend unlock instructions" %>
13
+ </div>
10
14
  <% end %>
11
15
 
12
16
  <%= render "devise/shared/links" %>
data/bin/test ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path(File.expand_path('../../test', __FILE__))
3
+
4
+ require 'bundler/setup'
5
+ begin
6
+ require 'rails/test_unit/minitest_plugin'
7
+ rescue LoadError
8
+ exec 'rake'
9
+ end
10
+
11
+ Rails::TestUnitReporter.executable = 'bin/test'
12
+
13
+ exit Minitest.run(ARGV)