devise-two-factor 4.1.1 → 6.4.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +6 -0
  3. data/.github/workflows/ci.yml +3 -18
  4. data/.github/workflows/push.yml +28 -0
  5. data/.markdownlint.json +6 -0
  6. data/Appraisals +9 -34
  7. data/CHANGELOG.md +59 -0
  8. data/README.md +110 -67
  9. data/Rakefile +2 -0
  10. data/SECURITY.md +5 -0
  11. data/UPGRADING.md +218 -2
  12. data/devise-two-factor.gemspec +8 -15
  13. data/gemfiles/{rails_4.2.gemfile → rails_7.2.gemfile} +2 -2
  14. data/gemfiles/{rails_5.0.gemfile → rails_8.0.gemfile} +2 -2
  15. data/gemfiles/{rails_4.1.gemfile → rails_8.1.gemfile} +2 -2
  16. data/lib/devise-two-factor.rb +12 -5
  17. data/lib/devise_two_factor/models/two_factor_authenticatable.rb +41 -29
  18. data/lib/devise_two_factor/models/two_factor_backupable.rb +6 -2
  19. data/lib/devise_two_factor/spec_helpers/two_factor_authenticatable_shared_examples.rb +6 -18
  20. data/lib/devise_two_factor/spec_helpers/two_factor_backupable_shared_examples.rb +53 -24
  21. data/lib/devise_two_factor/strategies/two_factor_authenticatable.rb +8 -2
  22. data/lib/devise_two_factor/strategies/two_factor_backupable.rb +6 -4
  23. data/lib/devise_two_factor/version.rb +1 -1
  24. data/lib/generators/devise_two_factor/devise_two_factor_generator.rb +2 -7
  25. data/spec/devise/models/two_factor_authenticatable_spec.rb +11 -69
  26. data/spec/devise/models/two_factor_backupable_spec.rb +11 -2
  27. data/spec/spec_helper.rb +0 -1
  28. metadata +42 -134
  29. checksums.yaml.gz.sig +0 -0
  30. data/certs/tinfoil-cacert.pem +0 -41
  31. data/certs/tinfoilsecurity-gems-cert.pem +0 -35
  32. data/gemfiles/rails_5.1.gemfile +0 -8
  33. data/gemfiles/rails_5.2.gemfile +0 -8
  34. data/gemfiles/rails_6.0.gemfile +0 -8
  35. data/gemfiles/rails_6.1.gemfile +0 -8
  36. data/gemfiles/rails_7.0.gemfile +0 -8
  37. data.tar.gz.sig +0 -0
  38. metadata.gz.sig +0 -0
@@ -4,12 +4,18 @@ module Devise
4
4
 
5
5
  def authenticate!
6
6
  resource = mapping.to.find_for_database_authentication(authentication_hash)
7
+
8
+ hashed = false
7
9
  # We authenticate in two cases:
8
10
  # 1. The password and the OTP are correct
9
11
  # 2. The password is correct, and OTP is not required for login
10
12
  # We check the OTP, then defer to DatabaseAuthenticatable
11
- if validate(resource) { validate_otp(resource) }
13
+ if validate(resource) { hashed = true; validate_otp(resource) }
12
14
  super
15
+ else
16
+ # Paranoid mode: do the expensive hash even when resource is nil,
17
+ # to avoid timing-based user enumeration.
18
+ mapping.to.new.password = password if !hashed && Devise.paranoid
13
19
  end
14
20
 
15
21
  fail(Devise.paranoid ? :invalid : :not_found_in_database) unless resource
@@ -21,7 +27,7 @@ module Devise
21
27
 
22
28
  def validate_otp(resource)
23
29
  return true unless resource.otp_required_for_login
24
- return if params[scope]['otp_attempt'].nil?
30
+ return if params[scope].nil? || params[scope]['otp_attempt'].nil?
25
31
  resource.validate_and_consume_otp!(params[scope]['otp_attempt'])
26
32
  end
27
33
  end
@@ -5,10 +5,7 @@ module Devise
5
5
  def authenticate!
6
6
  resource = mapping.to.find_for_database_authentication(authentication_hash)
7
7
 
8
- if validate(resource) { resource.invalidate_otp_backup_code!(params[scope]['otp_attempt']) }
9
- # Devise fails to authenticate invalidated resources, but if we've
10
- # gotten here, the object changed (Since we deleted a recovery code)
11
- resource.save!
8
+ if validate(resource) { validate_backup_code(resource) }
12
9
  super
13
10
  end
14
11
 
@@ -18,6 +15,11 @@ module Devise
18
15
  # but database authenticatable automatically halts on a bad password
19
16
  @halted = false if @result == :failure
20
17
  end
18
+
19
+ def validate_backup_code(resource)
20
+ return if params[scope].nil? || params[scope]['otp_attempt'].nil?
21
+ resource.invalidate_otp_backup_code!(params[scope]['otp_attempt'])
22
+ end
21
23
  end
22
24
  end
23
25
  end
@@ -1,3 +1,3 @@
1
1
  module DeviseTwoFactor
2
- VERSION = '4.1.1'.freeze
2
+ VERSION = '6.4.0'.freeze
3
3
  end
