devise 3.2.0 → 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 +7 -0
  2. data/CHANGELOG.md +260 -949
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +383 -100
  5. data/app/controllers/devise/confirmations_controller.rb +13 -5
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  7. data/app/controllers/devise/passwords_controller.rb +23 -8
  8. data/app/controllers/devise/registrations_controller.rb +60 -24
  9. data/app/controllers/devise/sessions_controller.rb +48 -16
  10. data/app/controllers/devise/unlocks_controller.rb +11 -4
  11. data/app/controllers/devise_controller.rb +67 -31
  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 +9 -5
  15. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  16. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  17. data/app/views/devise/mailer/password_change.html.erb +3 -0
  18. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  19. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  20. data/app/views/devise/passwords/edit.html.erb +16 -7
  21. data/app/views/devise/passwords/new.html.erb +9 -5
  22. data/app/views/devise/registrations/edit.html.erb +29 -15
  23. data/app/views/devise/registrations/new.html.erb +20 -9
  24. data/app/views/devise/sessions/new.html.erb +19 -10
  25. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  26. data/app/views/devise/shared/{_links.erb → _links.html.erb} +9 -9
  27. data/app/views/devise/unlocks/new.html.erb +9 -5
  28. data/config/locales/en.yml +23 -17
  29. data/lib/devise/controllers/helpers.rb +113 -49
  30. data/lib/devise/controllers/rememberable.rb +15 -6
  31. data/lib/devise/controllers/scoped_views.rb +3 -1
  32. data/lib/devise/controllers/sign_in_out.rb +42 -26
  33. data/lib/devise/controllers/store_location.rb +76 -0
  34. data/lib/devise/controllers/url_helpers.rb +9 -7
  35. data/lib/devise/delegator.rb +2 -0
  36. data/lib/devise/encryptor.rb +24 -0
  37. data/lib/devise/failure_app.rb +122 -40
  38. data/lib/devise/hooks/activatable.rb +7 -6
  39. data/lib/devise/hooks/csrf_cleaner.rb +5 -1
  40. data/lib/devise/hooks/forgetable.rb +2 -0
  41. data/lib/devise/hooks/lockable.rb +7 -2
  42. data/lib/devise/hooks/proxy.rb +4 -2
  43. data/lib/devise/hooks/rememberable.rb +4 -2
  44. data/lib/devise/hooks/timeoutable.rb +16 -9
  45. data/lib/devise/hooks/trackable.rb +3 -1
  46. data/lib/devise/mailers/helpers.rb +15 -12
  47. data/lib/devise/mapping.rb +8 -2
  48. data/lib/devise/models/authenticatable.rb +81 -56
  49. data/lib/devise/models/confirmable.rb +137 -42
  50. data/lib/devise/models/database_authenticatable.rb +114 -28
  51. data/lib/devise/models/lockable.rb +30 -17
  52. data/lib/devise/models/omniauthable.rb +3 -1
  53. data/lib/devise/models/recoverable.rb +62 -26
  54. data/lib/devise/models/registerable.rb +4 -0
  55. data/lib/devise/models/rememberable.rb +62 -33
  56. data/lib/devise/models/timeoutable.rb +4 -8
  57. data/lib/devise/models/trackable.rb +20 -4
  58. data/lib/devise/models/validatable.rb +16 -9
  59. data/lib/devise/models.rb +3 -1
  60. data/lib/devise/modules.rb +12 -10
  61. data/lib/devise/omniauth/config.rb +2 -0
  62. data/lib/devise/omniauth/url_helpers.rb +14 -5
  63. data/lib/devise/omniauth.rb +2 -0
  64. data/lib/devise/orm/active_record.rb +5 -1
  65. data/lib/devise/orm/mongoid.rb +6 -2
  66. data/lib/devise/parameter_filter.rb +4 -0
  67. data/lib/devise/parameter_sanitizer.rb +139 -65
  68. data/lib/devise/rails/routes.rb +150 -104
  69. data/lib/devise/rails/warden_compat.rb +3 -10
  70. data/lib/devise/rails.rb +10 -13
  71. data/lib/devise/secret_key_finder.rb +27 -0
  72. data/lib/devise/strategies/authenticatable.rb +21 -10
  73. data/lib/devise/strategies/base.rb +3 -1
  74. data/lib/devise/strategies/database_authenticatable.rb +15 -4
  75. data/lib/devise/strategies/rememberable.rb +15 -3
  76. data/lib/devise/test/controller_helpers.rb +165 -0
  77. data/lib/devise/test/integration_helpers.rb +63 -0
  78. data/lib/devise/test_helpers.rb +7 -124
  79. data/lib/devise/time_inflector.rb +4 -2
  80. data/lib/devise/token_generator.rb +3 -41
  81. data/lib/devise/version.rb +3 -1
  82. data/lib/devise.rb +111 -83
  83. data/lib/generators/active_record/devise_generator.rb +49 -12
  84. data/lib/generators/active_record/templates/migration.rb +9 -7
  85. data/lib/generators/active_record/templates/migration_existing.rb +9 -7
  86. data/lib/generators/devise/controllers_generator.rb +46 -0
  87. data/lib/generators/devise/devise_generator.rb +9 -5
  88. data/lib/generators/devise/install_generator.rb +22 -0
  89. data/lib/generators/devise/orm_helpers.rb +10 -21
  90. data/lib/generators/devise/views_generator.rb +51 -28
  91. data/lib/generators/mongoid/devise_generator.rb +22 -19
  92. data/lib/generators/templates/README +5 -12
  93. data/lib/generators/templates/controllers/README +14 -0
  94. data/lib/generators/templates/controllers/confirmations_controller.rb +30 -0
  95. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +30 -0
  96. data/lib/generators/templates/controllers/passwords_controller.rb +34 -0
  97. data/lib/generators/templates/controllers/registrations_controller.rb +62 -0
  98. data/lib/generators/templates/controllers/sessions_controller.rb +27 -0
  99. data/lib/generators/templates/controllers/unlocks_controller.rb +30 -0
  100. data/lib/generators/templates/devise.rb +81 -36
  101. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  102. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  103. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  104. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  105. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  106. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +6 -2
  107. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +12 -4
  108. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +5 -2
  109. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +14 -6
  110. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +12 -4
  111. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +11 -6
  112. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +5 -2
  113. metadata +46 -280
  114. data/.gitignore +0 -10
  115. data/.travis.yml +0 -20
  116. data/.yardopts +0 -9
  117. data/CONTRIBUTING.md +0 -14
  118. data/Gemfile +0 -31
  119. data/Gemfile.lock +0 -160
  120. data/Rakefile +0 -35
  121. data/devise.gemspec +0 -27
  122. data/devise.png +0 -0
  123. data/gemfiles/Gemfile.rails-3.2.x +0 -31
  124. data/gemfiles/Gemfile.rails-3.2.x.lock +0 -159
  125. data/test/controllers/custom_strategy_test.rb +0 -62
  126. data/test/controllers/helpers_test.rb +0 -253
  127. data/test/controllers/internal_helpers_test.rb +0 -120
  128. data/test/controllers/passwords_controller_test.rb +0 -31
  129. data/test/controllers/sessions_controller_test.rb +0 -99
  130. data/test/controllers/url_helpers_test.rb +0 -59
  131. data/test/delegator_test.rb +0 -19
  132. data/test/devise_test.rb +0 -94
  133. data/test/failure_app_test.rb +0 -232
  134. data/test/generators/active_record_generator_test.rb +0 -103
  135. data/test/generators/devise_generator_test.rb +0 -39
  136. data/test/generators/install_generator_test.rb +0 -13
  137. data/test/generators/mongoid_generator_test.rb +0 -23
  138. data/test/generators/views_generator_test.rb +0 -67
  139. data/test/helpers/devise_helper_test.rb +0 -51
  140. data/test/integration/authenticatable_test.rb +0 -713
  141. data/test/integration/confirmable_test.rb +0 -284
  142. data/test/integration/database_authenticatable_test.rb +0 -84
  143. data/test/integration/http_authenticatable_test.rb +0 -105
  144. data/test/integration/lockable_test.rb +0 -239
  145. data/test/integration/omniauthable_test.rb +0 -133
  146. data/test/integration/recoverable_test.rb +0 -334
  147. data/test/integration/registerable_test.rb +0 -349
  148. data/test/integration/rememberable_test.rb +0 -167
  149. data/test/integration/timeoutable_test.rb +0 -178
  150. data/test/integration/trackable_test.rb +0 -92
  151. data/test/mailers/confirmation_instructions_test.rb +0 -115
  152. data/test/mailers/reset_password_instructions_test.rb +0 -96
  153. data/test/mailers/unlock_instructions_test.rb +0 -91
  154. data/test/mapping_test.rb +0 -127
  155. data/test/models/authenticatable_test.rb +0 -13
  156. data/test/models/confirmable_test.rb +0 -454
  157. data/test/models/database_authenticatable_test.rb +0 -244
  158. data/test/models/lockable_test.rb +0 -298
  159. data/test/models/omniauthable_test.rb +0 -7
  160. data/test/models/recoverable_test.rb +0 -184
  161. data/test/models/registerable_test.rb +0 -7
  162. data/test/models/rememberable_test.rb +0 -183
  163. data/test/models/serializable_test.rb +0 -49
  164. data/test/models/timeoutable_test.rb +0 -51
  165. data/test/models/trackable_test.rb +0 -13
  166. data/test/models/validatable_test.rb +0 -127
  167. data/test/models_test.rb +0 -144
  168. data/test/omniauth/config_test.rb +0 -57
  169. data/test/omniauth/url_helpers_test.rb +0 -54
  170. data/test/orm/active_record.rb +0 -10
  171. data/test/orm/mongoid.rb +0 -13
  172. data/test/parameter_sanitizer_test.rb +0 -81
  173. data/test/rails_app/Rakefile +0 -6
  174. data/test/rails_app/app/active_record/admin.rb +0 -6
  175. data/test/rails_app/app/active_record/shim.rb +0 -2
  176. data/test/rails_app/app/active_record/user.rb +0 -6
  177. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  178. data/test/rails_app/app/controllers/admins_controller.rb +0 -11
  179. data/test/rails_app/app/controllers/application_controller.rb +0 -9
  180. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  181. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  182. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  183. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  184. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  185. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  186. data/test/rails_app/app/mailers/users/mailer.rb +0 -12
  187. data/test/rails_app/app/mongoid/admin.rb +0 -29
  188. data/test/rails_app/app/mongoid/shim.rb +0 -23
  189. data/test/rails_app/app/mongoid/user.rb +0 -39
  190. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  191. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  192. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  193. data/test/rails_app/app/views/home/index.html.erb +0 -1
  194. data/test/rails_app/app/views/home/join.html.erb +0 -1
  195. data/test/rails_app/app/views/home/private.html.erb +0 -1
  196. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  197. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  198. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  199. data/test/rails_app/app/views/users/index.html.erb +0 -1
  200. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  201. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  202. data/test/rails_app/bin/bundle +0 -3
  203. data/test/rails_app/bin/rails +0 -4
  204. data/test/rails_app/bin/rake +0 -4
  205. data/test/rails_app/config/application.rb +0 -40
  206. data/test/rails_app/config/boot.rb +0 -8
  207. data/test/rails_app/config/database.yml +0 -18
  208. data/test/rails_app/config/environment.rb +0 -5
  209. data/test/rails_app/config/environments/development.rb +0 -34
  210. data/test/rails_app/config/environments/production.rb +0 -84
  211. data/test/rails_app/config/environments/test.rb +0 -36
  212. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  213. data/test/rails_app/config/initializers/devise.rb +0 -181
  214. data/test/rails_app/config/initializers/inflections.rb +0 -2
  215. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  216. data/test/rails_app/config/initializers/session_store.rb +0 -1
  217. data/test/rails_app/config/routes.rb +0 -104
  218. data/test/rails_app/config.ru +0 -4
  219. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  220. data/test/rails_app/db/schema.rb +0 -51
  221. data/test/rails_app/lib/shared_admin.rb +0 -17
  222. data/test/rails_app/lib/shared_user.rb +0 -29
  223. data/test/rails_app/public/404.html +0 -26
  224. data/test/rails_app/public/422.html +0 -26
  225. data/test/rails_app/public/500.html +0 -26
  226. data/test/rails_app/public/favicon.ico +0 -0
  227. data/test/routes_test.rb +0 -250
  228. data/test/support/assertions.rb +0 -40
  229. data/test/support/helpers.rb +0 -70
  230. data/test/support/integration.rb +0 -92
  231. data/test/support/locale/en.yml +0 -8
  232. data/test/support/webrat/integrations/rails.rb +0 -24
  233. data/test/test_helper.rb +0 -34
  234. data/test/test_helpers_test.rb +0 -173
  235. data/test/test_models.rb +0 -26
