devise-security 0.11.1 → 0.12.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 (69) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +41 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +22 -2
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +15 -3
  7. data/Appraisals +19 -0
  8. data/Gemfile +1 -0
  9. data/README.md +15 -10
  10. data/Rakefile +3 -1
  11. data/app/controllers/devise/paranoid_verification_code_controller.rb +1 -1
  12. data/app/controllers/devise/password_expired_controller.rb +1 -1
  13. data/app/views/devise/paranoid_verification_code/show.html.erb +2 -2
  14. data/app/views/devise/password_expired/show.html.erb +5 -5
  15. data/config/locales/de.yml +7 -7
  16. data/config/locales/en.yml +8 -8
  17. data/config/locales/es.yml +8 -8
  18. data/devise-security.gemspec +12 -6
  19. data/gemfiles/rails_4.1_stable.gemfile +8 -0
  20. data/gemfiles/rails_4.2_stable.gemfile +8 -0
  21. data/gemfiles/rails_5.0_stable.gemfile +8 -0
  22. data/gemfiles/rails_5.1_stable.gemfile +8 -0
  23. data/gemfiles/rails_5.2_rc1.gemfile +8 -0
  24. data/lib/devise-security/controllers/helpers.rb +2 -2
  25. data/lib/devise-security/hooks/session_limitable.rb +3 -3
  26. data/lib/devise-security/models/compatibility.rb +22 -0
  27. data/lib/devise-security/models/expirable.rb +13 -13
  28. data/lib/devise-security/models/old_password.rb +1 -1
  29. data/lib/devise-security/models/paranoid_verification.rb +5 -2
  30. data/lib/devise-security/models/password_archivable.rb +34 -38
  31. data/lib/devise-security/models/password_expirable.rb +1 -1
  32. data/lib/devise-security/models/secure_validatable.rb +16 -14
  33. data/lib/devise-security/models/security_questionable.rb +1 -2
  34. data/lib/devise-security/models/session_limitable.rb +3 -3
  35. data/lib/devise-security/orm/active_record.rb +1 -3
  36. data/lib/devise-security/patches/confirmations_controller_captcha.rb +2 -2
  37. data/lib/devise-security/patches/confirmations_controller_security_question.rb +2 -2
  38. data/lib/devise-security/patches/passwords_controller_captcha.rb +2 -2
  39. data/lib/devise-security/patches/passwords_controller_security_question.rb +2 -2
  40. data/lib/devise-security/patches/registrations_controller_captcha.rb +2 -2
  41. data/lib/devise-security/patches/sessions_controller_captcha.rb +3 -3
  42. data/lib/devise-security/patches/unlocks_controller_captcha.rb +2 -2
  43. data/lib/devise-security/patches/unlocks_controller_security_question.rb +2 -2
  44. data/lib/devise-security/rails.rb +2 -2
  45. data/lib/devise-security/routes.rb +2 -3
  46. data/lib/devise-security/schema.rb +11 -6
  47. data/lib/devise-security/version.rb +1 -1
  48. data/test/dummy/app/models/application_record.rb +3 -0
  49. data/test/dummy/app/models/captcha_user.rb +1 -1
  50. data/test/dummy/app/models/security_question_user.rb +2 -3
  51. data/test/dummy/app/models/user.rb +21 -4
  52. data/test/dummy/app/models/widget.rb +4 -0
  53. data/test/dummy/config/environments/test.rb +10 -2
  54. data/test/dummy/config/initializers/devise.rb +1 -0
  55. data/test/dummy/config/secrets.yml +1 -2
  56. data/test/dummy/db/migrate/20120508165529_create_tables.rb +9 -3
  57. data/test/dummy/db/migrate/20180318103603_add_expireable_columns.rb +6 -0
  58. data/test/dummy/db/migrate/20180318105329_add_confirmable_columns.rb +8 -0
  59. data/test/dummy/db/migrate/20180318105732_add_rememberable_columns.rb +5 -0
  60. data/test/dummy/db/migrate/20180318111336_add_recoverable_columns.rb +6 -0
  61. data/test/dummy/db/migrate/20180319114023_add_widget.rb +8 -0
  62. data/test/test_captcha_controller.rb +13 -13
  63. data/test/test_helper.rb +7 -0
  64. data/test/test_paranoid_verification.rb +2 -2
  65. data/test/test_password_archivable.rb +27 -13
  66. data/test/test_password_expirable.rb +2 -2
  67. data/test/test_password_expired_controller.rb +25 -10
  68. data/test/test_security_question_controller.rb +45 -21
  69. metadata +90 -13