@@ -3,8 +3,6 @@ require 'rails/generators'
3
3
  module DeviseTwoFactor
4
4
  module Generators
5
5
  class DeviseTwoFactorGenerator < Rails::Generators::NamedBase
6
- argument :encryption_key_env, :type => :string, :required => true
7
-
8
6
  desc 'Creates a migration to add the required attributes to NAME, and ' \
9
7
  'adds the necessary Devise directives to the model'
10
8
 
@@ -19,9 +17,7 @@ module DeviseTwoFactor
19
17
  def create_devise_two_factor_migration
20
18
  migration_arguments = [
21
19
  "add_devise_two_factor_to_#{plural_name}",
22
- "encrypted_otp_secret:string",
23
- "encrypted_otp_secret_iv:string",
24
- "encrypted_otp_secret_salt:string",
20
+ "otp_secret:string",
25
21
  "consumed_timestep:integer",
26
22
  "otp_required_for_login:boolean"
27
23
  ]
@@ -51,8 +47,7 @@ module DeviseTwoFactor
51
47
  indent_depth = class_path.size
52
48
 
53
49
  content = [
54
- "devise :two_factor_authenticatable,",
55
- " :otp_secret_encryption_key => ENV['#{encryption_key_env}']\n"
50
+ "devise :two_factor_authenticatable"
56
51
  ]
57
52
 
58
53
  content << "attr_accessible :otp_attempt\n" if needs_attr_accessible?
@@ -6,91 +6,33 @@ class TwoFactorAuthenticatableDouble
6
6
  include ::ActiveModel::Validations::Callbacks
7
7
  extend ::Devise::Models
8
8
 
9
- define_model_callbacks :update
10
-
11
- devise :two_factor_authenticatable, :otp_secret_encryption_key => 'test-key'*4
12
-
13
- attr_accessor :consumed_timestep
14
-
15
- def save(validate)
16
- # noop for testing
17
- true
9
+ # stub out the ::ActiveRecord::Encryption::EncryptableRecord API
10
+ attr_accessor :otp_secret
11
+ def self.encrypts(*attrs)
12
+ nil
18
13
  end
19
- end
20
-
21
- class TwoFactorAuthenticatableWithCustomizeAttrEncryptedDouble
22
- extend ::ActiveModel::Callbacks
23
- include ::ActiveModel::Validations::Callbacks
24
-
25
- # like https://github.com/tinfoil/devise-two-factor/blob/cf73e52043fbe45b74d68d02bc859522ad22fe73/UPGRADING.md#guide-to-upgrading-from-2x-to-3x
26
- extend ::AttrEncrypted
27
- attr_encrypted :otp_secret,
28
- :key => 'test-key'*8,
29
- :mode => :per_attribute_iv_and_salt,
30
- :algorithm => 'aes-256-cbc'
31
-
32
- extend ::Devise::Models
33
14
 
34
15
  define_model_callbacks :update
35
16
 
36
- devise :two_factor_authenticatable, :otp_secret_encryption_key => 'test-key'*4
17
+ devise :two_factor_authenticatable
37
18
 
38
19
  attr_accessor :consumed_timestep
39
20
 
40
- def save(validate)
21
+ def save!(_)
41
22
  # noop for testing
42
23
  true
43
24
  end
44
25
  end
45
26
 
46
27
  describe ::Devise::Models::TwoFactorAuthenticatable do
47
- context 'When included in a class' do
48
- subject { TwoFactorAuthenticatableDouble.new }
49
-
50
- it_behaves_like 'two_factor_authenticatable'
28
+ it 'should be inserted prior to other devise modules' do
29
+ expect(Devise::ALL.first).to eq(:two_factor_authenticatable)
51
30
  end
52
- end
53
31
 
54
- describe ::Devise::Models::TwoFactorAuthenticatable do
55
32
  context 'When included in a class' do
56
- subject { TwoFactorAuthenticatableWithCustomizeAttrEncryptedDouble.new }
33
+ subject { TwoFactorAuthenticatableDouble.new }
57
34
 
58
35
  it_behaves_like 'two_factor_authenticatable'
59
-
60
- before :each do
61
- subject.otp_secret = subject.class.generate_otp_secret
62
- subject.consumed_timestep = nil
63
- end
64
-
65
- describe 'otp_secret options' do
66
- it 'should be of the key' do
67
- if attr_encrypted_is_rails_seven_compatible?
68
- expect(subject.attr_encrypted_encrypted_attributes[:otp_secret][:key]).to eq('test-key'*8)
69
- else
70
- expect(subject.encrypted_attributes[:otp_secret][:key]).to eq('test-key'*8)
71
- end
72
- end
73
-
74
- it 'should be of the mode' do
75
- if attr_encrypted_is_rails_seven_compatible?
76
- expect(subject.attr_encrypted_encrypted_attributes[:otp_secret][:mode]).to eq(:per_attribute_iv_and_salt)
77
- else
78
- expect(subject.encrypted_attributes[:otp_secret][:mode]).to eq(:per_attribute_iv_and_salt)
79
- end
80
- end
81
-
82
- it 'should be of the mode' do
83
- if attr_encrypted_is_rails_seven_compatible?
84
- expect(subject.attr_encrypted_encrypted_attributes[:otp_secret][:algorithm]).to eq('aes-256-cbc')
85
- else
86
- expect(subject.encrypted_attributes[:otp_secret][:algorithm]).to eq('aes-256-cbc')
87
- end
88
- end
89
-
90
- def attr_encrypted_is_rails_seven_compatible?
91
- Gem::Version.new(AttrEncrypted::Version.string) >= Gem::Version.new('4.0.0')
92
- end
93
- end
94
36
  end
