devise-security 0.14.2 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +125 -59
  3. data/app/controllers/devise/paranoid_verification_code_controller.rb +13 -1
  4. data/app/controllers/devise/password_expired_controller.rb +24 -6
  5. data/app/views/devise/paranoid_verification_code/show.html.erb +3 -3
  6. data/app/views/devise/password_expired/show.html.erb +5 -5
  7. data/config/locales/bg.yml +41 -0
  8. data/config/locales/by.yml +49 -0
  9. data/config/locales/cs.yml +41 -0
  10. data/config/locales/de.yml +15 -2
  11. data/config/locales/en.yml +15 -2
  12. data/config/locales/es.yml +10 -9
  13. data/config/locales/fa.yml +41 -0
  14. data/config/locales/fr.yml +1 -0
  15. data/config/locales/hi.yml +42 -0
  16. data/config/locales/it.yml +35 -4
  17. data/config/locales/ja.yml +2 -1
  18. data/config/locales/nl.yml +41 -0
  19. data/config/locales/pt.yml +41 -0
  20. data/config/locales/ru.yml +49 -0
  21. data/config/locales/tr.yml +1 -0
  22. data/config/locales/uk.yml +49 -0
  23. data/config/locales/zh_CN.yml +41 -0
  24. data/config/locales/zh_TW.yml +41 -0
  25. data/lib/devise-security/controllers/helpers.rb +59 -50
  26. data/lib/devise-security/hooks/password_expirable.rb +2 -0
  27. data/lib/devise-security/hooks/session_limitable.rb +21 -11
  28. data/lib/devise-security/models/database_authenticatable_patch.rb +15 -5
  29. data/lib/devise-security/models/password_archivable.rb +2 -2
  30. data/lib/devise-security/models/password_expirable.rb +5 -1
  31. data/lib/devise-security/models/secure_validatable.rb +56 -6
  32. data/lib/devise-security/models/session_limitable.rb +10 -1
  33. data/lib/devise-security/validators/password_complexity_validator.rb +53 -24
  34. data/lib/devise-security/version.rb +1 -1
  35. data/lib/devise-security.rb +13 -5
  36. data/lib/generators/devise_security/install_generator.rb +3 -3
  37. data/lib/generators/templates/{devise-security.rb → devise_security.rb} +6 -1
  38. data/test/controllers/test_paranoid_verification_code_controller.rb +68 -0
  39. data/test/controllers/test_password_expired_controller.rb +121 -19
  40. data/test/controllers/test_security_question_controller.rb +16 -40
  41. data/test/dummy/app/assets/config/manifest.js +3 -0
  42. data/test/dummy/app/controllers/overrides/paranoid_verification_code_controller.rb +7 -0
  43. data/test/dummy/app/controllers/overrides/password_expired_controller.rb +7 -0
  44. data/test/dummy/app/controllers/widgets_controller.rb +3 -0
  45. data/test/dummy/app/models/application_user_record.rb +2 -1
  46. data/test/dummy/app/models/mongoid/confirmable_fields.rb +2 -0
  47. data/test/dummy/app/models/mongoid/database_authenticable_fields.rb +4 -3
  48. data/test/dummy/app/models/mongoid/expirable_fields.rb +2 -0
  49. data/test/dummy/app/models/mongoid/lockable_fields.rb +2 -0
  50. data/test/dummy/app/models/mongoid/mappings.rb +4 -2
  51. data/test/dummy/app/models/mongoid/omniauthable_fields.rb +2 -0
  52. data/test/dummy/app/models/mongoid/paranoid_verification_fields.rb +2 -0
  53. data/test/dummy/app/models/mongoid/password_archivable_fields.rb +2 -0
  54. data/test/dummy/app/models/mongoid/password_expirable_fields.rb +2 -0
  55. data/test/dummy/app/models/mongoid/recoverable_fields.rb +2 -0
  56. data/test/dummy/app/models/mongoid/registerable_fields.rb +4 -2
  57. data/test/dummy/app/models/mongoid/rememberable_fields.rb +2 -0
  58. data/test/dummy/app/models/mongoid/secure_validatable_fields.rb +2 -0
  59. data/test/dummy/app/models/mongoid/security_questionable_fields.rb +2 -0
  60. data/test/dummy/app/models/mongoid/session_limitable_fields.rb +2 -0
  61. data/test/dummy/app/models/mongoid/timeoutable_fields.rb +2 -0
  62. data/test/dummy/app/models/mongoid/trackable_fields.rb +2 -0
  63. data/test/dummy/app/models/mongoid/validatable_fields.rb +2 -0
  64. data/test/dummy/app/models/paranoid_verification_user.rb +26 -0
  65. data/test/dummy/app/models/password_expired_user.rb +26 -0
  66. data/test/dummy/app/models/user.rb +1 -2
  67. data/test/dummy/app/models/widget.rb +1 -3
  68. data/test/dummy/app/mongoid/one_user.rb +5 -5
  69. data/test/dummy/app/mongoid/user_on_engine.rb +2 -2
  70. data/test/dummy/app/mongoid/user_on_main_app.rb +2 -2
  71. data/test/dummy/app/mongoid/user_with_validations.rb +3 -3
  72. data/test/dummy/app/mongoid/user_without_email.rb +3 -3
  73. data/test/dummy/config/application.rb +4 -4
  74. data/test/dummy/config/boot.rb +1 -1
  75. data/test/dummy/config/environment.rb +1 -1
  76. data/test/dummy/config/environments/test.rb +3 -13
  77. data/test/dummy/config/initializers/migration_class.rb +1 -8
  78. data/test/dummy/config/locales/en.yml +10 -0
  79. data/test/dummy/config/mongoid.yml +1 -1
  80. data/test/dummy/config/routes.rb +5 -3
  81. data/test/dummy/db/migrate/20120508165529_create_tables.rb +3 -3
  82. data/test/dummy/lib/shared_expirable_columns.rb +1 -0
  83. data/test/dummy/lib/shared_security_questions_fields.rb +1 -0
  84. data/test/dummy/lib/shared_user.rb +17 -6
  85. data/test/dummy/lib/shared_user_without_email.rb +2 -1
  86. data/test/dummy/lib/shared_user_without_omniauth.rb +12 -3
  87. data/test/dummy/lib/shared_verification_fields.rb +1 -0
  88. data/test/dummy/{app/models/.gitkeep → log/development.log} +0 -0
  89. data/test/dummy/log/test.log +101533 -0
  90. data/test/integration/test_password_expirable_workflow.rb +53 -0
  91. data/test/integration/test_session_limitable_workflow.rb +2 -0
  92. data/test/orm/active_record.rb +7 -4
  93. data/test/orm/mongoid.rb +2 -1
  94. data/test/support/integration_helpers.rb +15 -33
  95. data/test/support/mongoid.yml +1 -1
  96. data/test/test_compatibility.rb +2 -0
  97. data/test/test_complexity_validator.rb +250 -29
  98. data/test/test_database_authenticatable_patch.rb +146 -0
  99. data/test/test_helper.rb +12 -6
  100. data/test/test_install_generator.rb +12 -2
  101. data/test/test_paranoid_verification.rb +0 -1
  102. data/test/test_password_archivable.rb +34 -11
  103. data/test/test_password_expirable.rb +26 -26
  104. data/test/test_secure_validatable.rb +292 -50
  105. data/test/test_secure_validatable_overrides.rb +185 -0
  106. data/test/test_session_limitable.rb +27 -1
  107. data/test/tmp/config/initializers/devise_security.rb +49 -0
  108. data/test/tmp/config/locales/devise.security_extension.by.yml +49 -0
  109. data/test/tmp/config/locales/devise.security_extension.cs.yml +41 -0
  110. data/test/tmp/config/locales/devise.security_extension.de.yml +41 -0
  111. data/test/tmp/config/locales/devise.security_extension.en.yml +42 -0
  112. data/test/tmp/config/locales/devise.security_extension.es.yml +30 -0
  113. data/test/tmp/config/locales/devise.security_extension.fa.yml +41 -0
  114. data/test/tmp/config/locales/devise.security_extension.fr.yml +30 -0
  115. data/test/tmp/config/locales/devise.security_extension.hi.yml +42 -0
  116. data/test/tmp/config/locales/devise.security_extension.it.yml +41 -0
  117. data/test/tmp/config/locales/devise.security_extension.ja.yml +30 -0
  118. data/test/tmp/config/locales/devise.security_extension.nl.yml +41 -0
  119. data/test/tmp/config/locales/devise.security_extension.pt.yml +41 -0
  120. data/test/tmp/config/locales/devise.security_extension.ru.yml +49 -0
  121. data/test/tmp/config/locales/devise.security_extension.tr.yml +18 -0
  122. data/test/tmp/config/locales/devise.security_extension.uk.yml +49 -0
  123. data/test/tmp/config/locales/devise.security_extension.zh_CN.yml +41 -0
  124. data/test/tmp/config/locales/devise.security_extension.zh_TW.yml +41 -0
  125. metadata +168 -132
  126. data/.codeclimate.yml +0 -63
  127. data/.document +0 -5
  128. data/.gitignore +0 -43
  129. data/.mdlrc +0 -1
  130. data/.rubocop.yml +0 -64
  131. data/.ruby-version +0 -1
  132. data/.travis.yml +0 -39
  133. data/Appraisals +0 -35
  134. data/Gemfile +0 -10
  135. data/Rakefile +0 -27
  136. data/devise-security.gemspec +0 -50
  137. data/gemfiles/rails_4.2_stable.gemfile +0 -16
  138. data/gemfiles/rails_5.0_stable.gemfile +0 -15
  139. data/gemfiles/rails_5.1_stable.gemfile +0 -15
  140. data/gemfiles/rails_5.2_stable.gemfile +0 -15
  141. data/gemfiles/rails_6.0_beta.gemfile +0 -15
  142. data/lib/devise-security/orm/active_record.rb +0 -20
  143. data/lib/devise-security/schema.rb +0 -66
  144. data/test/dummy/app/models/secure_user.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5aa65f547b5acbc4207678cda6b4af888f94f3c18a7ebb1ccd80888433cf350f