data/lib/devise.rb CHANGED
@@ -1,27 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
  require 'active_support/core_ext/numeric/time'
3
5
  require 'active_support/dependencies'
4
6
  require 'orm_adapter'
5
7
  require 'set'
6
8
  require 'securerandom'
9
+ require 'responders'
7
10
 
8
11
  module Devise
9
12
  autoload :Delegator, 'devise/delegator'
13
+ autoload :Encryptor, 'devise/encryptor'
10
14
  autoload :FailureApp, 'devise/failure_app'
11
15
  autoload :OmniAuth, 'devise/omniauth'
12
16
  autoload :ParameterFilter, 'devise/parameter_filter'
13
- autoload :BaseSanitizer, 'devise/parameter_sanitizer'
14
17
  autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
15
18
  autoload :TestHelpers, 'devise/test_helpers'
16
19
  autoload :TimeInflector, 'devise/time_inflector'
17
20
  autoload :TokenGenerator, 'devise/token_generator'
21
+ autoload :SecretKeyFinder, 'devise/secret_key_finder'
18
22
 
19
23
  module Controllers
20
- autoload :Helpers, 'devise/controllers/helpers'
21
- autoload :Rememberable, 'devise/controllers/rememberable'
22
- autoload :ScopedViews, 'devise/controllers/scoped_views'
23
- autoload :SignInOut, 'devise/controllers/sign_in_out'
24
- autoload :UrlHelpers, 'devise/controllers/url_helpers'
24
+ autoload :Helpers, 'devise/controllers/helpers'
25
+ autoload :Rememberable, 'devise/controllers/rememberable'
26
+ autoload :ScopedViews, 'devise/controllers/scoped_views'
27
+ autoload :SignInOut, 'devise/controllers/sign_in_out'
28
+ autoload :StoreLocation, 'devise/controllers/store_location'
29
+ autoload :UrlHelpers, 'devise/controllers/url_helpers'
25
30
  end
