devise-security 0.12.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +186 -63
  3. data/app/controllers/devise/paranoid_verification_code_controller.rb +2 -0
  4. data/app/controllers/devise/password_expired_controller.rb +13 -6
  5. data/app/views/devise/paranoid_verification_code/show.html.erb +4 -4
  6. data/app/views/devise/password_expired/show.html.erb +6 -6
  7. data/config/locales/by.yml +49 -0
  8. data/config/locales/cs.yml +41 -0
  9. data/config/locales/de.yml +30 -7
  10. data/config/locales/en.yml +25 -1
  11. data/config/locales/es.yml +19 -6
  12. data/config/locales/fa.yml +41 -0
  13. data/config/locales/fr.yml +30 -0
  14. data/config/locales/hi.yml +42 -0
  15. data/config/locales/it.yml +35 -4
  16. data/config/locales/ja.yml +30 -0
  17. data/config/locales/nl.yml +41 -0
  18. data/config/locales/pt.yml +41 -0
  19. data/config/locales/ru.yml +49 -0
  20. data/config/locales/tr.yml +18 -0
  21. data/config/locales/uk.yml +49 -0
  22. data/config/locales/zh_CN.yml +41 -0
  23. data/config/locales/zh_TW.yml +41 -0
  24. data/lib/devise-security/controllers/helpers.rb +61 -50
  25. data/lib/devise-security/hooks/expirable.rb +3 -1
  26. data/lib/devise-security/hooks/paranoid_verification.rb +2 -0
  27. data/lib/devise-security/hooks/password_expirable.rb +4 -0
  28. data/lib/devise-security/hooks/session_limitable.rb +31 -14
  29. data/lib/devise-security/models/active_record/old_password.rb +5 -0
  30. data/lib/devise-security/models/compatibility/active_record_patch.rb +40 -0
  31. data/lib/devise-security/models/compatibility/mongoid_patch.rb +31 -0
  32. data/lib/devise-security/models/compatibility.rb +8 -15
  33. data/lib/devise-security/models/database_authenticatable_patch.rb +3 -1
  34. data/lib/devise-security/models/expirable.rb +8 -2
  35. data/lib/devise-security/models/mongoid/old_password.rb +21 -0
  36. data/lib/devise-security/models/paranoid_verification.rb +2 -0
  37. data/lib/devise-security/models/password_archivable.rb +18 -7
  38. data/lib/devise-security/models/password_expirable.rb +103 -48
  39. data/lib/devise-security/models/secure_validatable.rb +26 -6
  40. data/lib/devise-security/models/security_questionable.rb +2 -0
  41. data/lib/devise-security/models/session_limitable.rb +19 -2
  42. data/lib/devise-security/orm/mongoid.rb +7 -0
  43. data/lib/devise-security/patches/confirmations_controller_captcha.rb +2 -0
  44. data/lib/devise-security/patches/confirmations_controller_security_question.rb +2 -0
  45. data/lib/devise-security/patches/controller_captcha.rb +2 -0
  46. data/lib/devise-security/patches/controller_security_question.rb +3 -1
  47. data/lib/devise-security/patches/passwords_controller_captcha.rb +2 -0
  48. data/lib/devise-security/patches/passwords_controller_security_question.rb +2 -0
  49. data/lib/devise-security/patches/registrations_controller_captcha.rb +2 -0
  50. data/lib/devise-security/patches/sessions_controller_captcha.rb +2 -0
  51. data/lib/devise-security/patches/unlocks_controller_captcha.rb +2 -0
  52. data/lib/devise-security/patches/unlocks_controller_security_question.rb +2 -0
  53. data/lib/devise-security/patches.rb +2 -0
  54. data/lib/devise-security/rails.rb +2 -0
  55. data/lib/devise-security/routes.rb +2 -0
  56. data/lib/devise-security/validators/password_complexity_validator.rb +35 -0
  57. data/lib/devise-security/version.rb +3 -1
  58. data/lib/devise-security.rb +16 -10
  59. data/lib/generators/devise_security/install_generator.rb +5 -3
  60. data/lib/generators/templates/devise_security.rb +47 -0
  61. data/test/{test_captcha_controller.rb → controllers/test_captcha_controller.rb} +2 -0
  62. data/test/controllers/test_password_expired_controller.rb +110 -0
  63. data/test/controllers/test_security_question_controller.rb +60 -0
  64. data/test/dummy/Rakefile +3 -1
  65. data/test/dummy/app/assets/config/manifest.js +3 -0
  66. data/test/dummy/app/controllers/application_controller.rb +2 -0
  67. data/test/dummy/app/controllers/captcha/sessions_controller.rb +2 -0
  68. data/test/dummy/app/controllers/security_question/unlocks_controller.rb +2 -0
  69. data/test/dummy/app/controllers/widgets_controller.rb +6 -0
  70. data/test/dummy/app/models/application_record.rb +10 -2
  71. data/test/dummy/app/models/application_user_record.rb +11 -0
  72. data/test/dummy/app/models/captcha_user.rb +7 -2
  73. data/test/dummy/app/models/mongoid/confirmable_fields.rb +13 -0
  74. data/test/dummy/app/models/mongoid/database_authenticable_fields.rb +17 -0
  75. data/test/dummy/app/models/mongoid/expirable_fields.rb +11 -0
  76. data/test/dummy/app/models/mongoid/lockable_fields.rb +13 -0
  77. data/test/dummy/app/models/mongoid/mappings.rb +13 -0
  78. data/test/dummy/app/models/mongoid/omniauthable_fields.rb +11 -0
  79. data/test/dummy/app/models/mongoid/paranoid_verification_fields.rb +10 -0
  80. data/test/dummy/app/models/mongoid/password_archivable_fields.rb +9 -0
  81. data/test/dummy/app/models/mongoid/password_expirable_fields.rb +10 -0
  82. data/test/dummy/app/models/mongoid/recoverable_fields.rb +11 -0
  83. data/test/dummy/app/models/mongoid/registerable_fields.rb +19 -0
  84. data/test/dummy/app/models/mongoid/rememberable_fields.rb +10 -0
  85. data/test/dummy/app/models/mongoid/secure_validatable_fields.rb +11 -0
  86. data/test/dummy/app/models/mongoid/security_questionable_fields.rb +13 -0
  87. data/test/dummy/app/models/mongoid/session_limitable_fields.rb +10 -0
  88. data/test/dummy/app/models/mongoid/timeoutable_fields.rb +9 -0
  89. data/test/dummy/app/models/mongoid/trackable_fields.rb +14 -0
  90. data/test/dummy/app/models/mongoid/validatable_fields.rb +7 -0
  91. data/test/dummy/app/models/secure_user.rb +7 -1
  92. data/test/dummy/app/models/security_question_user.rb +9 -4
  93. data/test/dummy/app/models/user.rb +15 -0
  94. data/test/dummy/app/models/widget.rb +6 -0
  95. data/test/dummy/app/mongoid/admin.rb +31 -0
  96. data/test/dummy/app/mongoid/one_user.rb +58 -0
  97. data/test/dummy/app/mongoid/shim.rb +25 -0
  98. data/test/dummy/app/mongoid/user_on_engine.rb +41 -0
  99. data/test/dummy/app/mongoid/user_on_main_app.rb +41 -0
  100. data/test/dummy/app/mongoid/user_with_validations.rb +37 -0
  101. data/test/dummy/app/mongoid/user_without_email.rb +35 -0
  102. data/test/dummy/config/application.rb +13 -7
  103. data/test/dummy/config/boot.rb +2 -0
  104. data/test/dummy/config/environment.rb +2 -0
  105. data/test/dummy/config/environments/test.rb +5 -13
  106. data/test/dummy/config/initializers/devise.rb +10 -3
  107. data/test/dummy/config/initializers/migration_class.rb +3 -6
  108. data/test/dummy/config/mongoid.yml +6 -0
  109. data/test/dummy/config/routes.rb +6 -3
  110. data/test/dummy/config.ru +3 -1
  111. data/test/dummy/db/migrate/20120508165529_create_tables.rb +13 -2
  112. data/test/dummy/db/migrate/20150402165590_add_verification_columns.rb +2 -0
  113. data/test/dummy/db/migrate/20150407162345_add_verification_attempt_column.rb +2 -0
  114. data/test/dummy/db/migrate/20160320162345_add_security_questions_fields.rb +2 -0
  115. data/test/dummy/db/migrate/20180318103603_add_expireable_columns.rb +2 -0
  116. data/test/dummy/db/migrate/20180318105329_add_confirmable_columns.rb +2 -0
  117. data/test/dummy/db/migrate/20180318105732_add_rememberable_columns.rb +2 -0
  118. data/test/dummy/db/migrate/20180318111336_add_recoverable_columns.rb +2 -0
  119. data/test/dummy/db/migrate/20180319114023_add_widget.rb +2 -0
  120. data/test/dummy/lib/shared_expirable_columns.rb +14 -0
  121. data/test/dummy/lib/shared_security_questions_fields.rb +16 -0
  122. data/test/dummy/lib/shared_user.rb +32 -0
  123. data/test/dummy/lib/shared_user_with_password_verification.rb +13 -0
  124. data/test/dummy/lib/shared_user_without_email.rb +28 -0
  125. data/test/dummy/lib/shared_user_without_omniauth.rb +15 -0
  126. data/test/dummy/lib/shared_verification_fields.rb +15 -0
  127. data/test/dummy/log/development.log +883 -0
  128. data/test/dummy/log/test.log +21689 -0
  129. data/test/integration/test_password_expirable_workflow.rb +53 -0
  130. data/test/integration/test_session_limitable_workflow.rb +67 -0
  131. data/test/orm/active_record.rb +15 -0
  132. data/test/orm/mongoid.rb +13 -0
  133. data/test/support/integration_helpers.rb +29 -0
  134. data/test/support/mongoid.yml +6 -0
  135. data/test/test_compatibility.rb +13 -0
  136. data/test/test_complexity_validator.rb +72 -0
  137. data/test/test_helper.rb +42 -9
  138. data/test/test_install_generator.rb +19 -2
  139. data/test/test_paranoid_verification.rb +2 -0
  140. data/test/test_password_archivable.rb +8 -7
  141. data/test/test_password_expirable.rb +70 -7
  142. data/test/test_secure_validatable.rb +97 -21
  143. data/test/test_session_limitable.rb +57 -0
  144. data/{lib/generators/templates → test/tmp/config/initializers}/devise-security.rb +12 -3
  145. data/test/tmp/config/locales/devise.security_extension.by.yml +49 -0
  146. data/test/tmp/config/locales/devise.security_extension.cs.yml +41 -0
  147. data/test/tmp/config/locales/devise.security_extension.de.yml +39 -0
  148. data/test/tmp/config/locales/devise.security_extension.en.yml +41 -0
  149. data/test/tmp/config/locales/devise.security_extension.es.yml +30 -0
  150. data/test/tmp/config/locales/devise.security_extension.fa.yml +41 -0
  151. data/test/tmp/config/locales/devise.security_extension.fr.yml +30 -0
  152. data/test/tmp/config/locales/devise.security_extension.hi.yml +42 -0
  153. data/test/tmp/config/locales/devise.security_extension.it.yml +41 -0
  154. data/test/tmp/config/locales/devise.security_extension.ja.yml +30 -0
  155. data/test/tmp/config/locales/devise.security_extension.nl.yml +41 -0
  156. data/test/tmp/config/locales/devise.security_extension.pt.yml +41 -0
  157. data/test/tmp/config/locales/devise.security_extension.ru.yml +49 -0
  158. data/test/tmp/config/locales/devise.security_extension.tr.yml +18 -0
  159. data/test/tmp/config/locales/devise.security_extension.uk.yml +49 -0
  160. data/test/tmp/config/locales/devise.security_extension.zh_CN.yml +41 -0
  161. data/test/tmp/config/locales/devise.security_extension.zh_TW.yml +41 -0
  162. metadata +235 -110
  163. data/.circleci/config.yml +0 -41
  164. data/.document +0 -5
  165. data/.gitignore +0 -40
  166. data/.rubocop.yml +0 -63
  167. data/.ruby-version +0 -1
  168. data/.travis.yml +0 -25
  169. data/Appraisals +0 -19
  170. data/Gemfile +0 -3
  171. data/Rakefile +0 -28
  172. data/devise-security.gemspec +0 -44
  173. data/gemfiles/rails_4.1_stable.gemfile +0 -8
  174. data/gemfiles/rails_4.2_stable.gemfile +0 -8
  175. data/gemfiles/rails_5.0_stable.gemfile +0 -8
  176. data/gemfiles/rails_5.1_stable.gemfile +0 -8
  177. data/gemfiles/rails_5.2_rc1.gemfile +0 -8
  178. data/lib/devise-security/models/old_password.rb +0 -4
  179. data/lib/devise-security/orm/active_record.rb +0 -18
  180. data/lib/devise-security/schema.rb +0 -64
  181. data/test/dummy/app/models/.gitkeep +0 -0
  182. data/test/test_password_expired_controller.rb +0 -44
  183. data/test/test_security_question_controller.rb +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ccd3b9a01ec2f531013bbed8d14cbf3131f2630d2c2d1a56d119268f1aa696c
