devise-two-factor 4.1.1 → 6.0.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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "railties", "~> 7.0"
6
- gem "activesupport", "~> 7.0"
5
+ gem "railties", "~> 7.0.0"
6
+ gem "activesupport", "~> 7.0.0"
7
7
 
8
8
  gemspec path: "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "railties", "~> 4.1"
6
- gem "activesupport", "~> 4.1"
5
+ gem "railties", "~> 7.1.0"
6
+ gem "activesupport", "~> 7.1.0"
7
7
 
8
8
  gemspec path: "../"
@@ -3,20 +3,26 @@ require 'devise_two_factor/models'
3
3
  require 'devise_two_factor/strategies'
4
4
 
5
5
  module Devise
6
- # The length of generated OTP secrets
6
+ # The length of randomly generated OTP shared secret (in bytes).
7
+ # The secrets will be base32-encoded and have a length 1.6 times the configured value.
7
8
  mattr_accessor :otp_secret_length
8
- @@otp_secret_length = 24
9
+ @@otp_secret_length = 20
9
10
 
10
11
  # The number of seconds before and after the current
11
12
  # time for which codes will be accepted
12
13
  mattr_accessor :otp_allowed_drift
13
14
  @@otp_allowed_drift = 30
14
15
 
15
- # The key used to encrypt OTP secrets in the database
16
+ # The key used to encrypt OTP secrets in the database in legacy installs.
16
17
  mattr_accessor :otp_secret_encryption_key
17
18
  @@otp_secret_encryption_key = nil
18
19
 
19
- # The length of all generated OTP backup codes
20
+ # These options are passed to the Rails 7+ encrypted attribute
21
+ mattr_accessor :otp_encrypted_attribute_options
22
+ @@otp_encrypted_attribute_options = {}
23
+
24
+ # The length of randomly generated OTP backup codes (in bytes).
25
+ # The codes will be hex-encoded and have a length twice the configured value.
20
26
  mattr_accessor :otp_backup_code_length
21
27
  @@otp_backup_code_length = 16
22
28
 
@@ -27,7 +33,7 @@ module Devise
27
33
  end
28
34
 
29
35
  Devise.add_module(:two_factor_authenticatable, :route => :session, :strategy => true,
30
- :controller => :sessions, :model => true)
36
+ :controller => :sessions, :model => true, :insert_at => 0)
31
37
 
32
38
  Devise.add_module(:two_factor_backupable, :route => :session, :strategy => true,
33
39
  :controller => :sessions, :model => true)
@@ -7,25 +7,28 @@ module Devise
7
7
  include Devise::Models::DatabaseAuthenticatable
8
8
 
9
9
  included do
10
- unless %i[otp_secret otp_secret=].all? { |attr| method_defined?(attr) }
11
- require 'attr_encrypted'
12
-
13
- unless singleton_class.ancestors.include?(AttrEncrypted)
14
- extend AttrEncrypted
15
- end
16
-
17
- unless attr_encrypted?(:otp_secret)
18
- attr_encrypted :otp_secret,
19
- :key => self.otp_secret_encryption_key,
20
- :mode => :per_attribute_iv_and_salt unless self.attr_encrypted?(:otp_secret)
21
- end
22
- end
23
-
10
+ encrypts :otp_secret, **splattable_encrypted_attr_options
24
11
  attr_accessor :otp_attempt
25
12
  end
26
13
 
14
+ def otp_secret
15
+ # return the OTP secret stored as a Rails encrypted attribute if it
16
+ # exists. Otherwise return OTP secret stored by the `attr_encrypted` gem
17
+ return self[:otp_secret] if self[:otp_secret]
18
+
19
+ legacy_otp_secret
20
+ end
21
+
22
+ ##
23
+ # Decrypt and return the `encrypted_otp_secret` attribute which was used in
24
+ # prior versions of devise-two-factor
25
+ # See: # https://github.com/tinfoil/devise-two-factor/blob/main/UPGRADING.md
26
+ def legacy_otp_secret
27
+ nil
28
+ end
29
+
27
30
  def self.required_fields(klass)