26
31
 
27
32
  module Hooks
@@ -33,17 +38,22 @@ module Devise
33
38
  end
34
39
 
35
40
  module Strategies
36
- autoload :Base, 'devise/strategies/base'
41
+ autoload :Base, 'devise/strategies/base'
37
42
  autoload :Authenticatable, 'devise/strategies/authenticatable'
38
43
  end
39
44
 
45
+ module Test
46
+ autoload :ControllerHelpers, 'devise/test/controller_helpers'
47
+ autoload :IntegrationHelpers, 'devise/test/integration_helpers'
48
+ end
49
+
40
50
  # Constants which holds devise configuration for extensions. Those should
41
51
  # not be modified by the "end user" (this is why they are constants).
42
52
  ALL = []
43
- CONTROLLERS = ActiveSupport::OrderedHash.new
44
- ROUTES = ActiveSupport::OrderedHash.new
45
- STRATEGIES = ActiveSupport::OrderedHash.new
46
- URL_HELPERS = ActiveSupport::OrderedHash.new
53
+ CONTROLLERS = {}
54
+ ROUTES = {}
55
+ STRATEGIES = {}
56
+ URL_HELPERS = {}
47
57
 
48
58
  # Strategies that do not require user input.
49
59
  NO_INPUT = []
@@ -55,29 +65,13 @@ module Devise
55
65
  mattr_accessor :secret_key