4
- data.tar.gz: f9305b860b267fd4f49dc724864d1d822c1e4d0f952be56f78d02d1c6b1a1b3c
3
+ metadata.gz: 1d065158ce85c823918ca0fb7ad40382ca9957f7c5e0847e1fec86e1eaed0ffb
4
+ data.tar.gz: fa07606b583076da6b68ceeddf70f74f80c05f3adf752a057b8f935c9af68fb6
5
5
  SHA512:
6
- metadata.gz: f176d4afaee6b712cc7fa83c234cca6f286729f8a03660c33d10cf5cd363f49f70e56440f3e9e960f275ef4f7b2a846f60984af73e46e55f73266b431314cee1
7
- data.tar.gz: 00e810e6e1c6c1845cc67d534206378c111499f09bb849a8d4129b20bc4c52a89b9261cfaf07ec7bb243995cc016f50f26c99eba29a9c1c148b3d9ec8b6632c5
6
+ metadata.gz: 7f18a70374b20c80908006811184fc4757c4f678e11ff226d60b78ff0a3c1cf2612382185911b23692c6c7ed1553914f1361ab1243948ad1e1ff3ac91fdb5ab7
7
+ data.tar.gz: 68e392e9f0049659ad62977a0bb31910d4942b26ab24fab11b28e1e875286f2b48e9da20dd952f94bc4ac8350b1cd5199d9984e431d4664c865544a095b274b8
data/README.md CHANGED
@@ -4,27 +4,42 @@
4
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
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/ace7cd003a0db8bffa5a/maintainability)](https://codeclimate.com/github/devise-security/devise-security/maintainability)
6
6
 
7
- 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)
8
10
 