4
- data.tar.gz: ce3b96b475d683ba121c3db9477915c44c52ac27c9244a54f5c613e76a0e86e4
3
+ metadata.gz: 9d2d19c261f7efb929b61e3bfdb31fbe0dce4ae5ab81d829508338ec86486f09
4
+ data.tar.gz: fa6c34683e462867b85d9fefe9132dae0891e0fca4eb1fa32fc0c1f9fc9177f3
5
5
  SHA512:
6
- metadata.gz: 540d6e0534dd9c37d28e7281ada99959d73f6afb0de030f406305e689c237afda6ea94fc3f84f4392c4a5cea2243191aa1aaae4bf0f9e77efb41a41cff2e8497
7
- data.tar.gz: 6064b218564eb7c9b3d8b849185d4fe3bbd49c466e47716a6ee666dcbc5f02f27d7015dde4f32238c95f6189b32516afcf3101c2dea0cb0bd78e9f9bd2d70cfd
6
+ metadata.gz: 99cd7b257250d09474d2de4b1aeb2348ca1ec8ca651ff0cc11121e23a71faea5bc2085293c83fcb11d4d641d402a76977185df3bd39a2862d3cab6359a1f90ec
7
+ data.tar.gz: fc55c011517dbaaab893ebb5da71d6fcd0d65de43de21bb51620cec29104a187e6fb405f159b3ad14a5f40109c9e4a9d18695ae020f0485393fc9b5d4840968d
data/README.md CHANGED
@@ -1,28 +1,45 @@
1
1
  # Devise Security