56
66
  @@secret_key = nil
57
67
 
58
- [ :allow_insecure_token_lookup,
59
- :allow_insecure_sign_in_after_confirmation,
60
- :token_authentication_key ].each do |method|
61
- class_eval <<-RUBY
62
- def self.#{method}
63
- ActiveSupport::Deprecation.warn "Devise.#{method} is deprecated " \
64
- "and has no effect"
65
- end
66
-
67
- def self.#{method}=(val)
68
- ActiveSupport::Deprecation.warn "Devise.#{method}= is deprecated " \
69
- "and has no effect"
70
- end
71
- RUBY
72
- end
73
-
74
68
  # Custom domain or key for cookies. Not set by default
75
69
  mattr_accessor :rememberable_options
76
70
  @@rememberable_options = {}
77
71
 
78
- # The number of times to encrypt password.
72
+ # The number of times to hash the password.
79
73
  mattr_accessor :stretches
80
- @@stretches = 10
74
+ @@stretches = 11
81
75
 
82
76
  # The default key used when authenticating over http auth.
83
77
  mattr_accessor :http_authentication_key
@@ -85,7 +79,7 @@ module Devise
85
79
 
86
80
  # Keys used when authenticating a user.
87
81
  mattr_accessor :authentication_keys
88
- @@authentication_keys = [ :email ]
82
+ @@authentication_keys = [:email]
89
83
 
90
84
  # Request keys used when authenticating a user.
91
85
  mattr_accessor :request_keys
@@ -93,11 +87,11 @@ module Devise
93
87
 
94
88
  # Keys that should be case-insensitive.
95
89
  mattr_accessor :case_insensitive_keys
96
- @@case_insensitive_keys = [ :email ]
90
+ @@case_insensitive_keys = [:email]
97
91
 
98
92
  # Keys that should have whitespace stripped.
99
93
  mattr_accessor :strip_whitespace_keys
100
- @@strip_whitespace_keys = []
94
+ @@strip_whitespace_keys = [:email]
101
95
 
102
96
  # If http authentication is enabled by default.
103
97
  mattr_accessor :http_authenticatable
@@ -115,11 +109,11 @@ module Devise
115
109
  mattr_accessor :http_authentication_realm
116
110
  @@http_authentication_realm = "Application"
117
111
 
118
- # Email regex used to validate email formats. It simply asserts that
119
- # an one (and only one) @ exists in the given string. This is mainly
120
- # to give user feedback and not to assert the e-mail validity.
112
+ # Email regex used to validate email formats. It asserts that there are no
113
+ # @ symbols or whitespaces in either the localpart or the domain, and that
114
+ # there is a single @ symbol separating the localpart and the domain.
121
115
  mattr_accessor :email_regexp
122
- @@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
116
+ @@email_regexp = /\A[^@\s]+@[^@\s]+\z/
123
117
 
124
118
  # Range validation for password length
125
119
  mattr_accessor :password_length
@@ -133,6 +127,10 @@ module Devise
133
127
  mattr_accessor :extend_remember_period
134
128
  @@extend_remember_period = false
135
129
 
130
+ # If true, all the remember me tokens are going to be invalidated when the user signs out.
131
+ mattr_accessor :expire_all_remember_me_on_sign_out
132
+ @@expire_all_remember_me_on_sign_out = true
133
+
136
134
  # Time interval you can access your account before confirming your account.
137
135
  # nil - allows unconfirmed access for unlimited time
138
136
  mattr_accessor :allow_unconfirmed_access_for
@@ -144,25 +142,28 @@ module Devise
144
142
 
145
143
  # Defines which key will be used when confirming an account.
146
144
  mattr_accessor :confirmation_keys
147
- @@confirmation_keys = [ :email ]
145
+ @@confirmation_keys = [:email]
148
146
 
149
147
  # Defines if email should be reconfirmable.
150
- # False by default for backwards compatibility.
151
148
  mattr_accessor :reconfirmable
152
- @@reconfirmable = false
149
+ @@reconfirmable = true
153
150
 