@@ -22,7 +22,7 @@ class TestParanoidVerification < ActiveSupport::TestCase
22
22
  assert_equal(0, user.paranoid_verification_attempt)
23
23
  end
24
24
 
25
- test "generate code must reset attempt counter" do
25
+ test 'generate code must reset attempt counter' do
26
26
  user = User.new
27
27
  user.generate_paranoid_code
28
28
  # default generator generates 5 char string
@@ -30,7 +30,7 @@ class TestParanoidVerification < ActiveSupport::TestCase
30
30
  assert_equal(user.paranoid_verification_code.length, 5)
31
31
  end
32
32
 
33
- test "when code match upon verify code, should mark record that it's no loger needed to verify" do
33
+ test 'when code match upon verify code, should mark record that it\'s no loger needed to verify' do
34
34
  user = User.new(paranoid_verification_code: 'abcde')
35
35
 
36
36
  assert_equal(true, user.need_paranoid_verification?)
@@ -16,31 +16,45 @@ class TestPasswordArchivable < ActiveSupport::TestCase
16
16
  end
17
17
 
18
18
  test 'cannot use same password' do
19
- user = User.create password: 'password1', password_confirmation: 'password1'
19
+ user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
20
+ assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
21
+ end
22
+
23
+ test 'indirectly saving associated user does not cause deprecation warning' do
24
+ old_behavior = ActiveSupport::Deprecation.behavior
25
+ ActiveSupport::Deprecation.behavior = :raise
26
+ user = User.new email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
27
+ widget = Widget.new(user: user)
28
+ widget.save
29
+ ActiveSupport::Deprecation.behavior = old_behavior
30
+ end
20
31
 
21
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'password1') }
32
+ test 'does not save an OldPassword if user password was originally nil' do
33
+ user = User.new(email: 'bob@microsoft.com', password: nil, password_confirmation: nil)
34
+ set_password(user, 'Password1')
35
+ assert_equal 0, OldPassword.count
22
36
  end
23
37
 
24
38
  test 'cannot use archived passwords' do
25
39
  assert_equal 2, Devise.password_archiving_count
26
40
 
27
- user = User.create password: 'password1', password_confirmation: 'password1'
41
+ user = User.create! email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
28
42
  assert_equal 0, OldPassword.count
29
43
 
30
- set_password(user, 'password2')
44
+ set_password(user, 'Password2')
31
45
  assert_equal 1, OldPassword.count
32
46
 
33
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'password1') }
47
+ assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
34
48
 
35
- set_password(user, 'password3')
49
+ set_password(user, 'Password3')
36
50
  assert_equal 2, OldPassword.count
37
51
 
38
52
  # rotate first password out of archive
39
- assert set_password(user, 'password4')
53
+ assert set_password(user, 'Password4')
40
54
 
41
55
  # archive count was 2, so first password should work again
42
- assert set_password(user, 'password1')
43
- assert set_password(user, 'password2')
56
+ assert set_password(user, 'Password1')
57
+ assert set_password(user, 'Password2')
44
58
  end
45
59
 
46
60
  test 'the option should be dynamic during runtime' do
@@ -50,12 +64,12 @@ class TestPasswordArchivable < ActiveSupport::TestCase
50
64
  end
51
65
  end
52
66
 
53
- user = User.create password: 'password1', password_confirmation: 'password1'
67
+ user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
54
68
 
55
- assert set_password(user, 'password2')
69
+ assert set_password(user, 'Password2')
56
70
 
57
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'password2') }
71
+ assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password2') }
58
72
 
59
- assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'password1') }
73
+ assert_raises(ActiveRecord::RecordInvalid) { set_password(user, 'Password1') }
60
74
  end
61
75
  end
@@ -10,7 +10,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
10
10
  end
11
11
 
12
12
  test 'password expires' do
13
- user = User.create password: 'password1', password_confirmation: 'password1'
13
+ user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
14
14
  refute user.need_change_password?
15
15
 
16
16
  user.update(password_changed_at: Time.now.ago(3.month))
@@ -18,7 +18,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
18
18
  end
19
19
 
20
20
  test 'override expire after at runtime' do