95
37
  end
96
38
 
@@ -101,11 +43,11 @@ describe ::Devise::Models::TwoFactorAuthenticatable do
101
43
  subject.otp_attempt = 'foo'
102
44
  subject.password_confirmation = 'foo'
103
45
  end
104
- it 'otp_attempt should be nill' do
46
+ it 'otp_attempt should be nill' do
105
47
  subject.clean_up_passwords
106
48
  expect(subject.otp_attempt).to be_nil
107
49
  end
108
- it 'password_confirmation should be nill' do
50
+ it 'password_confirmation should be nill' do
109
51
  subject.clean_up_passwords
110
52
  expect(subject.password_confirmation).to be_nil
111
53
  end
@@ -6,12 +6,21 @@ class TwoFactorBackupableDouble
6
6
  include ::ActiveModel::Validations::Callbacks
7
7
  extend ::Devise::Models
8
8
 
9
+ # stub out the ::ActiveRecord::Encryption::EncryptableRecord API
10
+ attr_accessor :otp_secret
11
+ def self.encrypts(*attrs)
12
+ nil
13
+ end
14
+
9
15
  define_model_callbacks :update
10
16
 
11
- devise :two_factor_authenticatable, :two_factor_backupable,
12
- :otp_secret_encryption_key => 'test-key'*4
17
+ devise :two_factor_authenticatable, :two_factor_backupable
13
18
 
14
19
  attr_accessor :otp_backup_codes
20
+
21
+ def save!(_)
22
+ true
23
+ end
15
24
  end
16
25
 
17
26
  describe ::Devise::Models::TwoFactorBackupable do
data/spec/spec_helper.rb CHANGED
@@ -18,7 +18,6 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
18
  $LOAD_PATH.unshift(File.dirname(__FILE__))
19
19
 
20
20
  require 'rspec'
21
- require 'faker'
22
21
  require 'devise-two-factor'
23
22
  require 'devise_two_factor/spec_helpers'
24
23
 
metadata CHANGED
@@ -1,161 +1,74 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-two-factor
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 6.4.0
5
5
  platform: ruby
6
6
  authors:
7
- - Shane Wilton
8
- autorequire:
7
+ - Quinn Wilton
9
8
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIHSjCCBTKgAwIBAgIJAK2u0LojMCNgMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
14
- VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEfMB0GA1UE
15
- ChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEfMB0GA1UEAxMWVGluZm9pbCBTZWN1
16
- cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYbc3VwcG9ydEB0aW5mb2lsc2VjdXJp
17
- dHkuY29tMB4XDTIxMDkwOTE4MjIwMFoXDTI1MDkwOTE4MjIwMFowgZwxCzAJBgNV
18
- BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
19
- ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR8wHQYDVQQDExZUaW5mb2lsIFNlY3Vy
20
- aXR5LCBJbmMuMSowKAYJKoZIhvcNAQkBFhtzdXBwb3J0QHRpbmZvaWxzZWN1cml0
21
- eS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqbHvsSj0H0FB1
22
- 0gLYoDK1BKugkSB2DZeZZHP6B1UdWRahJXJP9oT1lhfQxx8iX4cgEi7JU3NqA6NR
23
- cIRFQ50eH/qlmgs7909gaf8pDaeC0vR3wd0GeRg6qr1eDEnkzIyr/D1AMiX6H1eP
24
- Y7J3SfrdaL3gft2iPRKGkgqsXR7oBNLA3n/ShiNgPXqRDl1CCj6aMY0cn5ROFScz
25
- vT2FUB4DEwPD2l18m1p99OnXqsOLL2J65qA2+cI8FtgFmlwIi5oSf+URvIdNx+cH
26
- lInlAtVHCvAKYLY0dlQ7czMQBcRpYjp2rwPt9f2ksq9b/voMTBABYHFV+IVn8svv
27
- GZ5e1+icjtr/R7dCGmCdEdFLXVxafmZhukymG9USv9DKuv1qh7r4q8KaPIE8n7nQ
28
- m97jENFfsgnwv+nUmIJ3tzuW5ZxO7A0tIIYdwzt0UjrO3ya4R5bTFXr4bnzZ/g/s
29
- CLknWqg1BCRlPd6LnpVGPT0gNDV1pEO25wE3A3Yy0Ujxudcgay/CgUhnlU11qOAc
30
- xmar2fhNZsviUhndd/220Ad5QMV2XzcAiopJIeu0juIVGRQM7x2h19Hsp0m6sOEF
31
- jfhvbdUa4nvmIFeYFY+hr/YkTmG9ZjyBa8YaZXhwjhSmKCQ374J7mn5e0Cryuvi5
32
- tYhwJn8rdwYZF/h2qqfEu8vaLoD09QIDAQABo4IBizCCAYcwHQYDVR0OBBYEFMmT
33
- /x412UH+5OHqgleeTjLOv6iHMIHRBgNVHSMEgckwgcaAFMmT/x412UH+5OHqglee
34
- TjLOv6iHoYGipIGfMIGcMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNV
35
- BAcTCVBhbG8gQWx0bzEfMB0GA1UEChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEf
36
- MB0GA1UEAxMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYb
37
- c3VwcG9ydEB0aW5mb2lsc2VjdXJpdHkuY29tggkAra7QuiMwI2AwDwYDVR0TAQH/
38
- BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQYwCQYDVR0SBAIwADArBglghkgBhvhC
39
- AQ0EHhYcVGlueUNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAmBgNVHREEHzAdgRtz
40
- dXBwb3J0QHRpbmZvaWxzZWN1cml0eS5jb20wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
41
- SIb3DQEBBQUAA4ICAQBZy4JJSmwLuO0nZbdr4tJeVS2P8bcGi6PzAcdzVfwzjp6n
42
- 5qf8m4O8my4lnJieom0GrWSHQoPY1Yur4hEoZbugKO9DWZL3dTiGcrgw0TbQ6Gtq
43
- TTPatW3LA21qFJwvohSvLqPdmZuM+H9g49sdl2kNTDVI6iUyMYuNpL14aPKPGBFo
44
- o7UjciT1h7JtJl9b/fXrbPeRHBwpZXWeipiPGv/OZW5KnOsNlUkTquS7Zj4ETkIC
45
- 6mVtmsLvq+YwFthFyMU37pXwYxcmqRmH6lX+XC6AVW5oO4GBmG+Zr/Z+h5Cih5ca
46
- /mX88RkO+dGTjw1IdxKmxOqKL62OBATKrTDJ/scsmRptynA4TunYW+7ikOpDbPfL
47
- l18aleLISlcgWJg/Czf2nmBqAClPLnhV8qxWsvt58MQQ/Jpoggvpl8EG1PylWiBS
48
- Kc/4Ad/FKQFpTzXUgDg2kV07npVjYbBzA5p4ZSWSlflFu93jb9gg2+qtnRSImVCZ
49
- nQjZdsv8hebElPAIbtJjSnoH1Kz2ucYLakdF1UMKnpp1PVREtuKPz/foU9KUHs0z
50
- dWRALx8cWG4uKK9AIEUlVdGKfX0Wj0qFK0KGxl3f3jObud5Agwue2EPKWwUzEGUh
51
- Iqp60gNw3vBdKHw4dh1bfcbXWnRDL+OQPuOFZeMWgu1QmeHeuggYtYtRg7V5Kg==
52
- -----END CERTIFICATE-----
53
- - |
54
- -----BEGIN CERTIFICATE-----
55
- MIIGADCCA+igAwIBAgIIHIF9ta6cW3YwDQYJKoZIhvcNAQENBQAwgZwxCzAJBgNV
56
- BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
57
- ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR8wHQYDVQQDExZUaW5mb2lsIFNlY3Vy
58
- aXR5LCBJbmMuMSowKAYJKoZIhvcNAQkBFhtzdXBwb3J0QHRpbmZvaWxzZWN1cml0
59
- eS5jb20wHhcNMjIwMzIyMjI1MzAwWhcNMjUwOTA5MTgyMjAwWjCBiDELMAkGA1UE
60
- BhMCVVMxCzAJBgNVBAgTAkNBMR8wHQYDVQQKExZUaW5mb2lsIFNlY3VyaXR5LCBJ
61
- bmMuMR0wGwYDVQQDExR0aW5mb2lsc2VjdXJpdHktZ2VtczEsMCoGCSqGSIb3DQEJ
62
- ARYdZW5naW5lZXJzQHRpbmZvaWxzZWN1cml0eS5jb20wggIiMA0GCSqGSIb3DQEB
63
- AQUAA4ICDwAwggIKAoICAQDNJYNH8D+8lACLt3KzjEIPs3XVBCPaMm2eD/Xk9OOT
64
- uDV/NqgMK0icD9MRxMUtS3SCrC9QcPocXT76f2LQ3yVJuK+rBUasymEES47PIx2c
65
- zC4n4Hga0xPPuBpioO26oaRFsobyzh9RPOIbnYfpjyqtdrbm+YyM3sPR4XzFirv9
66
- xomT4E9T4RCLgOQHTcLKL9K9m+EN7PeVdVUXV0Pa7cVs2vJUKedsd7vnr6Lzbn8T
67
- oPk/7J/4W931PbaeI5yg9ZuaRa9K2IaY1TkPI67NW4qKitBVepRlXw6Sb7TYcUnc
68
- WEQ/eC5CpnOmqUrG5tfGD8cc5aGZOkitW/VXZgVj81xgCv1hk4HjErrqq4FBNAaC
69
- SNyBfwR0TUYqg1lN1nbNjOKwfb6YRn06R2ovcFJG0tmGhsQULCr6fW8u2TfSM+U9
70
- WFSIJx2griureY7EZPwg/MgsUiWUWMFemz3GVYXWJR3dN2pW9Uqr3rkjKZbA0bst
71
- GWahJO9HuFdDakQxoaTPYPtTQDC+kskkO6lKG1KLIoZ1iLZzB1Ks1vEeyE7lp1im
72
- WgpUq+q23PFkt1gIBi/4tGvzsLZye25QU2Y+XLzldCNm+DyRFXZ+Q+bK33IveUeU
73
- WEOv4T1qTXHAOypyzmgodVRG/PrlsSMOBfE515kG1mDMGjRcCpEtlskgxUbf7qM7
74
- hQIDAQABo1gwVjAJBgNVHRMEAjAAMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHBzOi8v
75
- d3d3LnRpbmZvaWxzZWN1cml0eS5jb20vc2VjdXJpdHkvcmV2b2NhdGlvbl9saXN0
76
- MA0GCSqGSIb3DQEBDQUAA4ICAQAiYF/m2ny/mxFvBVxHfdYuzybhCvsEUd+TSnoe
77
- mqOWntY3sxCOaY0aGOMB4vyg9G+oP/kT4m63sD4uQxeuU7WOjaG2smCSS5q+PSWS
78
- v63gILqPamjSyP/Om864EA6YlvVQ7nPXhVDEaiBt3iliefJGmb0wWSbbDCmq3aMb
79
- WTLuax/IeY6MjJi20LutIcuz+VX8OxlA1hSpgAToMz3xrhA8fPt5UkKhkDkPFYBF
80
- 5htKVipyijChWsXyt33YM2qGaavTEXzxza1I99PGNRKxUMvbSMas4YaLqkBpQSc+
81
- mcrLWYPiXWsePGu+j08AypE2Ubp4AOSZJN9rBBGotC3gofipo+K/sBiOM9xXI76Q
82
- 0HYOxXPa7D7UQQG1R9i0rcxmf9qepIVYCldmqVkKKDizcDo5UI9lRiLFjDyQhn6l
83
- YFY9bPQ4lKTK5Jr3M6+dV7fHxLhqXyMGs1905IUb7qvB7Bq/f0qJfC0JZuY/qdn2
84
- lL0SeFKOVsjErtobh3u8p8j2USkc8uJgIANHpXEMEExdp899CV/eVjh3TpAR7E6T
85
- mg7Q9Hi6Hh8z+Le9iR4I49vPEWDQEvj35IT6VfwU79UfIOlX+DkW8fFkPbaut3Se
86
- vqIDv6JBG9I16h/HhchntKfM58MI1bNZFBSdZqYOJiL8JIjP8HNIk76Y366ppG29
87
- EhBYYg==
88
- -----END CERTIFICATE-----
89
- date: 2023-10-12 00:00:00.000000000 Z
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
90
11
  dependencies:
91
12
  - !ruby/object:Gem::Dependency
92
13
  name: railties
93
14
  requirement: !ruby/object:Gem::Requirement
94
15
  requirements:
95
- - - "~>"
96
- - !ruby/object:Gem::Version
97
- version: '7.0'
98
- type: :runtime
99
- prerelease: false
100
- version_requirements: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - "~>"
16
+ - - ">="
103
17
  - !ruby/object:Gem::Version
104
- version: '7.0'
105
- - !ruby/object:Gem::Dependency
106
- name: activesupport
107
- requirement: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - "~>"
18
+ version: '7.2'
19
+ - - "<"
110
20
  - !ruby/object:Gem::Version
111
- version: '7.0'
21
+ version: '8.2'
112
22
  type: :runtime
113
23
  prerelease: false
114
24
  version_requirements: !ruby/object:Gem::Requirement
115
25
  requirements:
116
- - - "~>"
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '7.2'
29
+ - - "<"
117
30
  - !ruby/object:Gem::Version
118
- version: '7.0'
31
+ version: '8.2'
119
32
  - !ruby/object:Gem::Dependency
120
- name: attr_encrypted
33
+ name: activesupport
121
34
  requirement: !ruby/object:Gem::Requirement
122
35
  requirements:
123
36
  - - ">="
124
37
  - !ruby/object:Gem::Version
125
- version: '1.3'
126
- - - "!="
127
- - !ruby/object:Gem::Version
128
- version: '2'
38
+ version: '7.2'
129
39
  - - "<"
130
40
  - !ruby/object:Gem::Version
131
- version: '5'
41
+ version: '8.2'
132
42
  type: :runtime
133
43
  prerelease: false
134
44
  version_requirements: !ruby/object:Gem::Requirement
135
45
  requirements:
136
46
  - - ">="
137
47
  - !ruby/object:Gem::Version
138
- version: '1.3'
139
- - - "!="
140
- - !ruby/object:Gem::Version
141
- version: '2'
48
+ version: '7.2'
142
49
  - - "<"
143
50
  - !ruby/object:Gem::Version