154
151
  # Time interval to timeout the user session without activity.
155
152
  mattr_accessor :timeout_in
156
153
  @@timeout_in = 30.minutes
157
154
 
158
- # Authentication token expiration on timeout
159
- mattr_accessor :expire_auth_token_on_timeout
160
- @@expire_auth_token_on_timeout = false
161
-
162
- # Used to encrypt password. Please generate one with rake secret.
155
+ # Used to hash the password. Please generate one with rails secret.
163
156
  mattr_accessor :pepper
164
157
  @@pepper = nil
165
158
 
159
+ # Used to send notification to the original user email when their email is changed.
160
+ mattr_accessor :send_email_changed_notification
161
+ @@send_email_changed_notification = false
162
+
163
+ # Used to enable sending notification to user when their password is changed.
164
+ mattr_accessor :send_password_change_notification
165
+ @@send_password_change_notification = false
166
+
166
167
  # Scoped views. Since it relies on fallbacks to render default views, it's
167
168
  # turned off by default.
168
169
  mattr_accessor :scoped_views
@@ -175,7 +176,7 @@ module Devise
175
176
 
176
177
  # Defines which key will be used when locking and unlocking an account
177
178
  mattr_accessor :unlock_keys
178
- @@unlock_keys = [ :email ]
179
+ @@unlock_keys = [:email]
179
180
 
180
181
  # Defines which strategy can be used to unlock an account.
181
182
  # Values: :email, :time, :both
@@ -192,12 +193,16 @@ module Devise
192
193
 
193
194
  # Defines which key will be used when recovering the password for an account
194
195
  mattr_accessor :reset_password_keys
195
- @@reset_password_keys = [ :email ]
196
+ @@reset_password_keys = [:email]
196
197
 
197
198
  # Time interval you can reset your password with a reset password key
198
199
  mattr_accessor :reset_password_within
199
200
  @@reset_password_within = 6.hours
200
201
 
202
+ # When set to false, resetting a password does not automatically sign in a user
203
+ mattr_accessor :sign_in_after_reset_password
204
+ @@sign_in_after_reset_password = true
205
+
201
206
  # The default scope which is used by warden.
202
207
  mattr_accessor :default_scope
203
208
  @@default_scope = nil
@@ -208,7 +213,7 @@ module Devise
208
213
 
209
214
  # Skip session storage for the following strategies
210
215
  mattr_accessor :skip_session_storage
211
- @@skip_session_storage = []
216
+ @@skip_session_storage = [:http_auth]
212
217
 
213
218
  # Which formats should be treated as navigational.
214
219
  mattr_accessor :navigational_formats
@@ -220,7 +225,7 @@ module Devise
220
225
 
221
226
  # The default method used while signing out
222
227
  mattr_accessor :sign_out_via
223
- @@sign_out_via = :get
228
+ @@sign_out_via = :delete
224
229
 
225
230
  # The parent controller all Devise controllers inherits from.
226
231
  # Defaults to ApplicationController. This should be set early
@@ -235,12 +240,12 @@ module Devise
235
240
  @@parent_mailer = "ActionMailer::Base"
236
241
 
237
242
  # The router Devise should use to generate routes. Defaults
238
- # to :main_app. Should be overriden by engines in order
243
+ # to :main_app. Should be overridden by engines in order
239
244
  # to provide custom routes.
240
245
  mattr_accessor :router_name
241
246
  @@router_name = nil
242
247
 
243
- # Set the omniauth path prefix so it can be overriden when
248
+ # Set the OmniAuth path prefix so it can be overridden when
244
249
  # Devise is used in a mountable engine
245
250
  mattr_accessor :omniauth_path_prefix
246
251
  @@omniauth_path_prefix = nil
@@ -249,15 +254,22 @@ module Devise
249
254
  mattr_accessor :clean_up_csrf_token_on_authentication
250
255
  @@clean_up_csrf_token_on_authentication = true
251
256
 
257
+ # When false, Devise will not attempt to reload routes on eager load.
258
+ # This can reduce the time taken to boot the app but if your application
259
+ # requires the Devise mappings to be loaded during boot time the application
260
+ # won't boot properly.
261
+ mattr_accessor :reload_routes
262
+ @@reload_routes = true
263
+
252
264
  # PRIVATE CONFIGURATION
253
265
 
254
266
  # Store scopes mappings.
255
267
  mattr_reader :mappings
256
- @@mappings = ActiveSupport::OrderedHash.new
268
+ @@mappings = {}
257
269
 
258
- # Omniauth configurations.
270
+ # OmniAuth configurations.
259
271
  mattr_reader :omniauth_configs
260
- @@omniauth_configs = ActiveSupport::OrderedHash.new
272
+ @@omniauth_configs = {}
261
273
 
262
274
  # Define a set of modules that are called when a mapping is added.
263
275
  mattr_reader :helpers
@@ -267,28 +279,40 @@ module Devise
267
279
  # Private methods to interface with Warden.
268
280
  mattr_accessor :warden_config
269
281
  @@warden_config = nil