21
- user = User.new password: 'password1', password_confirmation: 'password1'
21
+ user = User.new email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
22
22
  user.instance_eval do
23
23
  def expire_password_after
24
24
  4.month
@@ -5,9 +5,14 @@ class Devise::PasswordExpiredControllerTest < ActionController::TestCase
5
5
 
6
6
  setup do
7
7
  @request.env["devise.mapping"] = Devise.mappings[:user]
8
- @user = User.create(username: 'hello', email: 'hello@path.travel',
9
- password: '1234', password_changed_at: 4.months.ago)
10
-
8
+ @user = User.create!(
9
+ username: 'hello',
10
+ email: 'hello@path.travel',
11
+ password: 'Password4',
12
+ password_changed_at: 4.months.ago,
13
+ confirmed_at: 5.months.ago
14
+ )
15
+ assert @user.valid?
11
16
  sign_in(@user)
12
17
  end
13
18
 
@@ -16,14 +21,24 @@ class Devise::PasswordExpiredControllerTest < ActionController::TestCase
16
21
  assert_includes @response.body, 'Renew your password'
17
22
  end
18
23
 
19
- test 'shold update password' do
20
- put :update, params: {
21
- user: {
22
- current_password: '1234',
23
- password: '12345',
24
- password_confirmation: '12345'
24
+ test 'should update password' do
25
+ if Rails.version < "5"
26
+ put :update, {
27
+ user: {
28
+ current_password: 'Password4',
29
+ password: 'Password5',
30
+ password_confirmation: 'Password5'
31
+ }
32
+ }
33
+ else
34
+ put :update, params: {
35
+ user: {
36
+ current_password: 'Password4',
37
+ password: 'Password5',
38
+ password_confirmation: 'Password5'
39
+ }
25
40
  }
26
- }
41
+ end
27
42
  assert_redirected_to root_path
28
43
  end
29
44
  end
@@ -6,31 +6,47 @@ class TestWithSecurityQuestion < ActionController::TestCase
6
6
 
7
7
  setup do
8
8
  @user = User.create(username: 'hello', email: 'hello@path.travel',
9
- password: '1234', security_question_answer: "Right Answer")
9
+ password: '1234', security_question_answer: 'Right Answer')
10
10
  @user.lock_access!
11
11
 
12
- @request.env["devise.mapping"] = Devise.mappings[:security_question_user]
12
+ @request.env['devise.mapping'] = Devise.mappings[:security_question_user]
13
13
  end
14
14
 
15
15
  test 'When security question is enabled, it is inserted correctly' do
16
- post :create, params: {
17
- security_question_user: {
18
- email: @user.email
19
- }, security_question_answer: "wrong answer"
20
- }
16
+ if Rails.version < "5"
17
+ post :create, {
18
+ security_question_user: {
19
+ email: @user.email
20
+ }, security_question_answer: "wrong answer"
21
+ }
22
+ else
23
+ post :create, params: {
24
+ security_question_user: {
25
+ email: @user.email
26
+ }, security_question_answer: "wrong answer"
27
+ }
28
+ end
21
29
 
22
- assert_equal "The security question answer was invalid.", flash[:alert]
30
+ assert_equal 'The security question answer was invalid.', flash[:alert]
23
31
  assert_redirected_to new_security_question_user_unlock_path
24
32
  end
25
33
 
26
34
  test 'When security_question is valid, it runs as normal' do
27
- post :create, params: {
28
- security_question_user: {
29
- email: @user.email
30
- }, security_question_answer: @user.security_question_answer
31
- }
35
+ if Rails.version < "5"
36
+ post :create, {
37
+ security_question_user: {
38
+ email: @user.email
39
+ }, security_question_answer: @user.security_question_answer
40
+ }
41
+ else
42
+ post :create, params: {
43
+ security_question_user: {
44
+ email: @user.email
45
+ }, security_question_answer: @user.security_question_answer
46
+ }
47
+ end
32
48
 
33
- assert_equal "You will receive an email with instructions for how to unlock your account in a few minutes.", flash[:notice]
49
+ assert_equal 'You will receive an email with instructions for how to unlock your account in a few minutes.', flash[:notice]
34
50
  assert_redirected_to new_security_question_user_session_path
35
51
  end
36
52
  end
@@ -41,20 +57,28 @@ class TestWithoutSecurityQuestion < ActionController::TestCase
41
57
 