28
- [:encrypted_otp_secret, :encrypted_otp_secret_iv, :encrypted_otp_secret_salt, :consumed_timestep]
31
+ [:otp_secret, :consumed_timestep]
29
32
  end
30
33
 
31
34
  # This defaults to the model's otp_secret
@@ -78,7 +81,8 @@ module Devise
78
81
  def consume_otp!
79
82
  if self.consumed_timestep != current_otp_timestep
80
83
  self.consumed_timestep = current_otp_timestep
81
- return save(validate: false)
84
+ save!(validate: false)
85
+ return true
82
86
  end
83
87
 
84
88
  false
@@ -87,10 +91,21 @@ module Devise
87
91
  module ClassMethods
88
92
  Devise::Models.config(self, :otp_secret_length,
89
93
  :otp_allowed_drift,
94
+ :otp_encrypted_attribute_options,
90
95
  :otp_secret_encryption_key)
91
96
 
97
+ # Geneartes an OTP secret of the specified length, returning it after Base32 encoding.
92
98
  def generate_otp_secret(otp_secret_length = self.otp_secret_length)
93
- ROTP::Base32.random_base32(otp_secret_length)
99
+ ROTP::Base32.random(otp_secret_length)
100
+ end
101
+
102
+ # Return value will be splatted with ** so return a version of the
103
+ # encrypted attribute options which is always a Hash.
104
+ # @return [Hash]
105
+ def splattable_encrypted_attr_options
106
+ return {} if otp_encrypted_attribute_options.nil?
107
+
108
+ otp_encrypted_attribute_options
94
109
  end
95
110
  end
96
111
  end
@@ -20,7 +20,7 @@ module Devise
20
20
  code_length = self.class.otp_backup_code_length
21
21
 
22
22
  number_of_codes.times do
23
- codes << SecureRandom.hex(code_length / 2) # Hexstring has length 2*n
23
+ codes << SecureRandom.hex(code_length)
24
24
  end
25
25
 
26
26
  hashed_codes = codes.map { |code| Devise::Encryptor.digest(self.class, code) }
@@ -30,7 +30,7 @@ module Devise
30
30
  end
31
31
 
32
32
  # Returns true and invalidates the given code
33
- # iff that code is a valid backup code.
33
+ # if that code is a valid backup code.
34
34
  def invalidate_otp_backup_code!(code)
35
35
  codes = self.otp_backup_codes || []
36
36
 
@@ -39,6 +39,7 @@ module Devise
39
39
 
40
40
  codes.delete(backup_code)
41
41
  self.otp_backup_codes = codes
42
+ save!(validate: false)
42
43
  return true
43
44
  end
44
45
 
@@ -8,25 +8,13 @@ RSpec.shared_examples 'two_factor_authenticatable' do
8
8
 
9
9
  describe 'required_fields' do
10
10
  it 'should have the attr_encrypted fields for otp_secret' do
11
- expect(Devise::Models::TwoFactorAuthenticatable.required_fields(subject.class)).to contain_exactly(:encrypted_otp_secret, :encrypted_otp_secret_iv, :encrypted_otp_secret_salt, :consumed_timestep)
11
+ expect(Devise::Models::TwoFactorAuthenticatable.required_fields(subject.class)).to contain_exactly(:otp_secret, :consumed_timestep)
12
12
  end
13
13
  end
14
14
 
15
15
  describe '#otp_secret' do
16
- it 'should be of the configured length' do
17
- expect(subject.otp_secret.length).to eq(subject.class.otp_secret_length)
18
- end
19
-
20
- it 'stores the encrypted otp_secret' do
21
- expect(subject.encrypted_otp_secret).to_not be_nil
22
- end
23
-
24
- it 'stores an iv for otp_secret' do
25
- expect(subject.encrypted_otp_secret_iv).to_not be_nil
26
- end
27
-
28
- it 'stores a salt for otp_secret' do
29
- expect(subject.encrypted_otp_secret_salt).to_not be_nil
16
+ it 'should be of the expected length' do
17
+ expect(subject.otp_secret.length).to eq(subject.class.otp_secret_length*8/5)
30
18
  end