270
- @@warden_config_block = nil
282
+ @@warden_config_blocks = []
271
283
 
272
284
  # When true, enter in paranoid mode to avoid user enumeration.
273
285
  mattr_accessor :paranoid
274
286
  @@paranoid = false
275
287
 
276
- # When true, warn user if he just used next-to-last attempt of authentication
288
+ # When true, warn user if they just used next-to-last attempt of authentication
277
289
  mattr_accessor :last_attempt_warning
278
- @@last_attempt_warning = false
290
+ @@last_attempt_warning = true
279
291
 
280
292
  # Stores the token generator
281
293
  mattr_accessor :token_generator
282
294
  @@token_generator = nil
283
295
 
284
- # Default way to setup Devise. Run rails generate devise_install to create
296
+ # When set to false, changing a password does not automatically sign in a user
297
+ mattr_accessor :sign_in_after_change_password
298
+ @@sign_in_after_change_password = true
299
+
300
+ def self.rails51? # :nodoc:
301
+ Rails.gem_version >= Gem::Version.new("5.1.x")
302
+ end
303
+
304
+ def self.activerecord51? # :nodoc:
305
+ defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
306
+ end
307
+
308
+ # Default way to set up Devise. Run rails generate devise_install to create
285
309
  # a fresh initializer with all configuration values.
286
310
  def self.setup
287
311
  yield self
288
312
  end
289
313
 
290
314
  class Getter
291
- def initialize name
315
+ def initialize(name)
292
316
  @name = name
293
317
  end
294
318
 
@@ -298,12 +322,8 @@ module Devise
298
322
  end
299
323
 
300
324
  def self.ref(arg)
301
- if defined?(ActiveSupport::Dependencies::ClassCache)
302
- ActiveSupport::Dependencies::reference(arg)
303
- Getter.new(arg)
304
- else
305
- ActiveSupport::Dependencies.ref(arg)
306
- end
325
+ ActiveSupport::Dependencies.reference(arg)
326
+ Getter.new(arg)
307
327
  end
308
328
 
309
329
  def self.available_router_name
@@ -334,7 +354,12 @@ module Devise
334
354
  mapping
335
355
  end
336
356
 
337
- # Make Devise aware of an 3rd party Devise-module (like invitable). For convenience.
357
+ # Register available devise modules. For the standard modules that Devise provides, this method is
358
+ # called from lib/devise/modules.rb. Third-party modules need to be added explicitly using this method.
359
+ #
360
+ # Note that adding a module using this method does not cause it to be used in the authentication
361
+ # process. That requires that the module be listed in the arguments passed to the 'devise' method
362
+ # in the model class definition.
338
363
  #
339
364
  # == Options:
340
365
  #
@@ -342,6 +367,7 @@ module Devise
342
367
  # +controller+ - Symbol representing the name of an existing or custom *controller* for this module.
343
368
  # +route+ - Symbol representing the named *route* helper for this module.
344
369
  # +strategy+ - Symbol representing if this module got a custom *strategy*.
370
+ # +insert_at+ - Integer representing the order in which this module's model will be included
345
371
  #
346
372
  # All values, except :model, accept also a boolean and will have the same name as the given module
347
373
  # name.
@@ -349,12 +375,14 @@ module Devise
349
375
  # == Examples:
350
376
  #
351
377
  # Devise.add_module(:party_module)
352
- # Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
353
- # Devise.add_module(:party_module, :model => 'party_module/model')
378
+ # Devise.add_module(:party_module, strategy: true, controller: :sessions)
379
+ # Devise.add_module(:party_module, model: 'party_module/model')
380
+ # Devise.add_module(:party_module, insert_at: 0)
354
381
  #
355
382
  def self.add_module(module_name, options = {})
356
- ALL << module_name
357
- options.assert_valid_keys(:strategy, :model, :controller, :route, :no_input)
383
+ options.assert_valid_keys(:strategy, :model, :controller, :route, :no_input, :insert_at)
384
+
385
+ ALL.insert (options[:insert_at] || -1), module_name
358
386
 
359
387
  if strategy = options[:strategy]
360
388
  strategy = (strategy == true ? module_name : strategy)
@@ -399,7 +427,7 @@ module Devise
399
427
  # Sets warden configuration using a block that will be invoked on warden
400
428
  # initialization.
401
429
  #
402
- # Devise.initialize do |config|
430
+ # Devise.setup do |config|
403
431
  # config.allow_unconfirmed_access_for = 2.days
404
432
  #
405
433
  # config.warden do |manager|
@@ -408,15 +436,14 @@ module Devise
408
436
  # end
409
437
  # end
410
438
  def self.warden(&block)
411
- @@warden_config_block = block
439
+ @@warden_config_blocks << block
412
440
  end
413
441
 
414
- # Specify an omniauth provider.
442
+ # Specify an OmniAuth provider.
415
443
  #
416
444
  # config.omniauth :github, APP_ID, APP_SECRET
417
445
  #
418
446
  def self.omniauth(provider, *args)
419
- @@helpers << Devise::OmniAuth::UrlHelpers
420
447
  config = Devise::OmniAuth::Config.new(provider, args)