42
58
  setup do
43
59
  @user = User.create(username: 'hello', email: 'hello@path.travel',
44
- password: '1234', security_question_answer: "Right Answer")
60
+ password: '1234', security_question_answer: 'Right Answer')
45
61
  @user.lock_access!
46
62
 
47
- @request.env["devise.mapping"] = Devise.mappings[:user]
63
+ @request.env['devise.mapping'] = Devise.mappings[:user]
48
64
  end
49
65
 
50
66
  test 'When security question is not enabled it is not inserted' do
51
- post :create, params: {
52
- user: {
53
- email: @user.email
67
+ if Rails.version < "5"
68
+ post :create, {
69
+ user: {
70
+ email: @user.email
71
+ }
72
+ }
73
+ else
74
+ post :create, params: {
75
+ user: {
76
+ email: @user.email
77
+ }
54
78
  }
55
- }
79
+ end
56
80
 
57
- assert_equal "You will receive an email with instructions for how to unlock your account in a few minutes.", flash[:notice]
81
+ assert_equal 'You will receive an email with instructions for how to unlock your account in a few minutes.', flash[:notice]
58
82
  assert_redirected_to new_user_session_path
59
83
  end
60
84
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-security
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Scholl
@@ -11,15 +11,15 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-01-30 00:00:00.000000000 Z
14
+ date: 2018-04-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: railties
17
+ name: rails
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 3.2.6
22
+ version: 4.1.0
23
23
  - - "<"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '6.0'
@@ -29,7 +29,7 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 3.2.6
32
+ version: 4.1.0
33
33
  - - "<"
34
34
  - !ruby/object:Gem::Version
35
35
  version: '6.0'
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - "<"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '5.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: appraisal
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: bundler
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -119,16 +133,58 @@ dependencies:
119
133
  name: minitest
120
134
  requirement: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - "~>"
136
+ - - '='
123
137
  - !ruby/object:Gem::Version
124
- version: '5.0'
138
+ version: 5.10.3
125
139
  type: :development
126
140
  prerelease: false
127
141
  version_requirements: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - "~>"
143
+ - - '='
130
144
  - !ruby/object:Gem::Version
131
- version: '5.0'
145
+ version: 5.10.3
146
+ - !ruby/object:Gem::Dependency
147
+ name: pry-byebug
148
+ requirement: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ type: :development
154
+ prerelease: false
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ - !ruby/object:Gem::Dependency
161
+ name: pry-rescue
162
+ requirement: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ type: :development
168
+ prerelease: false
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: pry
176
+ requirement: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ type: :development
182
+ prerelease: false
183
+ version_requirements: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
132
188
  - !ruby/object:Gem::Dependency
133
189
  name: rails_email_validator
134
190
  requirement: !ruby/object:Gem::Requirement
@@ -177,18 +233,19 @@ dependencies:
177
233
  - - ">="
178
234
  - !ruby/object:Gem::Version
179
235
  version: 1.3.10
180
- description: An enterprise security extension for devise, trying to meet industrial
181
- standard security demands for web applications.
236
+ description: An enterprise security extension for devise.
182
237
  email: natebird@gmail.com
183
238
  executables: []
184
239
  extensions: []
185
240
  extra_rdoc_files: []
186
241
  files:
242
+ - ".circleci/config.yml"
187
243
  - ".document"
188
244
  - ".gitignore"
189
245
  - ".rubocop.yml"
190
246
  - ".ruby-version"
191
247
  - ".travis.yml"
248
+ - Appraisals
192
249
  - Gemfile
193
250
  - LICENSE.txt
194
251
  - README.md
@@ -202,12 +259,18 @@ files:
202
259
  - config/locales/es.yml
203
260
  - config/locales/it.yml
204
261
  - devise-security.gemspec
262
+ - gemfiles/rails_4.1_stable.gemfile
263
+ - gemfiles/rails_4.2_stable.gemfile
264
+ - gemfiles/rails_5.0_stable.gemfile
265
+ - gemfiles/rails_5.1_stable.gemfile
266
+ - gemfiles/rails_5.2_rc1.gemfile
205
267
  - lib/devise-security.rb
206
268
  - lib/devise-security/controllers/helpers.rb
207
269
  - lib/devise-security/hooks/expirable.rb
208
270
  - lib/devise-security/hooks/paranoid_verification.rb
209
271
  - lib/devise-security/hooks/password_expirable.rb
210
272
  - lib/devise-security/hooks/session_limitable.rb
273
+ - lib/devise-security/models/compatibility.rb
211
274
  - lib/devise-security/models/database_authenticatable_patch.rb
212
275
  - lib/devise-security/models/expirable.rb
213
276
  - lib/devise-security/models/old_password.rb
@@ -241,10 +304,12 @@ files:
241
304
  - test/dummy/app/controllers/foos_controller.rb
242
305
  - test/dummy/app/controllers/security_question/unlocks_controller.rb
243
306
  - test/dummy/app/models/.gitkeep
307
+ - test/dummy/app/models/application_record.rb
244
308
  - test/dummy/app/models/captcha_user.rb
245
309
  - test/dummy/app/models/secure_user.rb
246
310
  - test/dummy/app/models/security_question_user.rb
247
311
  - test/dummy/app/models/user.rb
312
+ - test/dummy/app/models/widget.rb
248
313
  - test/dummy/app/views/foos/index.html.erb
249
314
  - test/dummy/config.ru
250
315
  - test/dummy/config/application.rb
@@ -260,6 +325,11 @@ files:
260
325
  - test/dummy/db/migrate/20150402165590_add_verification_columns.rb
261
326
  - test/dummy/db/migrate/20150407162345_add_verification_attempt_column.rb
262
327
  - test/dummy/db/migrate/20160320162345_add_security_questions_fields.rb
328
+ - test/dummy/db/migrate/20180318103603_add_expireable_columns.rb
329
+ - test/dummy/db/migrate/20180318105329_add_confirmable_columns.rb
330
+ - test/dummy/db/migrate/20180318105732_add_rememberable_columns.rb
331
+ - test/dummy/db/migrate/20180318111336_add_recoverable_columns.rb
332
+ - test/dummy/db/migrate/20180319114023_add_widget.rb
263
333
  - test/test_captcha_controller.rb
264
334
  - test/test_helper.rb
265
335
  - test/test_install_generator.rb
@@ -281,7 +351,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
281
351
  requirements:
282
352
  - - ">="
283
353
  - !ruby/object:Gem::Version
284
- version: 2.2.2
354
+ version: 2.2.9
285
355
  required_rubygems_version: !ruby/object:Gem::Requirement
286
356
  requirements:
287
357
  - - ">="
@@ -289,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
359
  version: '0'
290
360
  requirements: []
291
361
  rubyforge_project:
292
- rubygems_version: 2.6.13
362
+ rubygems_version: 2.7.6
293
363
  signing_key:
294
364
  specification_version: 4
295
365
  summary: Security extension for devise
@@ -300,10 +370,12 @@ test_files:
300
370
  - test/dummy/app/controllers/foos_controller.rb
301
371
  - test/dummy/app/controllers/security_question/unlocks_controller.rb
302
372
  - test/dummy/app/models/.gitkeep
373
+ - test/dummy/app/models/application_record.rb
303
374
  - test/dummy/app/models/captcha_user.rb
304
375
  - test/dummy/app/models/secure_user.rb
305
376
  - test/dummy/app/models/security_question_user.rb
306
377
  - test/dummy/app/models/user.rb
378
+ - test/dummy/app/models/widget.rb
307
379
  - test/dummy/app/views/foos/index.html.erb
308
380
  - test/dummy/config.ru
309
381
  - test/dummy/config/application.rb
@@ -319,6 +391,11 @@ test_files:
319
391
  - test/dummy/db/migrate/20150402165590_add_verification_columns.rb
320
392
  - test/dummy/db/migrate/20150407162345_add_verification_attempt_column.rb
321
393
  - test/dummy/db/migrate/20160320162345_add_security_questions_fields.rb
394
+ - test/dummy/db/migrate/20180318103603_add_expireable_columns.rb
395
+ - test/dummy/db/migrate/20180318105329_add_confirmable_columns.rb
396
+ - test/dummy/db/migrate/20180318105732_add_rememberable_columns.rb
397
+ - test/dummy/db/migrate/20180318111336_add_recoverable_columns.rb
398
+ - test/dummy/db/migrate/20180319114023_add_widget.rb
322
399
  - test/test_captcha_controller.rb
323
400
  - test/test_helper.rb
324
401
  - test/test_install_generator.rb