9
11
  It is composed of 7 additional Devise modules:
10
12
 
11
- * `:password_expirable` - passwords will expire after a configured time (and will need an update). 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.
12
- * `:secure_validatable` - better way to validate a model (email, stronger password validation). Don't use with Devise `:validatable` module!
13
- * `:password_archivable` - save used passwords in an `old_passwords` table for history checks (don't be able to use a formerly used password)
14
- * `:session_limitable` - ensures, that there is only one session usable per account at once
15
- * `:expirable` - expires a user account after x days of inactivity (default 90 days)
16
- * `:security_questionable` - as accessible substitution for captchas (security question with captcha fallback)
17
- * `: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.
18
30
 
19
31
  Configuration and database schema for each module below.
20
32
 
21
33
  ## Additional features
22
34
 
23
- * **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)
24
37
 
25
38
  ## Getting started
26
39
 
27
- Devise Security works with Devise on Rails 4.1 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.0. You can add it to your
41
+ Gemfile after you successfully set up Devise (see
42
+ [Devise documentation](https://github.com/heartcombo/devise)) with:
28
43
 
29
44
  ```ruby
30
45
  gem 'devise-security'
@@ -38,18 +53,27 @@ After you installed Devise Security you need to run the generator:
38
53
  rails generate devise_security:install
39
54
  ```
40
55
 
41
- The generator adds optional configurations to `config/initializers/devise-security.rb`. Enable
42
- 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:
43
60
 
44
61
  ```ruby
45
62
  devise :password_expirable, :secure_validatable, :password_archivable, :session_limitable, :expirable
46
63
  ```
47
64
 
48
- for `:secure_validatable` you need to add
65
+ ### E-mail Validation
49
66
 
50
- ```ruby
51
- gem 'rails_email_validator'
52
- ```
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!
69
+
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)
53
77
 
54
78
  ## Configuration
55
79
 
@@ -58,11 +82,14 @@ Devise.setup do |config|
58
82
  # ==> Security Extension
59
83
  # Configure security extension for devise
60
84
 
61
- # Should the password expire (e.g 3.months)
62
- # config.expire_password_after = 3.months
85
+ # Password expires after a configurable time (in seconds).
86
+ # Or expire passwords on demand by setting this configuration to `true`
87
+ # Use `user.need_change_password!` to expire a password.
88
+ # Setting the configuration to `false` will completely disable expiration checks.
89
+ # config.expire_password_after = 3.months | true | false
63
90
 
64
- # Need 1 char of A-Z, a-z and 0-9
65
- # config.password_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
91
+ # Need 1 char each of: A-Z, a-z, 0-9, and a punctuation mark or symbol
92
+ # config.password_complexity = { digit: 1, lower: 1, symbol: 1, upper: 1 }
66
93
 
67
94
  # Number of old passwords in archive
68
95
  # config.password_archiving_count = 5
@@ -97,34 +124,81 @@ Devise.setup do |config|
97
124
  # ==> Configuration for :expirable
98
125
  # Time period for account expiry from last_activity_at
99
126
  # config.expire_after = 90.days
127
+
128
+ # Allow passwords to be equal to email (false, true)
129
+ # config.allow_passwords_equal_to_email = false
100
130
  end
101
131
  ```
102
132
 
103
- ## Captcha-Support
104
- The captcha support depends on [EasyCaptcha](https://github.com/phatworx/easy_captcha). See further documentation there.
133
+ ## Other ORMs
105
134
 
106
- ### Installation
135
+ Devise-security supports [Mongoid](https://rubygems.org/gems/mongoid) as an
136
+ alternative ORM to active_record. To use this ORM, add this to your `Gemfile`.
107
137
 
108
- 1. Add EasyCaptcha to your `Gemfile` with
109
138
  ```ruby
110
- gem 'easy_captcha'
139
+ gem 'mongoid'
111
140
  ```
112
- 2. Run the initializer
141
+
142
+ And then ensure that the environment variable `DEVISE_ORM=mongoid` is set.
143
+
144
+ For local development you will need to have MongoDB installed locally.
145
+
146
+ ```bash
147
+ brew install mongodb
148
+ ```
149
+
150
+ ### Rails App setup example with Mongoid
151
+
113
152
  ```ruby
114
- rails generate easy_captcha:install
153
+ # inside config/application.rb
154
+ require File.expand_path('../boot', __FILE__)
155
+ #...
156
+ DEVISE_ORM=:mongoid
157
+
158
+ # Require the gems listed in Gemfile, including any gems
159
+ # you've limited to :test, :development, or :production.
160
+ Bundler.require(*Rails.groups)
161
+
162
+ module MyApp
163
+ class Application < Rails::Application
164
+ #...
165
+ end
166
+ end
115
167
  ```
168
+
169
+ ## Captcha-Support
170
+
171
+ The captcha support depends on
172
+ [EasyCaptcha](https://github.com/phatworx/easy_captcha). See further
173
+ documentation there.
174
+
175
+ ### Installation
176
+
177
+ 1. Add EasyCaptcha to your `Gemfile` with
178
+
179
+ ```ruby
180
+ gem 'easy_captcha'
181
+ ```
182
+
183
+ 2. Run the initializer
184
+
185
+ ```ruby
186
+ rails generate easy_captcha:install
187
+ ```
188
+
116
189
  3. Enable captcha - see "Configuration" of Devise Security above.
117
- 4. Add the captcha in the generated devise views for each controller you have activated
118
- ```erb
119
- <p><%= captcha_tag %></p>
120
- <p><%= text_field_tag :captcha %></p>
121
- ```
190
+ 4. Add the captcha in the generated devise views for each controller you have
191
+ activated.
122
192
 
123
- ## Schema
193
+ ```erb
194
+ <p><%= captcha_tag %></p>
195
+ <p><%= text_field_tag :captcha %></p>
196
+ ```
124
197
 
125
- Note: Unlike Devise, devise-security does not currently support mongoid. Pull requests are welcome!
198
+ ## Schema
126
199
 
127
200
  ### Password expirable
201
+
128
202
  ```ruby
129
203
  create_table :the_resources do |t|
130
204
  # other devise fields
@@ -134,7 +208,11 @@ end
134
208
  add_index :the_resources, :password_changed_at
135
209
  ```
136
210
 
211
+ Note: setting `password_changed_at` to `nil` will require the user to change
212
+ their password.
213
+
137
214
  ### Password archivable
215
+
138
216
  ```ruby
139
217
  create_table :old_passwords do |t|
140
218
  t.string :encrypted_password, null: false
@@ -143,19 +221,35 @@ create_table :old_passwords do |t|
143
221
  t.string :password_salt # Optional. bcrypt stores the salt in the encrypted password field so this column may not be necessary.
144
222
  t.datetime :created_at
145
223
  end
146
- add_index :old_passwords, [:password_archivable_type, :password_archivable_id], name: :index_password_archivable
224
+ add_index :old_passwords, [:password_archivable_type, :password_archivable_id], name: 'index_password_archivable'
147
225
  ```
148
226
 
149
227
  ### Session limitable
228
+
150
229
  ```ruby
151
230
  create_table :the_resources do |t|
152
231
  # other devise fields
153
232
 
154
- t.string :unique_session_id, limit: 20
233
+ t.string :unique_session_id
155
234
  end
156
235
  ```
157
236
 
237
+ #### Bypassing session limitable
238
+
239
+ Sometimes it's useful to impersonate a user without authentication (e.g.
240
+ [administrator impersonating a user](https://github.com/heartcombo/devise/wiki/How-To:-Sign-in-as-another-user-if-you-are-an-admin)),
241
+ in this case the `session_limitable` strategy will log out the user, and if the
242
+ user logs in while the administrator is still logged in, the administrator will
243
+ be logged out.
244
+
245
+ For such cases the following can be used:
246
+
247
+ ```ruby
248
+ sign_in(User.find(params[:id]), scope: :user, skip_session_limitable: true)
249
+ ```
250
+
158
251
  ### Expirable
252
+
159
253
  ```ruby
160
254
  create_table :the_resources do |t|
161
255
  # other devise fields
@@ -168,6 +262,7 @@ add_index :the_resources, :expired_at
168
262
  ```
169
263
 
170
264
  ### Paranoid verifiable
265
+
171
266
  ```ruby
172
267
  create_table :the_resources do |t|
173
268
  # other devise fields
@@ -180,7 +275,7 @@ add_index :the_resources, :paranoid_verification_code
180
275
  add_index :the_resources, :paranoid_verified_at
181
276
  ```
182
277
 
183
- [Documentation for Paranoid Verifiable module]( https://github.com/devise-security/devise-security/wiki/Paranoid-Verification)
278
+ [Documentation for Paranoid Verifiable module](https://github.com/devise-security/devise-security/wiki/Paranoid-Verification)
184
279
 
185
280
  ### Security questionable
186
281
 
@@ -207,7 +302,6 @@ SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblingstier?'
207
302
  SecurityQuestion.create! locale: :de, name: 'Was ist Ihr Lieblings-Reiseland?'
208
303
  ```
209
304
 
210
-
211
305
  ```ruby
212
306
  add_column :the_resources, :security_question_id, :integer
213
307
  add_column :the_resources, :security_question_answer, :string
@@ -226,42 +320,71 @@ end
226
320
 
227
321
  ## Requirements
228
322
 
229
- * Devise (https://github.com/plataformatec/devise)
230
- * Rails 4.1 onwards (http://github.com/rails/rails)
231
- * recommendations:
232
- * `autocomplete-off` (http://github.com/phatworx/autocomplete-off)
233
- * `easy_captcha` (http://github.com/phatworx/easy_captcha)
234
- * `rails_email_validator` (http://github.com/phatworx/rails_email_validator)
235
-
323
+ - Devise (<https://github.com/heartcombo/devise>)
324
+ - Rails 5.0 onwards (<http://github.com/rails/rails>)
325
+ - recommendations:
326
+ - `autocomplete-off` (<http://github.com/phatworx/autocomplete-off>)
327
+ - `easy_captcha` (<http://github.com/phatworx/easy_captcha>)
328
+ - `mongodb` (<https://www.mongodb.com/>)
329
+ - `rvm` (<https://rvm.io/>)
236
330
 
237
331
  ## Todo
238
332
 
239
- * see the github issues (feature requests)
333
+ - see the github issues (feature requests)
240
334
 
241
335
  ## History
242
- * 0.1 expire passwords
243
- * 0.2 strong password validation
244
- * 0.3 password archivable with validation
245
- * 0.4 captcha support for sign_up, sign_in, recover and unlock
246
- * 0.5 session_limitable module
247
- * 0.6 expirable module
248
- * 0.7 security questionable module for recover and unlock
249
- * 0.8 Support for Rails 4 (+ variety of patches)
250
- * 0.11 Support for Rails 5. Forked to allow project maintenance and features
336
+
337
+ - 0.1 expire passwords
338
+ - 0.2 strong password validation
339
+ - 0.3 password archivable with validation
340
+ - 0.4 captcha support for sign_up, sign_in, recover and unlock
341
+ - 0.5 session_limitable module
342
+ - 0.6 expirable module
343
+ - 0.7 security questionable module for recover and unlock
344
+ - 0.8 Support for Rails 4 (+ variety of patches)
345
+ - 0.11 Support for Rails 5. Forked to allow project maintenance and features
346
+
347
+ See also
348
+ [Github Releases](https://github.com/devise-security/devise-security/releases)
251
349
 
252
350
  ## Maintainers
253
351
 
254
- * Nate Bird (https://github.com/natebird)
352
+ - Nate Bird (<https://github.com/natebird>)
353
+ - Kevin Olbrich (<http://github.com/olbrich>)
354
+ - Dillon Welch (<http://github.com/oniofchaos>)
255
355
 
256
356
  ## Contributing to devise-security
257
357
 
258
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
259
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
260
- * Fork the project
261
- * Start a feature/bugfix branch
262
- * Commit and push until you are happy with your contribution
263
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
264
- * 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.
358
+ - Check out the latest master to make sure the feature hasn't been implemented
359
+ or the bug hasn't been fixed yet
360
+ - Check out the issue tracker to make sure someone already hasn't requested it
361
+ and/or contributed it
362
+ - Fork the project
363
+ - Start a feature/bugfix branch
364
+ - Commit and push until you are happy with your contribution
365
+ - Make sure to add tests for it. This is important so I don't break it in a
366
+ future version unintentionally.
367
+ - Please try not to mess with the Rakefile, version, or history. If you want to
368
+ have your own version, or is otherwise necessary, that is fine, but please
369
+ isolate to its own commit so I can cherry-pick around it.
370
+
371
+ ## Running tests
372
+
373
+ Standard tests can be invoked using `rake`. To run the tests against the
374
+ `mongoid` ORM, use `DEVISE_ORM=mongoid rake` while `mongodb` is running.
375
+
376
+ ## Maintenance Policy
377
+
378
+ We are committed to maintain support for `devise-security` for all normal or
379
+ security maintenance versions of the Ruby language
380
+ [as listed here](https://www.ruby-lang.org/en/downloads/branches/), and for the
381
+ Ruby on Rails framework
382
+ [as per their maintenance policy](https://rubyonrails.org/maintenance/).
383
+
384
+ In order to avoid introducing bugs caused by backwardly incompatible Ruby
385
+ language features, it is highly recommended that all development work be done
386
+ using the oldest supported ruby version. The contents of the `.ruby-version`
387
+ file should reflect this.
265
388
 
266
389
  ## Copyright
267
390
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::ParanoidVerificationCodeController < DeviseController
2
4
  skip_before_action :handle_paranoid_verification
3
5
  prepend_before_action :authenticate_scope!, only: [:show, :update]
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Devise::PasswordExpiredController < DeviseController
4
+ before_action :verify_requested_format!
2
5
  skip_before_action :handle_password_change
3
6
  before_action :skip_password_change, only: [:show, :update]
4
7
  prepend_before_action :authenticate_scope!, only: [:show, :update]
@@ -7,13 +10,21 @@ class Devise::PasswordExpiredController < DeviseController
7
10
  respond_with(resource)
8
11
  end
9
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
10
21
  def update
11
22
  resource.extend(Devise::Models::DatabaseAuthenticatablePatch)
12
23
  if resource.update_with_password(resource_params)
13
24
  warden.session(scope)['password_expired'] = false
14
25
  set_flash_message :notice, :updated
15
26
  bypass_sign_in resource, scope: scope
16
- redirect_to stored_location_for(scope) || :root
27
+ respond_with({}, location: stored_location_for(scope) || :root)
17
28
  else
18
29
  clean_up_passwords(resource)
19
30
  respond_with(resource, action: :show)
@@ -30,11 +41,7 @@ class Devise::PasswordExpiredController < DeviseController
30
41
  def resource_params
31
42
  permitted_params = [:current_password, :password, :password_confirmation]
32
43
 
33
- if params.respond_to?(:permit)
34
- params.require(resource_name).permit(*permitted_params)
35
- else
36
- params[scope].slice(*permitted_params)
37
- end
44
+ params.require(resource_name).permit(*permitted_params)
38
45
  end
39
46
 
40
47
  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
- <%= devise_error_messages! %>
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
- <%= devise_error_messages! %>
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,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.
@@ -1,16 +1,39 @@
1
1
  de:
2
2
  errors:
3
3
  messages:
4
- taken_in_past: 'wurde bereits in der Vergangenheit verwendet!'
5
- equal_to_current_password: 'darf nicht dem aktuellen Passwort entsprechen!'
6
- password_format: 'müssen große, kleine Buchstaben und Ziffern enthalten'
4
+ taken_in_past: 'wurde bereits in der Vergangenheit verwendet.'
5
+ equal_to_current_password: 'darf nicht dem aktuellen Passwort entsprechen.'
6
+ equal_to_email: 'darf nicht dem E-mail entsprechen.'
7
+ password_complexity:
8
+ digit:
9
+ one: muss mindestens eine Ziffer enthalten
10
+ other: muss mindestens %{count} Ziffern enthalten
11
+ lower:
12
+ one: muss mindestens einen Kleinbuchstaben enthalten
13
+ other: muss mindestens %{count} Kleinbuchstaben enthalten
14
+ symbol:
15
+ one: muss mindestens ein Sonderzeichen enthalten
16
+ other: muss mindestens %{count} Sonderzeichen enthalten
17
+ upper:
18
+ one: muss mindestens einen Großbuchstaben enthalten
19
+ other: muss mindestens %{count} Großbuchstaben enthalten
7
20
  devise:
8
- invalid_captcha: 'Die Captchaeingabe ist nicht gültig!'
21
+ invalid_captcha: 'Die Captcha-Eingabe ist nicht gültig.'
9
22
  paranoid_verify:
10
- code_required: 'Bitte geben Sie den Code unser Support-Team zur Verfügung gestellt'
23
+ code_required: 'Bitte geben Sie den Code ein, den unser Support-Team zur Verfügung gestellt hat.'
24
+ show:
25
+ submit_verification_code: Bestätigungscode eingeben
26
+ verification_code: Bestätigungscode
27
+ submit: Bestätigen
11
28
  password_expired:
12
29
  updated: 'Das neue Passwort wurde übernommen.'
13
- change_required: 'Ihr Passwort ist abgelaufen. Bitte vergeben sie ein neues Passwort!'
30
+ change_required: 'Ihr Passwort ist abgelaufen. Bitte vergeben Sie ein neues Passwort.'
31
+ show:
32
+ renew_your_password: Vergeben Sie ein neues Passwort
33
+ current_password: Aktuelles Passwort
34
+ new_password: Neues Passwort
35
+ new_password_confirmation: Passwort bestätigen
36
+ change_my_password: Passwort ändern
14
37
  failure:
15
38
  session_limited: 'Ihre Anmeldedaten wurden in einem anderen Browser genutzt. Bitte melden Sie sich erneut an, um in diesem Browser fortzufahren.'
16
- expired: 'Ihr Account ist aufgrund zu langer Inaktiviät abgelaufen. Bitte kontaktieren Sie den Administrator.'
39
+ expired: 'Ihr Account ist aufgrund zu langer Inaktivität abgelaufen. Bitte kontaktieren Sie den Administrator.'