421
448
  @@omniauth_configs[config.strategy_name.to_sym] = config
422
449
  end
@@ -439,8 +466,8 @@ module Devise
439
466
  Devise::Controllers::UrlHelpers.generate_helpers!
440
467
  end
441
468
 
442
- # A method used internally to setup warden manager from the Rails initialize
443
- # block.
469
+ # A method used internally to complete the setup of warden manager after routes are loaded.
470
+ # See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!
444
471
  def self.configure_warden! #:nodoc:
445
472
  @@warden_configured ||= begin
446
473
  warden_config.failure_app = Devise::Delegator.new
@@ -448,28 +475,29 @@ module Devise
448
475
  warden_config.intercept_401 = false
449
476
 
450
477
  Devise.mappings.each_value do |mapping|
451
- warden_config.scope_defaults mapping.name, :strategies => mapping.strategies
478
+ warden_config.scope_defaults mapping.name, strategies: mapping.strategies
452
479
 
453
480
  warden_config.serialize_into_session(mapping.name) do |record|
454
481
  mapping.to.serialize_into_session(record)
455
482
  end
456
483
 
457
- warden_config.serialize_from_session(mapping.name) do |key|
458
- # Previous versions contained an additional entry at the beginning of
459
- # key with the record's class name.
460
- args = key[-2, 2]
484
+ warden_config.serialize_from_session(mapping.name) do |args|
461
485
  mapping.to.serialize_from_session(*args)
462
486
  end
463
487
  end
464
488
 
465
- @@warden_config_block.try :call, Devise.warden_config
489
+ @@warden_config_blocks.map { |block| block.call Devise.warden_config }
466
490
  true
467
491
  end
468
492
  end
469
493
 
470
494
  # Generate a friendly string randomly to be used as token.
471
- def self.friendly_token
472
- SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz')
495
+ # By default, length is 20 characters.
496
+ def self.friendly_token(length = 20)
497
+ # To calculate real characters, we must perform this operation.
498
+ # See SecureRandom.urlsafe_base64
499
+ rlength = (length * 3) / 4
500
+ SecureRandom.urlsafe_base64(rlength).tr('lIO0', 'sxyz')
473
501
  end
474
502
 
475
503
  # constant-time comparison algorithm to prevent timing attacks
@@ -1,24 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/active_record'
2
4
  require 'generators/devise/orm_helpers'
3
5
 
4
6
  module ActiveRecord
5
7
  module Generators
6
8
  class DeviseGenerator < ActiveRecord::Generators::Base
7
- argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
9
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
10
+
11
+ class_option :primary_key_type, type: :string, desc: "The type for primary key"
8
12
 
9
13
  include Devise::Generators::OrmHelpers
10
14
  source_root File.expand_path("../templates", __FILE__)
11
15
 
12
16
  def copy_devise_migration
13
17
  if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
14
- migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}"
18
+ migration_template "migration_existing.rb", "#{migration_path}/add_devise_to_#{table_name}.rb", migration_version: migration_version
15
19
  else
16
- migration_template "migration.rb", "db/migrate/devise_create_#{table_name}"
20
+ migration_template "migration.rb", "#{migration_path}/devise_create_#{table_name}.rb", migration_version: migration_version
17
21
  end
18
22
  end
19
23
 
20
24
  def generate_model
21
- invoke "active_record:model", [name], :migration => false unless model_exists? && behavior == :invoke
25
+ invoke "active_record:model", [name], migration: false unless model_exists? && behavior == :invoke
22
26
  end
23
27
 
24
28
  def inject_devise_content
@@ -39,8 +43,8 @@ module ActiveRecord
39
43
  def migration_data
40
44
  <<RUBY
41
45
  ## Database authenticatable
42
- t.string :email, :null => false, :default => ""
43
- t.string :encrypted_password, :null => false, :default => ""
46
+ t.string :email, null: false, default: ""
47
+ t.string :encrypted_password, null: false, default: ""
44
48
 
45
49
  ## Recoverable
46
50
  t.string :reset_password_token
@@ -50,11 +54,11 @@ module ActiveRecord
50
54
  t.datetime :remember_created_at
51
55
 
52
56
  ## Trackable
53
- t.integer :sign_in_count, :default => 0, :null => false
54
- t.datetime :current_sign_in_at
55
- t.datetime :last_sign_in_at
56
- t.string :current_sign_in_ip
57
- t.string :last_sign_in_ip
57
+ # t.integer :sign_in_count, default: 0, null: false
58
+ # t.datetime :current_sign_in_at
59
+ # t.datetime :last_sign_in_at
60
+ # t.#{ip_column} :current_sign_in_ip
61
+ # t.#{ip_column} :last_sign_in_ip
58
62
 
59
63
  ## Confirmable
60
64
  # t.string :confirmation_token
@@ -63,11 +67,44 @@ module ActiveRecord
63
67
  # t.string :unconfirmed_email # Only if using reconfirmable
64
68
 
65
69
  ## Lockable
66
- # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
70
+ # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
67
71
  # t.string :unlock_token # Only if unlock strategy is :email or :both