2
2
 
3
- [![Build Status](https://travis-ci.org/devise-security/devise-security.svg?branch=master)](https://travis-ci.org/devise-security/devise-security)[![Coverage Status](https://coveralls.io/repos/github/devise-security/devise-security/badge.svg?branch=master)](https://coveralls.io/github/devise-security/devise-security?branch=master)[![Maintainability](https://api.codeclimate.com/v1/badges/ace7cd003a0db8bffa5a/maintainability)](https://codeclimate.com/github/devise-security/devise-security/maintainability)
3
+ [![Build Status](https://travis-ci.org/devise-security/devise-security.svg?branch=master)](https://travis-ci.org/devise-security/devise-security)
4
+ [![Coverage Status](https://coveralls.io/repos/github/devise-security/devise-security/badge.svg?branch=master)](https://coveralls.io/github/devise-security/devise-security?branch=master)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/ace7cd003a0db8bffa5a/maintainability)](https://codeclimate.com/github/devise-security/devise-security/maintainability)
4
6
 
5
- A [Devise](https://github.com/plataformatec/devise) extension to add additional security features required by modern web applications. Forked from [Devise Security Extension](https://github.com/phatworx/devise_security_extension)
7
+ A [Devise](https://github.com/heartcombo/devise) extension to add additional
8
+ security features required by modern web applications. Forked from
9
+ [Devise Security Extension](https://github.com/phatworx/devise_security_extension)
6
10
 
7
11
  It is composed of 7 additional Devise modules:
8
12
 
9
- - `:password_expirable` - passwords will expire after a configured time (and will need to be changed by the user). You will most likely want to use `:password_expirable` together with the `:password_archivable` module to [prevent the current expired password being reused](https://github.com/phatworx/devise_security_extension/issues/175) immediately as the new password.
10
- - `:secure_validatable` - better way to validate a model (email, stronger password validation). Don't use with Devise `:validatable` module!
11
- - `:password_archivable` - save used passwords in an `old_passwords` table for history checks (don't be able to use a formerly used password)
12
- - `:session_limitable` - ensures, that there is only one session usable per account at once
13
- - `:expirable` - expires a user account after x days of inactivity (default 90 days)
14
- - `:security_questionable` - as accessible substitution for captchas (security question with captcha fallback)
15
- - `:paranoid_verification` - admin can generate verification code that user needs to fill in otherwise he wont be able to use the application.
13
+ - `:password_expirable` - passwords will expire after a configured time (and
14
+ will need to be changed by the user). You will most likely want to use
15
+ `:password_expirable` together with the `:password_archivable` module to
16
+ [prevent the current expired password from being reused](https://github.com/phatworx/devise_security_extension/issues/175)
17
+ immediately as the new password.
18
+ - `:secure_validatable` - better way to validate a model (email, stronger
19
+ password validation). Don't use with Devise `:validatable` module!
20
+ - `:password_archivable` - save used passwords in an `old_passwords` table for
21
+ history checks (prevent reusing passwords)
22
+ - `:session_limitable` - ensures, that there is only one session usable per
23
+ account at once
24
+ - `:expirable` - expires a user account after x days of inactivity (default 90
25
+ days)
26
+ - `:security_questionable` - as accessible substitution for captchas (security
27
+ question with captcha fallback)
28
+ - `:paranoid_verification` - admin can generate verification code that user
29
+ needs to fill in otherwise he won't be able to use the application.
16
30
 
17
31
  Configuration and database schema for each module below.
18
32
 
19
33
  ## Additional features
20
34
 
21
- - **captcha support** for `sign_up`, `sign_in`, `recover` and `unlock` (to make automated mass creation and brute forcing of accounts harder)
35
+ **captcha support** for `sign_up`, `sign_in`, `recover` and `unlock` (to make
36
+ automated mass creation and brute forcing of accounts harder)
22
37
 
23
38
  ## Getting started
24
39
 
25
- Devise Security works with Devise on Rails 4.2 onwards. You can add it to your Gemfile after you successfully set up Devise (see [Devise documentation](https://github.com/plataformatec/devise)) with:
40
+ Devise Security works with Devise on Rails >= 5.2. You can add it to your
41
+ Gemfile after you successfully set up Devise (see
42
+ [Devise documentation](https://github.com/heartcombo/devise)) with:
26
43
 
27
44
  ```ruby
28
45
  gem 'devise-security'
@@ -36,7 +53,10 @@ After you installed Devise Security you need to run the generator:
36
53
  rails generate devise_security:install
37
54
  ```
38
55
 
39
- The generator adds optional configurations to `config/initializers/devise-security.rb`. Enable the modules you wish to use in the initializer you are ready to add Devise Security modules on top of Devise modules to any of your Devise models:
56
+ The generator adds optional configurations to
57
+ `config/initializers/devise_security.rb`. Enable the modules you wish to use in
58
+ the initializer you are ready to add Devise Security modules on top of Devise
59
+ modules to any of your Devise models:
40
60
 
41
61
  ```ruby
42
62
  devise :password_expirable, :secure_validatable, :password_archivable, :session_limitable, :expirable
@@ -44,13 +64,16 @@ devise :password_expirable, :secure_validatable, :password_archivable, :session_
44
64
 
45
65
  ### E-mail Validation
46
66
 
47
- for `:secure_validatable` you need to have a way to validate an e-mail. There are multiple libraries that support this, and even a way built into Ruby!
67
+ For `:secure_validatable` you need to have a way to validate an e-mail. There
68
+ are multiple libraries that support this, and even a way built into Ruby!
48
69
 
49
- [Ruby Constant](http://yogodoshi.com/ruby-already-has-its-own-regular-expression-to-validate-emails/)
50
- * Note: This method would require a `email_validation` method to be defined in order to hook into the `validates` method defined here.
51
- [email_address](https://github.com/afair/email_address) gem
52
- [valid_email2](https://github.com/micke/valid_email2) gem
53
- [rails_email_validator](https://github.com/phatworx/rails_email_validator) gem (deprecated)
70
+ - (Recommended) Ruby built-in `URI::MailTo::EMAIL_REGEXP` constant
71
+ > Note: This method would require a `email_validation` method to be defined in
72
+ > order to hook into the `validates` method defined here.
73
+ - [email_address](https://github.com/afair/email_address) gem
74
+ - [valid_email2](https://github.com/micke/valid_email2) gem
75
+ - [rails_email_validator](https://github.com/phatworx/rails_email_validator) gem
76
+ (deprecated)
54
77
 
55
78
  ## Configuration
56
79
 
@@ -61,11 +84,13 @@ Devise.setup do |config|
61
84
 
62
85
  # Password expires after a configurable time (in seconds).
63
86
  # Or expire passwords on demand by setting this configuration to `true`
64
- # Use `user.need_password_change!` to expire a password.
87
+ # Use `user.need_change_password!` to expire a password.
65
88
  # Setting the configuration to `false` will completely disable expiration checks.
66
89
  # config.expire_password_after = 3.months | true | false
67
90
 
68
91
  # Need 1 char each of: A-Z, a-z, 0-9, and a punctuation mark or symbol
92
+ # You may use "digits" in place of "digit" and "symbols" in place of
93
+ # "symbol" based on your preference
69
94
  # config.password_complexity = { digit: 1, lower: 1, symbol: 1, upper: 1 }
70
95
 
71
96
  # Number of old passwords in archive
@@ -101,65 +126,76 @@ Devise.setup do |config|
101
126
  # ==> Configuration for :expirable
102
127
  # Time period for account expiry from last_activity_at
103
128
  # config.expire_after = 90.days
129
+
130
+ # Allow passwords to be equal to email (false, true)
131
+ # config.allow_passwords_equal_to_email = false
104
132
  end
105
133
  ```
106
134
 
107
135
  ## Other ORMs
108
136
 
109
- Devise-security supports [Mongoid](https://rubygems.org/gems/mongoid) as an alternative ORM to active_record. To use this ORM, add this to your `Gemfile`.
137
+ Devise-security supports [Mongoid](https://rubygems.org/gems/mongoid) as an
138
+ alternative ORM to active_record. To use this ORM, add this to your `Gemfile`.
110
139
 
111
- gem 'mongoid'
140
+ ```ruby
141
+ gem 'mongoid'
142
+ ```
112
143
 
113
144
  And then ensure that the environment variable `DEVISE_ORM=mongoid` is set.
114
145
 
115
146
  For local development you will need to have MongoDB installed locally.
116
147
 
117
- brew install mongodb
148
+ ```bash
149
+ brew install mongodb
150
+ ```
118
151
 
119
152
  ### Rails App setup example with Mongoid
120
153
 
121
154
  ```ruby
122
155
  # inside config/application.rb
123
- require File.expand_path('../boot', __FILE__)
124
- #...
125
- DEVISE_ORM=:mongoid
156
+ require File.expand_path('../boot', __FILE__)
157
+ #...
158
+ DEVISE_ORM=:mongoid
126
159
 
127
160
  # Require the gems listed in Gemfile, including any gems
128
161
  # you've limited to :test, :development, or :production.
129
- Bundler.require(*Rails.groups)
162
+ Bundler.require(*Rails.groups)
130
163
 
131
- module MyApp
164
+ module MyApp
132
165
  class Application < Rails::Application
133
166
  #...
134
167
  end
135
- end
168
+ end
136
169
  ```
137
170
 
138
171
  ## Captcha-Support
139
172
 
140
- The captcha support depends on [EasyCaptcha](https://github.com/phatworx/easy_captcha). See further documentation there.
173
+ The captcha support depends on
174
+ [EasyCaptcha](https://github.com/phatworx/easy_captcha). See further
175
+ documentation there.
141
176
 
142
177
  ### Installation
143
178
 
144
179
  1. Add EasyCaptcha to your `Gemfile` with
145
180
 
146
- ```ruby
147
- gem 'easy_captcha'
148
- ```
181
+ ```ruby
182
+ gem 'easy_captcha'
183
+ ```
149
184
 
150
- 1. Run the initializer
185
+ 2. Run the initializer
151
186
 
152
- ```ruby
153
- rails generate easy_captcha:install
154
- ```
187
+ ```ruby
188
+ rails generate easy_captcha:install
189
+ ```
155
190
 
156
- 1. Enable captcha - see "Configuration" of Devise Security above.
157
- 1. Add the captcha in the generated devise views for each controller you have activated
191
+ 3. Enable captcha - see "Configuration" of Devise Security above.
192
+ 4. Add the captcha in the generated devise views for each controller you have
193
+ activated.
158
194
 
159
- ```erb
160
- <p><%= captcha_tag %></p>
161
- <p><%= text_field_tag :captcha %></p>
162
- ```
195
+ ```erb
196
+ <p><%= captcha_tag %></p>
197
+ <p><%= text_field_tag :captcha %></p>
198
+ ```
163
199
 
164
200
  ## Schema
165
201
 
@@ -174,7 +210,8 @@ end
174
210
  add_index :the_resources, :password_changed_at
175
211
  ```
176
212
 
177
- Note: setting `password_changed_at` to `nil` will require the user to change their password.
213
+ Note: setting `password_changed_at` to `nil` will require the user to change
214
+ their password.
178
215
 
179
216
  ### Password archivable
180
217
 
@@ -199,6 +236,20 @@ create_table :the_resources do |t|
199
236
  end
200
237
  ```
201
238
 
239
+ #### Bypassing session limitable
240
+
241
+ Sometimes it's useful to impersonate a user without authentication (e.g.
242
+ [administrator impersonating a user](https://github.com/heartcombo/devise/wiki/How-To:-Sign-in-as-another-user-if-you-are-an-admin)),
243
+ in this case the `session_limitable` strategy will log out the user, and if the
244
+ user logs in while the administrator is still logged in, the administrator will
245
+ be logged out.
246
+
247
+ For such cases the following can be used:
248
+
249
+ ```ruby
250
+ sign_in(User.find(params[:id]), scope: :user, skip_session_limitable: true)
251
+ ```
252
+
202
253
  ### Expirable
203
254
 
204
255
  ```ruby
@@ -271,13 +322,13 @@ end
271
322
 
272
323
  ## Requirements
273
324
 
274
- * Devise (<https://github.com/plataformatec/devise>)
275
- * Rails 4.2 onwards (<http://github.com/rails/rails>)
276
- * recommendations:
277
- - `autocomplete-off` (<http://github.com/phatworx/autocomplete-off>)
278
- - `easy_captcha` (<http://github.com/phatworx/easy_captcha>)
279
- - `mongodb` (<https://www.mongodb.com/>)
280
- - `rvm` (<https://rvm.io/>)
325
+ - Devise (<https://github.com/heartcombo/devise>)
326
+ - Rails 5.2 onwards (<http://github.com/rails/rails>)
327
+ - recommendations:
328
+ - `autocomplete-off` (<http://github.com/phatworx/autocomplete-off>)
329
+ - `easy_captcha` (<http://github.com/phatworx/easy_captcha>)
330
+ - `mongodb` (<https://www.mongodb.com/>)
331
+ - `rvm` (<https://rvm.io/>)
281
332
 
282
333
  ## Todo
283
334
 
@@ -295,7 +346,8 @@ end
295
346
  - 0.8 Support for Rails 4 (+ variety of patches)
296
347
  - 0.11 Support for Rails 5. Forked to allow project maintenance and features
297
348
 
298
- See also [Github Releases](https://github.com/devise-security/devise-security/releases)
349
+ See also
350
+ [Github Releases](https://github.com/devise-security/devise-security/releases)
299
351
 
300
352
  ## Maintainers
301
353
 
@@ -305,22 +357,36 @@ See also [Github Releases](https://github.com/devise-security/devise-security/re
305
357
 
306
358
  ## Contributing to devise-security
307
359
 
308
- - Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
309
- - Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
360
+ - Check out the latest master to make sure the feature hasn't been implemented
361
+ or the bug hasn't been fixed yet
362
+ - Check out the issue tracker to make sure someone already hasn't requested it
363
+ and/or contributed it
310
364
  - Fork the project
311
365
  - Start a feature/bugfix branch
312
366
  - Commit and push until you are happy with your contribution
313
- - Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
314
- - Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
367
+ - Make sure to add tests for it. This is important so I don't break it in a
368
+ future version unintentionally.
369
+ - Please try not to mess with the Rakefile, version, or history. If you want to
370
+ have your own version, or is otherwise necessary, that is fine, but please
371
+ isolate to its own commit so I can cherry-pick around it.
315
372
 
316
373
  ## Running tests
317
374
 
318
- Standard tests can be invoked using `rake`. To run the tests against the `mongoid` ORM, use `DEVISE_ORM=mongoid rake` while `mongodb` is running.
375
+ Standard tests can be invoked using `rake`. To run the tests against the
376
+ `mongoid` ORM, use `DEVISE_ORM=mongoid rake` while `mongodb` is running.
377
+
378
+ ## Maintenance Policy
319
379
 
320
- To locally simulate what travis-ci will run when you push code use:
380
+ We are committed to maintain support for `devise-security` for all normal or
381
+ security maintenance versions of the Ruby language
382
+ [as listed here](https://www.ruby-lang.org/en/downloads/branches/), and for the
383
+ Ruby on Rails framework
384
+ [as per their maintenance policy](https://rubyonrails.org/maintenance/).
321
385
 
322
- $ gem install bundler -v '1.17.3'
323
- $ BUNDLER_VERSION=1.17.3 wwtd
386
+ In order to avoid introducing bugs caused by backwardly incompatible Ruby
387
+ language features, it is highly recommended that all development work be done
388
+ using the oldest supported ruby version. The contents of the `.ruby-version`
389
+ file should reflect this.
324
390
 
325
391
  ## Copyright
326
392
 
@@ -17,12 +17,24 @@ class Devise::ParanoidVerificationCodeController < DeviseController
17
17
  warden.session(scope)['paranoid_verify'] = false
18
18
  set_flash_message :notice, :updated
19
19
  bypass_sign_in resource, scope: scope
20
- redirect_to stored_location_for(scope) || :root
20
+ redirect_to after_paranoid_verification_code_update_path_for(resource)
21
21
  else
22
22
  respond_with(resource, action: :show)
23
23
  end
24
24
  end
25
25
 
26
+ # Allows you to customize where the user is redirected to after the update action
27
+ # successfully completes.
28
+ #
29
+ # Defaults to the request's original path, and then `root` if that is `nil`.
30
+ #
31
+ # @param resource [ActiveModel::Model] Devise `resource` model for logged in user.
32
+ #
33
+ # @return [String, Symbol] The path that the user will be redirected to.
34
+ def after_paranoid_verification_code_update_path_for(_resource)
35
+ stored_location_for(scope) || :root
36
+ end
37
+
26
38
  private
27
39
 
28
40
  def resource_params
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Devise::PasswordExpiredController < DeviseController
4
+ before_action :verify_requested_format!
4
5
  skip_before_action :handle_password_change
5
6
  before_action :skip_password_change, only: [:show, :update]
6
7
  prepend_before_action :authenticate_scope!, only: [:show, :update]
@@ -9,34 +10,51 @@ class Devise::PasswordExpiredController < DeviseController
9
10
  respond_with(resource)
10
11
  end
11
12
 
13
+ # Update the password stored on the `resource`.
14
+ # @note if a common data format like :json or :xml are requested
15
+ # this will respond with a 204 No Content and set the Location header.
16
+ # Useful for dealing with APIs when JS clients would otherwise automatically
17
+ # follow the redirect, which can be problematic.
18
+ # @see https://stackoverflow.com/questions/228225/prevent-redirection-of-xmlhttprequest
19
+ # @see https://github.com/axios/axios/issues/932#issuecomment-307390761
20
+ # @see https://github.com/devise-security/devise-security/pull/111
12
21
  def update
13
22
  resource.extend(Devise::Models::DatabaseAuthenticatablePatch)
14
23
  if resource.update_with_password(resource_params)
15
24
  warden.session(scope)['password_expired'] = false
16
25
  set_flash_message :notice, :updated
17
26
  bypass_sign_in resource, scope: scope
18
- redirect_to stored_location_for(scope) || :root
27
+ respond_with({}, location: after_password_expired_update_path_for(resource))
19
28
  else
20
29
  clean_up_passwords(resource)
21
30
  respond_with(resource, action: :show)
22
31
  end
23
32
  end
24
33
 
34
+ # Allows you to customize where the user is sent to after the update action
35
+ # successfully completes.
36
+ #
37
+ # Defaults to the request's original path, and then `root` if that is `nil`.
38
+ #
39
+ # @param resource [ActiveModel::Model] Devise `resource` model for logged in user.
40
+ #
41
+ # @return [String, Symbol] The path that the user will be sent to.
42
+ def after_password_expired_update_path_for(_resource)
43
+ stored_location_for(scope) || :root
44
+ end
45
+
25
46
  private
26
47
 
27
48
  def skip_password_change
28
49
  return if !resource.nil? && resource.need_change_password?
50
+
29
51
  redirect_to :root
30
52
  end
31
53
 
32
54
  def resource_params
33
55
  permitted_params = [:current_password, :password, :password_confirmation]
34
56
 
35
- if params.respond_to?(:permit)
36
- params.require(resource_name).permit(*permitted_params)
37
- else
38
- params[scope].slice(*permitted_params)
39
- end
57
+ params.require(resource_name).permit(*permitted_params)
40
58
  end
41
59
 
42
60
  def scope
@@ -1,10 +1,10 @@
1
- <h2>Submit verification code</h2>
1
+ <h2>t('.submit_verification_code')</h2>
2
2
 
3
3
  <%= form_for(resource, as: resource_name, url: [resource_name, :paranoid_verification_code], html: { method: :put }) do |f| %>
4
4
  <%= render partial: 'devise/shared/error_messages' %>
5
5
 
6
- <p><%= f.label :paranoid_verification_code, 'Verification code' %><br />
6
+ <p><%= f.label :paranoid_verification_code, t('.verification_code') %><br />
7
7
  <%= f.text_field :paranoid_verification_code, value: '' %></p>
8
8
 
9
- <p><%= f.submit 'Submit' %></p>
9
+ <p><%= f.submit t('.submit') %></p>
10
10
  <% end %>
@@ -1,16 +1,16 @@
1
- <h2>Renew your password</h2>
1
+ <h2><%= t('.renew_your_password') %></h2>
2
2
 
3
3
  <%= form_for(resource, as: resource_name, url: [resource_name, :password_expired], html: { method: :put }) do |f| %>
4
4
  <%= render partial: 'devise/shared/error_messages' %>
5
5
 
6
- <p><%= f.label :current_password, 'Current password' %><br />
6
+ <p><%= f.label :current_password, t('.current_password') %><br />
7
7
  <%= f.password_field :current_password %></p>
8
8
 
9
- <p><%= f.label :password, 'New password' %><br />
9
+ <p><%= f.label :password, t('.new_password') %><br />
10
10
  <%= f.password_field :password %></p>
11
11
 
12
- <p><%= f.label :password_confirmation, 'Confirm new password' %><br />
12
+ <p><%= f.label :password_confirmation, t('.new_password_confirmation') %><br />
13
13
  <%= f.password_field :password_confirmation %></p>
14
14
 
15
- <p><%= f.submit 'Change my password' %></p>
15
+ <p><%= f.submit t('.change_my_password') %></p>
16
16
  <% end %>
@@ -0,0 +1,41 @@
1
+ bg:
2
+ errors:
3
+ messages:
4
+ taken_in_past: 'е използвана и преди.'
5
+ equal_to_current_password: 'трябва да е различна от настоящата парола.'
6
+ equal_to_email: 'трябва да е различна от e-mail адреса.'
7
+ password_complexity:
8
+ digit:
9
+ one: трябва да съдържа поне една цифра
10
+ other: трябва да съдържа %{count} цифри
11
+ lower:
12
+ one: трябва да съдържа поне една малка буква
13
+ other: трябва да съдържа поне %{count} малки букви
14
+ symbol:
15
+ one: трябва да съдържа поне един пунктоационен знак или символ
16
+ other: трябва да съдържа поне %{count} пунктоационни знака или символи
17
+ upper:
18
+ one: трябва да съдържа поне една главна буква
19
+ other: трябва да съдържа поне %{count} главни букви
20
+ devise:
21
+ invalid_captcha: 'Кодът е грешен.'
22
+ invalid_security_question: 'Отговора на тайния въпрос е грешен.'
23
+ paranoid_verify:
24
+ code_required: 'Моля въведете кода, който нашия екип по поддръжката Ви е предоставил'
25
+ paranoid_verification_code:
26
+ show:
27
+ submit_verification_code: Изпрати код за потвърждение
28
+ verification_code: Код за потвърждение
29
+ submit: Изпрати
30
+ password_expired:
31
+ updated: 'Вашата нова парола е запазена.'
32
+ change_required: 'Вашата парола е изтекла. Моля подновете паролата си.'
33
+ show:
34
+ renew_your_password: Подновете паролата си
35
+ current_password: Настояща парола
36
+ new_password: Нова парола
37
+ new_password_confirmation: Потвърждение на нова парола
38
+ change_my_password: Промени паролата ми
39
+ failure:
40
+ session_limited: 'Вашето потребителско име и парола са използвани в друг браузър. Моля влезте отново за да продължите в този браузър.'
41
+ expired: 'Вашия акаунт е затворен поради неактивност. Моля свържете се с администратор.'
@@ -0,0 +1,49 @@
1
+ by:
2
+ errors:
3
+ messages:
4
+ taken_in_past: 'ужо раней выкарыстоўваўся.'
5
+ equal_to_current_password: 'павінен адрознівацца ад сучаснага пароля.'
6
+ equal_to_email: 'павінна адрознівацца ад электроннай пошты.'
7
+ password_complexity:
8
+ digit:
9
+ one: 'павінен утрымліваць хоць адну лічбу'
10
+ few: 'павінен утрымліваць хоць %{count} лічбы'
11
+ many: 'павінен утрымліваць хоць %{count} лічбы'
12
+ other: 'павінен утрымліваць хоць %{count} лічбы'
13
+ lower:
14
+ one: 'павінен утрымліваць хоць адну маленькую літару'
15
+ few: 'павінен утрымліваць хоць %{count} малыx літары'
16
+ many: 'павінен утрымліваць хоць %{count} малыx літары'
17
+ other: 'павінен утрымліваць хоць %{count} малыx літары'
18
+ symbol:
19
+ one: 'павінен утрымліваць хоць адзін знак пунктуацыі або сімвал'
20
+ few: 'павінен утрымліваць хоць %{count} знака пунктуацыі або сімвала'
21
+ many: 'павінен утрымліваць хоць %{count} знака пунктуацыі або сімвала'
22
+ other: 'павінен утрымліваць хоць %{count} знака пунктуацыі або сімвала'
23
+ upper:
24
+ one: 'павінен утрымліваць хоць адну вялікую літару'
25
+ few: 'павінен утрымліваць хоць %{count} вялікіx літары'
26
+ many: 'павінен утрымліваць хоць %{count} вялікіx літары'
27
+ other: 'павінен утрымліваць хоць %{count} вялікіx літары'
28
+ devise:
29
+ invalid_captcha: 'Уведзены няправільны код капчы.'
30
+ invalid_security_question: 'Адказ на сакрэтнае пытанне быў няправільны.'
31
+ paranoid_verify:
32
+ code_required: 'Калі ласка, увядзіце код, атрыманы ад нашай каманды падтрымкі'
33
+ paranoid_verification_code:
34
+ show:
35
+ submit_verification_code: 'Увод кода пацверджання'
36
+ verification_code: 'Код пацверджання'
37
+ submit: 'Адправіць'
38
+ password_expired:
39
+ updated: 'Ваш новы пароль захаваны.'
40
+ change_required: 'Ваш пароль састарэў. Калі ласка, усталюйце новы.'
41
+ show:
42
+ renew_your_password: 'Змена пароля'
43
+ current_password: 'Сучасны пароль'
44
+ new_password: 'Новы пароль'
45
+ new_password_confirmation: 'Пацвердзіце новы пароль'
46
+ change_my_password: 'Змяніць пароль'
47
+ failure:
48
+ session_limited: 'Вашы параметры ўваходу выкарыстоўваюцца ў іншым браўзэры. Калі ласка, аўтарызуйцеся зноў, каб працягнуць у гэтым браўзэры.'
49
+ expired: 'Ваш уліковы запіс састарэў з-за неактыўнасці. Калі ласка, звяжыцеся з адміністратарам.'
@@ -0,0 +1,41 @@
1
+ cs:
2
+ errors:
3
+ messages:
4
+ taken_in_past: bylo již použito v minulosti.
5
+ equal_to_current_password: se musí lišit od aktuálního hesla.
6
+ equal_to_email: musí být jiný než e-mail.
7
+ password_complexity:
8
+ digit:
9
+ one: musí obsahovat alespoň jednu číslici
10
+ other: musí obsahovat alespoň %{count} číslice
11
+ lower:
12
+ one: musí obsahovat alespoň jedno malé písmeno
13
+ other: musí obsahovat alespoň %{count} malé písmena
14
+ symbol:
15
+ one: musí obsahovat alespoň jedno interpunkční znaménko nebo symbol
16
+ other: musí obsahovat alespoň %{count} interpunkční znaménka nebo symboly
17
+ upper:
18
+ one: musí obsahovat alespoň jedno velké písmeno
19
+ other: musí obsahovat alespoň %{count} velké písmena
20
+ devise:
21
+ invalid_captcha: Chybná captcha.
22
+ invalid_security_question: Chybná odpověď na bezpečnostní otázku.
23
+ paranoid_verify:
24
+ code_required: Zadejte kód, který poskytla naše podpora
25
+ paranoid_verification_code:
26
+ show:
27
+ submit_verification_code: Odeslat ověřovací kód
28
+ verification_code: Ověřovací kód
29
+ submit: Odeslat
30
+ password_expired:
31
+ updated: Vaše nové heslo bylo uloženo.
32
+ change_required: Platnost Vašeho hesla vypršela. Prosím, obnovte si jej.
33
+ show:
34
+ renew_your_password: Obnovit heslo
35
+ current_password: Současné heslo
36
+ new_password: Nové heslo
37
+ new_password_confirmation: Potvrďte nové heslo
38
+ change_my_password: Změnit moje heslo
39
+ failure:
40
+ session_limited: Vaše přihlašovací údaje byly použity v jiném prohlížeči. Chcete-li pokračovat v tomto prohlížeči, znovu se přihlaste.
41
+ expired: Platnost Vašeho účtu vypršela z důvodu nečinnosti. Obraťte se na správce webu.
@@ -3,6 +3,7 @@ de:
3
3
  messages:
4
4
  taken_in_past: 'wurde bereits in der Vergangenheit verwendet.'
5
5
  equal_to_current_password: 'darf nicht dem aktuellen Passwort entsprechen.'
6
+ equal_to_email: 'darf nicht dem E-mail entsprechen.'
6
7
  password_complexity:
7
8
  digit:
8
9
  one: muss mindestens eine Ziffer enthalten
@@ -11,18 +12,30 @@ de:
11
12
  one: muss mindestens einen Kleinbuchstaben enthalten
12
13
  other: muss mindestens %{count} Kleinbuchstaben enthalten
13
14
  symbol:
14
- one: muss mindestens ein Satzzeichen enthalten
15
- other: muss mindestens %{count} Satzzeichen enthalten
15
+ one: muss mindestens ein Sonderzeichen enthalten
16
+ other: muss mindestens %{count} Sonderzeichen enthalten
16
17
  upper:
17
18
  one: muss mindestens einen Großbuchstaben enthalten
18
19
  other: muss mindestens %{count} Großbuchstaben enthalten
19
20
  devise:
20
21
  invalid_captcha: 'Die Captcha-Eingabe ist nicht gültig.'
22
+ invalid_security_question: 'Die Antwort auf die Sicherheitsfrage war ungültig.'
21
23
  paranoid_verify:
22
24
  code_required: 'Bitte geben Sie den Code ein, den unser Support-Team zur Verfügung gestellt hat.'
25
+ paranoid_verification_code:
26
+ show:
27
+ submit_verification_code: Bestätigungscode eingeben
28
+ verification_code: Bestätigungscode
29
+ submit: Bestätigen
23
30
  password_expired:
24
31
  updated: 'Das neue Passwort wurde übernommen.'
25
32
  change_required: 'Ihr Passwort ist abgelaufen. Bitte vergeben Sie ein neues Passwort.'
33
+ show:
34
+ renew_your_password: Vergeben Sie ein neues Passwort
35
+ current_password: Aktuelles Passwort
36
+ new_password: Neues Passwort
37
+ new_password_confirmation: Passwort bestätigen
38
+ change_my_password: Passwort ändern
26
39
  failure:
27
40
  session_limited: 'Ihre Anmeldedaten wurden in einem anderen Browser genutzt. Bitte melden Sie sich erneut an, um in diesem Browser fortzufahren.'
28
41
  expired: 'Ihr Account ist aufgrund zu langer Inaktivität abgelaufen. Bitte kontaktieren Sie den Administrator.'