31
19
  end
32
20
 
@@ -137,15 +125,15 @@ RSpec.shared_examples 'two_factor_authenticatable' do
137
125
 
138
126
  describe '#otp_provisioning_uri' do
139
127
  let(:otp_secret_length) { subject.class.otp_secret_length }
140
- let(:account) { Faker::Internet.email }
128
+ let(:account) { 'user@host.example' }
141
129
  let(:issuer) { 'Tinfoil' }
142
130
 
143
131
  it 'should return uri with specified account' do
144
- expect(subject.otp_provisioning_uri(account)).to match(%r{otpauth://totp/#{CGI.escape(account)}\?secret=\w{#{otp_secret_length}}})
132
+ expect(subject.otp_provisioning_uri(account)).to match(%r{otpauth://totp/#{CGI.escape(account)}\?secret=\w{#{otp_secret_length*8/5}}})
145
133
  end
146
134
 
147
135
  it 'should return uri with issuer option' do
148
- expect(subject.otp_provisioning_uri(account, issuer: issuer)).to match(%r{otpauth://totp/#{issuer}:#{CGI.escape(account)}\?.*secret=\w{#{otp_secret_length}}(&|$)})
136
+ expect(subject.otp_provisioning_uri(account, issuer: issuer)).to match(%r{otpauth://totp/#{issuer}:#{CGI.escape(account)}\?.*secret=\w{#{otp_secret_length*8/5}}(&|$)})
149
137
  expect(subject.otp_provisioning_uri(account, issuer: issuer)).to match(%r{otpauth://totp/#{issuer}:#{CGI.escape(account)}\?.*issuer=#{issuer}(&|$)})
150
138
  end
151
139
  end
@@ -17,7 +17,7 @@ RSpec.shared_examples 'two_factor_backupable' do
17
17
 
18
18
  it 'generates recovery codes of the correct length' do
19
19
  @plaintext_codes.each do |code|
20
- expect(code.length).to eq(subject.class.otp_backup_code_length)
20
+ expect(code.length).to eq(subject.class.otp_backup_code_length*2)
21
21
  end
22
22
  end
23
23
 
@@ -34,7 +34,7 @@ RSpec.shared_examples 'two_factor_backupable' do
34
34
  end
35
35
 
36
36
  context 'with existing recovery codes' do
37
- let(:old_codes) { Faker::Lorem.words }
37
+ let(:old_codes) { ['adam', 'betty', 'charles'] }
38
38
  let(:old_codes_hashed) { old_codes.map { |x| Devise::Encryptor.digest(subject.class, x) } }
39
39
 
40
40
  before do
@@ -21,7 +21,7 @@ module Devise
21
21
 
22
22
  def validate_otp(resource)
23
23
  return true unless resource.otp_required_for_login
24
- return if params[scope]['otp_attempt'].nil?
24
+ return if params[scope].nil? || params[scope]['otp_attempt'].nil?
25
25
  resource.validate_and_consume_otp!(params[scope]['otp_attempt'])
26
26
  end
27
27
  end
@@ -6,9 +6,6 @@ module Devise
6
6
  resource = mapping.to.find_for_database_authentication(authentication_hash)
7
7
 
8
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!
12
9
  super
13
10
  end
14
11
 
@@ -1,3 +1,3 @@
1
1
  module DeviseTwoFactor
2
- VERSION = '4.1.1'.freeze
2
+ VERSION = '6.0.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
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,11 +1,11 @@
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.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Shane Wilton
8
- autorequire:
7
+ - Quinn Wilton
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - |
@@ -86,7 +86,7 @@ cert_chain:
86
86
  vqIDv6JBG9I16h/HhchntKfM58MI1bNZFBSdZqYOJiL8JIjP8HNIk76Y366ppG29
87
87
  EhBYYg==
88
88
  -----END CERTIFICATE-----
89
- date: 2023-10-12 00:00:00.000000000 Z
89
+ date: 2024-09-17 00:00:00.000000000 Z
90
90
  dependencies:
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: railties
@@ -116,32 +116,6 @@ dependencies:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
118
  version: '7.0'
119
- - !ruby/object:Gem::Dependency
120
- name: attr_encrypted
121
- requirement: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '1.3'
126
- - - "!="
127
- - !ruby/object:Gem::Version
128
- version: '2'
129
- - - "<"
130
- - !ruby/object:Gem::Version
131
- version: '5'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '1.3'
139
- - - "!="
140
- - !ruby/object:Gem::Version
141
- version: '2'
142
- - - "<"
143
- - !ruby/object:Gem::Version
144
- version: '5'
145
119
  - !ruby/object:Gem::Dependency
146
120
  name: devise
147
121
  requirement: !ruby/object:Gem::Requirement
@@ -240,28 +214,17 @@ dependencies:
240
214
  - - ">="
241
215
  - !ruby/object:Gem::Version
242
216
  version: '0'
243
- - !ruby/object:Gem::Dependency
244
- name: faker
245
- requirement: !ruby/object:Gem::Requirement
246
- requirements:
247
- - - ">="
248
- - !ruby/object:Gem::Version
249
- version: '0'
250
- type: :development
251
- prerelease: false
252
- version_requirements: !ruby/object:Gem::Requirement
253
- requirements:
254
- - - ">="
255
- - !ruby/object:Gem::Version
256
- version: '0'
257
- description: Barebones two-factor authentication with Devise
258
- email: engineers@tinfoilsecurity.com
217
+ description: Devise-Two-Factor is a minimalist extension to Devise which offers support
218
+ for two-factor authentication through the TOTP scheme.
219
+ email:
259
220
  executables: []
260
221
  extensions: []
261
222
  extra_rdoc_files: []
262
223
  files:
224
+ - ".github/dependabot.yml"
263
225
  - ".github/workflows/ci.yml"
264
226
  - ".gitignore"
227
+ - ".markdownlint.json"
265
228
  - ".rspec"
266
229
  - Appraisals
267
230
  - CHANGELOG.md
@@ -270,18 +233,13 @@ files:
270
233
  - LICENSE
271
234
  - README.md
272
235
  - Rakefile
236
+ - SECURITY.md
273
237
  - UPGRADING.md
274
238
  - certs/tinfoil-cacert.pem
275
239
  - certs/tinfoilsecurity-gems-cert.pem
276
240
  - 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
241
  - gemfiles/rails_7.0.gemfile
242
+ - gemfiles/rails_7.1.gemfile
285
243
  - lib/devise-two-factor.rb
286
244
  - lib/devise_two_factor/models.rb
287
245
  - lib/devise_two_factor/models/two_factor_authenticatable.rb
@@ -297,11 +255,11 @@ files:
297
255
  - spec/devise/models/two_factor_authenticatable_spec.rb
298
256
  - spec/devise/models/two_factor_backupable_spec.rb
299
257
  - spec/spec_helper.rb
300
- homepage: https://github.com/tinfoil/devise-two-factor
258
+ homepage: https://github.com/devise-two-factor/devise-two-factor
301
259
  licenses:
302
260
  - MIT
303
261
  metadata: {}
304
- post_install_message:
262
+ post_install_message:
305
263
  rdoc_options: []
306
264
  require_paths:
307
265
  - lib
@@ -316,8 +274,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
274
  - !ruby/object:Gem::Version
317
275
  version: '0'
318
276
  requirements: []
319
- rubygems_version: 3.0.3.1
320
- signing_key:
277
+ rubygems_version: 3.5.11
278
+ signing_key:
321
279
  specification_version: 4
322
280
  summary: Barebones two-factor authentication with Devise
323
281
  test_files:
metadata.gz.sig CHANGED
Binary file
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "railties", "~> 4.2"
6
- gem "activesupport", "~> 4.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", "~> 5.0"
6
- gem "activesupport", "~> 5.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", "~> 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: "../"