144
- version: '5'
51
+ version: '8.2'
145
52
  - !ruby/object:Gem::Dependency
146
53
  name: devise
147
54
  requirement: !ruby/object:Gem::Requirement
148
55
  requirements:
149
- - - "~>"
56
+ - - ">="
150
57
  - !ruby/object:Gem::Version
151
58
  version: '4.0'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '6.0'
152
62
  type: :runtime
153
63
  prerelease: false
154
64
  version_requirements: !ruby/object:Gem::Requirement
155
65
  requirements:
156
- - - "~>"
66
+ - - ">="
157
67
  - !ruby/object:Gem::Version
158
68
  version: '4.0'
69
+ - - "<"
70
+ - !ruby/object:Gem::Version
71
+ version: '6.0'
159
72
  - !ruby/object:Gem::Dependency
160
73
  name: rotp
161
74
  requirement: !ruby/object:Gem::Requirement
@@ -241,27 +154,30 @@ dependencies:
241
154
  - !ruby/object:Gem::Version
242
155
  version: '0'
243
156
  - !ruby/object:Gem::Dependency
244
- name: faker
157
+ name: rake
245
158
  requirement: !ruby/object:Gem::Requirement
246
159
  requirements:
247
- - - ">="
160
+ - - "~>"
248
161
  - !ruby/object:Gem::Version
249
- version: '0'
162
+ version: '13'
250
163
  type: :development
251
164
  prerelease: false
252
165
  version_requirements: !ruby/object:Gem::Requirement
253
166
  requirements:
254
- - - ">="
167
+ - - "~>"
255
168
  - !ruby/object:Gem::Version
256
- version: '0'
257
- description: Barebones two-factor authentication with Devise
258
- email: engineers@tinfoilsecurity.com
169
+ version: '13'
170
+ description: Devise-Two-Factor is a minimalist extension to Devise which offers support
171
+ for two-factor authentication through the TOTP scheme.
259
172
  executables: []
260
173
  extensions: []
261
174
  extra_rdoc_files: []
262
175
  files:
176
+ - ".github/dependabot.yml"
263
177
  - ".github/workflows/ci.yml"
178
+ - ".github/workflows/push.yml"
264
179
  - ".gitignore"
180
+ - ".markdownlint.json"
265
181
  - ".rspec"
266
182
  - Appraisals
267
183
  - CHANGELOG.md
@@ -270,18 +186,12 @@ files:
270
186
  - LICENSE
271
187
  - README.md
272
188
  - Rakefile
189
+ - SECURITY.md
273
190
  - UPGRADING.md
274
- - certs/tinfoil-cacert.pem
275
- - certs/tinfoilsecurity-gems-cert.pem
276
191
  - devise-two-factor.gemspec
277
- - gemfiles/rails_4.1.gemfile
278
- - gemfiles/rails_4.2.gemfile
279
- - gemfiles/rails_5.0.gemfile
280
- - gemfiles/rails_5.1.gemfile
281
- - gemfiles/rails_5.2.gemfile
282
- - gemfiles/rails_6.0.gemfile
283
- - gemfiles/rails_6.1.gemfile
284
- - gemfiles/rails_7.0.gemfile
192
+ - gemfiles/rails_7.2.gemfile
193
+ - gemfiles/rails_8.0.gemfile
194
+ - gemfiles/rails_8.1.gemfile
285
195
  - lib/devise-two-factor.rb
286
196
  - lib/devise_two_factor/models.rb
287
197
  - lib/devise_two_factor/models/two_factor_authenticatable.rb
@@ -297,11 +207,10 @@ files:
297
207
  - spec/devise/models/two_factor_authenticatable_spec.rb
298
208
  - spec/devise/models/two_factor_backupable_spec.rb
299
209
  - spec/spec_helper.rb
300
- homepage: https://github.com/tinfoil/devise-two-factor
210
+ homepage: https://github.com/devise-two-factor/devise-two-factor
301
211
  licenses:
302
212
  - MIT
303
213
  metadata: {}
304
- post_install_message:
305
214
  rdoc_options: []
306
215
  require_paths:
307
216
  - lib
@@ -316,8 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
225
  - !ruby/object:Gem::Version
317
226
  version: '0'
318
227
  requirements: []
319
- rubygems_version: 3.0.3.1
320
- signing_key:
228
+ rubygems_version: 4.0.3
321
229
  specification_version: 4
322
230
  summary: Barebones two-factor authentication with Devise
323
231
  test_files:
checksums.yaml.gz.sig DELETED
Binary file
@@ -1,41 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIHSjCCBTKgAwIBAgIJAK2u0LojMCNgMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
3
- VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEfMB0GA1UE
4
- ChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEfMB0GA1UEAxMWVGluZm9pbCBTZWN1
5
- cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYbc3VwcG9ydEB0aW5mb2lsc2VjdXJp
6
- dHkuY29tMB4XDTIxMDkwOTE4MjIwMFoXDTI1MDkwOTE4MjIwMFowgZwxCzAJBgNV
7
- BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
8
- ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR8wHQYDVQQDExZUaW5mb2lsIFNlY3Vy
9
- aXR5LCBJbmMuMSowKAYJKoZIhvcNAQkBFhtzdXBwb3J0QHRpbmZvaWxzZWN1cml0
10
- eS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqbHvsSj0H0FB1
11
- 0gLYoDK1BKugkSB2DZeZZHP6B1UdWRahJXJP9oT1lhfQxx8iX4cgEi7JU3NqA6NR
12
- cIRFQ50eH/qlmgs7909gaf8pDaeC0vR3wd0GeRg6qr1eDEnkzIyr/D1AMiX6H1eP
13
- Y7J3SfrdaL3gft2iPRKGkgqsXR7oBNLA3n/ShiNgPXqRDl1CCj6aMY0cn5ROFScz
14
- vT2FUB4DEwPD2l18m1p99OnXqsOLL2J65qA2+cI8FtgFmlwIi5oSf+URvIdNx+cH
15
- lInlAtVHCvAKYLY0dlQ7czMQBcRpYjp2rwPt9f2ksq9b/voMTBABYHFV+IVn8svv
16
- GZ5e1+icjtr/R7dCGmCdEdFLXVxafmZhukymG9USv9DKuv1qh7r4q8KaPIE8n7nQ
17
- m97jENFfsgnwv+nUmIJ3tzuW5ZxO7A0tIIYdwzt0UjrO3ya4R5bTFXr4bnzZ/g/s
18
- CLknWqg1BCRlPd6LnpVGPT0gNDV1pEO25wE3A3Yy0Ujxudcgay/CgUhnlU11qOAc
19
- xmar2fhNZsviUhndd/220Ad5QMV2XzcAiopJIeu0juIVGRQM7x2h19Hsp0m6sOEF
20
- jfhvbdUa4nvmIFeYFY+hr/YkTmG9ZjyBa8YaZXhwjhSmKCQ374J7mn5e0Cryuvi5
21
- tYhwJn8rdwYZF/h2qqfEu8vaLoD09QIDAQABo4IBizCCAYcwHQYDVR0OBBYEFMmT
22
- /x412UH+5OHqgleeTjLOv6iHMIHRBgNVHSMEgckwgcaAFMmT/x412UH+5OHqglee
23
- TjLOv6iHoYGipIGfMIGcMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNV
24
- BAcTCVBhbG8gQWx0bzEfMB0GA1UEChMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEf
25
- MB0GA1UEAxMWVGluZm9pbCBTZWN1cml0eSwgSW5jLjEqMCgGCSqGSIb3DQEJARYb
26
- c3VwcG9ydEB0aW5mb2lsc2VjdXJpdHkuY29tggkAra7QuiMwI2AwDwYDVR0TAQH/
27
- BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQYwCQYDVR0SBAIwADArBglghkgBhvhC
28
- AQ0EHhYcVGlueUNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAmBgNVHREEHzAdgRtz
29
- dXBwb3J0QHRpbmZvaWxzZWN1cml0eS5jb20wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
30
- SIb3DQEBBQUAA4ICAQBZy4JJSmwLuO0nZbdr4tJeVS2P8bcGi6PzAcdzVfwzjp6n
31
- 5qf8m4O8my4lnJieom0GrWSHQoPY1Yur4hEoZbugKO9DWZL3dTiGcrgw0TbQ6Gtq
32
- TTPatW3LA21qFJwvohSvLqPdmZuM+H9g49sdl2kNTDVI6iUyMYuNpL14aPKPGBFo
33
- o7UjciT1h7JtJl9b/fXrbPeRHBwpZXWeipiPGv/OZW5KnOsNlUkTquS7Zj4ETkIC
34
- 6mVtmsLvq+YwFthFyMU37pXwYxcmqRmH6lX+XC6AVW5oO4GBmG+Zr/Z+h5Cih5ca
35
- /mX88RkO+dGTjw1IdxKmxOqKL62OBATKrTDJ/scsmRptynA4TunYW+7ikOpDbPfL
36
- l18aleLISlcgWJg/Czf2nmBqAClPLnhV8qxWsvt58MQQ/Jpoggvpl8EG1PylWiBS
37
- Kc/4Ad/FKQFpTzXUgDg2kV07npVjYbBzA5p4ZSWSlflFu93jb9gg2+qtnRSImVCZ
38
- nQjZdsv8hebElPAIbtJjSnoH1Kz2ucYLakdF1UMKnpp1PVREtuKPz/foU9KUHs0z
39
- dWRALx8cWG4uKK9AIEUlVdGKfX0Wj0qFK0KGxl3f3jObud5Agwue2EPKWwUzEGUh
40
- Iqp60gNw3vBdKHw4dh1bfcbXWnRDL+OQPuOFZeMWgu1QmeHeuggYtYtRg7V5Kg==
41
- -----END CERTIFICATE-----
@@ -1,35 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIGADCCA+igAwIBAgIIHIF9ta6cW3YwDQYJKoZIhvcNAQENBQAwgZwxCzAJBgNV
3
- BAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQK
4
- ExZUaW5mb2lsIFNlY3VyaXR5LCBJbmMuMR8wHQYDVQQDExZUaW5mb2lsIFNlY3Vy
5
- aXR5LCBJbmMuMSowKAYJKoZIhvcNAQkBFhtzdXBwb3J0QHRpbmZvaWxzZWN1cml0
6
- eS5jb20wHhcNMjIwMzIyMjI1MzAwWhcNMjUwOTA5MTgyMjAwWjCBiDELMAkGA1UE
7
- BhMCVVMxCzAJBgNVBAgTAkNBMR8wHQYDVQQKExZUaW5mb2lsIFNlY3VyaXR5LCBJ
8
- bmMuMR0wGwYDVQQDExR0aW5mb2lsc2VjdXJpdHktZ2VtczEsMCoGCSqGSIb3DQEJ
9
- ARYdZW5naW5lZXJzQHRpbmZvaWxzZWN1cml0eS5jb20wggIiMA0GCSqGSIb3DQEB
10
- AQUAA4ICDwAwggIKAoICAQDNJYNH8D+8lACLt3KzjEIPs3XVBCPaMm2eD/Xk9OOT
11
- uDV/NqgMK0icD9MRxMUtS3SCrC9QcPocXT76f2LQ3yVJuK+rBUasymEES47PIx2c
12
- zC4n4Hga0xPPuBpioO26oaRFsobyzh9RPOIbnYfpjyqtdrbm+YyM3sPR4XzFirv9
13
- xomT4E9T4RCLgOQHTcLKL9K9m+EN7PeVdVUXV0Pa7cVs2vJUKedsd7vnr6Lzbn8T
14
- oPk/7J/4W931PbaeI5yg9ZuaRa9K2IaY1TkPI67NW4qKitBVepRlXw6Sb7TYcUnc
15
- WEQ/eC5CpnOmqUrG5tfGD8cc5aGZOkitW/VXZgVj81xgCv1hk4HjErrqq4FBNAaC
16
- SNyBfwR0TUYqg1lN1nbNjOKwfb6YRn06R2ovcFJG0tmGhsQULCr6fW8u2TfSM+U9
17
- WFSIJx2griureY7EZPwg/MgsUiWUWMFemz3GVYXWJR3dN2pW9Uqr3rkjKZbA0bst
18
- GWahJO9HuFdDakQxoaTPYPtTQDC+kskkO6lKG1KLIoZ1iLZzB1Ks1vEeyE7lp1im
19
- WgpUq+q23PFkt1gIBi/4tGvzsLZye25QU2Y+XLzldCNm+DyRFXZ+Q+bK33IveUeU
20
- WEOv4T1qTXHAOypyzmgodVRG/PrlsSMOBfE515kG1mDMGjRcCpEtlskgxUbf7qM7
21
- hQIDAQABo1gwVjAJBgNVHRMEAjAAMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHBzOi8v
22
- d3d3LnRpbmZvaWxzZWN1cml0eS5jb20vc2VjdXJpdHkvcmV2b2NhdGlvbl9saXN0
23
- MA0GCSqGSIb3DQEBDQUAA4ICAQAiYF/m2ny/mxFvBVxHfdYuzybhCvsEUd+TSnoe
24
- mqOWntY3sxCOaY0aGOMB4vyg9G+oP/kT4m63sD4uQxeuU7WOjaG2smCSS5q+PSWS
25
- v63gILqPamjSyP/Om864EA6YlvVQ7nPXhVDEaiBt3iliefJGmb0wWSbbDCmq3aMb
26
- WTLuax/IeY6MjJi20LutIcuz+VX8OxlA1hSpgAToMz3xrhA8fPt5UkKhkDkPFYBF
27
- 5htKVipyijChWsXyt33YM2qGaavTEXzxza1I99PGNRKxUMvbSMas4YaLqkBpQSc+
28
- mcrLWYPiXWsePGu+j08AypE2Ubp4AOSZJN9rBBGotC3gofipo+K/sBiOM9xXI76Q
29
- 0HYOxXPa7D7UQQG1R9i0rcxmf9qepIVYCldmqVkKKDizcDo5UI9lRiLFjDyQhn6l
30
- YFY9bPQ4lKTK5Jr3M6+dV7fHxLhqXyMGs1905IUb7qvB7Bq/f0qJfC0JZuY/qdn2
31
- lL0SeFKOVsjErtobh3u8p8j2USkc8uJgIANHpXEMEExdp899CV/eVjh3TpAR7E6T
32
- mg7Q9Hi6Hh8z+Le9iR4I49vPEWDQEvj35IT6VfwU79UfIOlX+DkW8fFkPbaut3Se
33
- vqIDv6JBG9I16h/HhchntKfM58MI1bNZFBSdZqYOJiL8JIjP8HNIk76Y366ppG29
34
- EhBYYg==
35
- -----END CERTIFICATE-----
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 5.1"
6
- gem "activesupport", "~> 5.1"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 5.2"
6
- gem "activesupport", "~> 5.2"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 6.0"
6
- gem "activesupport", "~> 6.0"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 6.1"
6
- gem "activesupport", "~> 6.1"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 7.0"
6
- gem "activesupport", "~> 7.0"
7
-
8
- gemspec path: "../"
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
Binary file