68
72
  # t.datetime :locked_at
69
73
  RUBY
70
74
  end
75
+
76
+ def ip_column
77
+ # Padded with spaces so it aligns nicely with the rest of the columns.
78
+ "%-8s" % (inet? ? "inet" : "string")
79
+ end
80
+
81
+ def inet?
82
+ postgresql?
83
+ end
84
+
85
+ def rails5_and_up?
86
+ Rails::VERSION::MAJOR >= 5
87
+ end
88
+
89
+ def postgresql?
90
+ config = ActiveRecord::Base.configurations[Rails.env]
91
+ config && config['adapter'] == 'postgresql'
92
+ end
93
+
94
+ def migration_version
95
+ if rails5_and_up?
96
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
97
+ end
98
+ end
99
+
100
+ def primary_key_type
101
+ primary_key_string if rails5_and_up?
102
+ end
103
+
104
+ def primary_key_string
105
+ key_string = options[:primary_key_type]
106
+ ", id: :#{key_string}" if key_string
107
+ end
71
108
  end
72
109
  end
73
110
  end
@@ -1,18 +1,20 @@
1
- class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
4
  def change
3
- create_table(:<%= table_name %>) do |t|
5
+ create_table :<%= table_name %><%= primary_key_type %> do |t|
4
6
  <%= migration_data -%>
5
7
 
6
8
  <% attributes.each do |attribute| -%>
7
9
  t.<%= attribute.type %> :<%= attribute.name %>
8
10
  <% end -%>
9
11
 
10
- t.timestamps
12
+ t.timestamps null: false
11
13
  end
12
14
 
13
- add_index :<%= table_name %>, :email, :unique => true
14
- add_index :<%= table_name %>, :reset_password_token, :unique => true
15
- # add_index :<%= table_name %>, :confirmation_token, :unique => true
16
- # add_index :<%= table_name %>, :unlock_token, :unique => true
15
+ add_index :<%= table_name %>, :email, unique: true
16
+ add_index :<%= table_name %>, :reset_password_token, unique: true
17
+ # add_index :<%= table_name %>, :confirmation_token, unique: true
18
+ # add_index :<%= table_name %>, :unlock_token, unique: true
17
19
  end
18
20
  end
@@ -1,6 +1,8 @@
1
- class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
2
4
  def self.up
3
- change_table(:<%= table_name %>) do |t|
5
+ change_table :<%= table_name %> do |t|
4
6
  <%= migration_data -%>
5
7
 
6
8
  <% attributes.each do |attribute| -%>
@@ -8,13 +10,13 @@ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
8
10
  <% end -%>
9
11
 
10
12
  # Uncomment below if timestamps were not included in your original model.
11
- # t.timestamps
13
+ # t.timestamps null: false
12
14
  end
13
15
 
14
- add_index :<%= table_name %>, :email, :unique => true
15
- add_index :<%= table_name %>, :reset_password_token, :unique => true
16
- # add_index :<%= table_name %>, :confirmation_token, :unique => true
17
- # add_index :<%= table_name %>, :unlock_token, :unique => true
16
+ add_index :<%= table_name %>, :email, unique: true
17
+ add_index :<%= table_name %>, :reset_password_token, unique: true
18
+ # add_index :<%= table_name %>, :confirmation_token, unique: true
19
+ # add_index :<%= table_name %>, :unlock_token, unique: true
18
20
  end
19
21
 
20
22
  def self.down
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ module Devise
6
+ module Generators
7
+ class ControllersGenerator < Rails::Generators::Base
8
+ CONTROLLERS = %w(confirmations passwords registrations sessions unlocks omniauth_callbacks).freeze
9
+
10
+ desc <<-DESC.strip_heredoc
11
+ Create inherited Devise controllers in your app/controllers folder.
12
+
13
+ Use -c to specify which controller you want to overwrite.
14
+ If you do no specify a controller, all controllers will be created.
15
+ For example:
16
+
17
+ rails generate devise:controllers users -c=sessions
18
+
19
+ This will create a controller class at app/controllers/users/sessions_controller.rb like this:
20
+
21
+ class Users::SessionsController < Devise::SessionsController
22
+ content...
23
+ end
24
+ DESC
25
+
26
+ source_root File.expand_path("../../templates/controllers", __FILE__)
27
+ argument :scope, required: true,
28
+ desc: "The scope to create controllers in, e.g. users, admins"
29
+ class_option :controllers, aliases: "-c", type: :array,
30
+ desc: "Select specific controllers to generate (#{CONTROLLERS.join(', ')})"
31
+
32
+ def create_controllers
33
+ @scope_prefix = scope.blank? ? '' : (scope.camelize + '::')
34
+ controllers = options[:controllers] || CONTROLLERS
35
+ controllers.each do |name|
36
+ template "#{name}_controller.rb",
37
+ "app/controllers/#{scope}/#{name}_controller.rb"
38
+ end
39
+ end
40
+
41
+ def show_readme
42
+ readme "README" if behavior == :invoke
43
+ end
44
+ end
45
+ end
46
+ end