lockbox 1.4.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c227a11280d70eaaa03e7c81649bee696c2c88ab9a1825503f7db4e9af5d2d12
4
- data.tar.gz: 52a2969568229aefa391a093c93ae1771d021ddc2396d3e4f65ec2f509a82c41
3
+ metadata.gz: 15860ff6f0c444491002e98231bb32785c05d2f6f73be85e34ecb7a53ad43888
4
+ data.tar.gz: 026be73917780e5bea3fc7178d404d2d4a2320378f94dc98c7dca0b180e40a83
5
5
  SHA512:
6
- metadata.gz: 1734e1db6d559ed4221e81b30ca6a13db348a6089f58581376ce4cf16019a5787f8dd1b80abd1534ef2c82e294db4db1d8cb30089413d4e2e009544d3185d350
7
- data.tar.gz: d5bdb1947c5fac19038fe21651bf35d32d675eba024569ec085b015ad991a9c1ea5e65437df908f78e0083486726032571c6dee364fe92a95a7447e33495cf83
6
+ metadata.gz: 5cef3979e21483caaa9a860d2e6301c29dbc6c58a44be765da92970981695eb813d09a6c0b43dbd3a53fe3b30dc48dc212436be63dcbeac303d566064095e36b
7
+ data.tar.gz: 9a7378720dcfb6a1a07687a42d957b3d4abfae349cbef0678a98e6b0f458d4726087c1ee69457624c13f8342ef67687232ccab25d6e2e339561e5603d98b9ea3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 2.0.0 (2024-10-26)
2
+
3
+ - Improved `attributes`, `attribute_names`, and `has_attribute?` when ciphertext attributes not loaded
4
+ - Removed deprecated `lockbox_encrypts` (use `has_encrypted` instead)
5
+ - Dropped support for Active Record < 7 and Ruby < 3.1
6
+ - Dropped support for Mongoid < 8
7
+
8
+ ## 1.4.1 (2024-09-09)
9
+
10
+ - Fixed error message for previews for Active Storage 7.1.4
11
+
1
12
  ## 1.4.0 (2024-08-09)
2
13
 
3
14
  - Added support for Active Record 7.2
data/README.md CHANGED
@@ -35,7 +35,7 @@ Set the following environment variable with your key (you can use this one in de
35
35
  LOCKBOX_MASTER_KEY=0000000000000000000000000000000000000000000000000000000000000000
36
36
  ```
37
37
 
38
- or add it to your credentials for each environment (`rails credentials:edit --environment <env>` for Rails 6+)
38
+ or add it to your credentials for each environment (`rails credentials:edit --environment <env>`)
39
39
 
40
40
  ```yml
41
41
  lockbox:
@@ -72,7 +72,7 @@ Then follow the instructions below for the data you want to encrypt.
72
72
  Create a migration with:
73
73
 
74
74
  ```ruby
75
- class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.1]
75
+ class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.2]
76
76
  def change
77
77
  add_column :users, :email_ciphertext, :text
78
78
  end
@@ -251,7 +251,7 @@ User.decrypt_email_ciphertext(user.email_ciphertext)
251
251
  Create a migration with:
252
252
 
253
253
  ```ruby
254
- class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[7.1]
254
+ class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[7.2]
255
255
  def change
256
256
  add_column :action_text_rich_texts, :body_ciphertext, :text
257
257
  end
@@ -382,7 +382,7 @@ Encryption is applied to all versions after processing.
382
382
  You can mount the uploader [as normal](https://github.com/carrierwaveuploader/carrierwave#activerecord). With Active Record, this involves creating a migration:
383
383
 
384
384
  ```ruby
385
- class AddLicenseToUsers < ActiveRecord::Migration[7.1]
385
+ class AddLicenseToUsers < ActiveRecord::Migration[7.2]
386
386
  def change
387
387
  add_column :users, :license, :string
388
388
  end
@@ -910,7 +910,7 @@ end
910
910
  You can use `binary` columns for the ciphertext instead of `text` columns.
911
911
 
912
912
  ```ruby
913
- class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.1]
913
+ class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.2]
914
914
  def change
915
915
  add_column :users, :email_ciphertext, :binary
916
916
  end
@@ -961,7 +961,7 @@ end
961
961
  Create a migration with:
962
962
 
963
963
  ```ruby
964
- class MigrateToLockbox < ActiveRecord::Migration[7.1]
964
+ class MigrateToLockbox < ActiveRecord::Migration[7.2]
965
965
  def change
966
966
  add_column :users, :name_ciphertext, :text
967
967
  add_column :users, :email_ciphertext, :text
@@ -994,7 +994,7 @@ end
994
994
  Then remove the previous gem from your Gemfile and drop its columns.
995
995
 
996
996
  ```ruby
997
- class RemovePreviousEncryptedColumns < ActiveRecord::Migration[7.1]
997
+ class RemovePreviousEncryptedColumns < ActiveRecord::Migration[7.2]
998
998
  def change
999
999
  remove_column :users, :encrypted_name, :text
1000
1000
  remove_column :users, :encrypted_name_iv, :text
@@ -1004,18 +1004,6 @@ class RemovePreviousEncryptedColumns < ActiveRecord::Migration[7.1]
1004
1004
  end
1005
1005
  ```
1006
1006
 
1007
- ## Upgrading
1008
-
1009
- ### 1.0.0
1010
-
1011
- `encrypts` is now deprecated in favor of `has_encrypted` to avoid conflicting with Active Record encryption.
1012
-
1013
- ```ruby
1014
- class User < ApplicationRecord
1015
- has_encrypted :email
1016
- end
1017
- ```
1018
-
1019
1007
  ## History
1020
1008
 
1021
1009
  View the [changelog](https://github.com/ankane/lockbox/blob/master/CHANGELOG.md)
@@ -29,11 +29,7 @@ module Lockbox
29
29
  # use connection_config instead of connection.adapter
30
30
  # so database connection isn't needed
31
31
  def adapter
32
- if ActiveRecord::VERSION::STRING.to_f >= 6.1
33
- ActiveRecord::Base.connection_db_config.adapter.to_s
34
- else
35
- ActiveRecord::Base.connection_config[:adapter].to_s
36
- end
32
+ ActiveRecord::Base.connection_db_config.adapter.to_s
37
33
  end
38
34
  end
39
35
  end
@@ -34,13 +34,6 @@ module Lockbox
34
34
  end
35
35
 
36
36
  module AttachedOne
37
- if ActiveStorage::VERSION::MAJOR < 6
38
- def attach(attachable)
39
- attachable = encrypt_attachable(attachable) if encrypted?
40
- super(attachable)
41
- end
42
- end
43
-
44
37
  def rotate_encryption!
45
38
  raise "Not encrypted" unless encrypted?
46
39
 
@@ -51,19 +44,6 @@ module Lockbox
51
44
  end
52
45
 
53
46
  module AttachedMany
54
- if ActiveStorage::VERSION::MAJOR < 6
55
- def attach(*attachables)
56
- if encrypted?
57
- attachables =
58
- attachables.flatten.collect do |attachable|
59
- encrypt_attachable(attachable)
60
- end
61
- end
62
-
63
- super(attachables)
64
- end
65
- end
66
-
67
47
  def rotate_encryption!
68
48
  raise "Not encrypted" unless encrypted?
69
49
 
@@ -124,32 +104,43 @@ module Lockbox
124
104
  super
125
105
  end
126
106
 
127
- if ActiveStorage::VERSION::MAJOR >= 6
128
- def open(**options)
129
- blob.open(**options) do |file|
130
- options = Utils.encrypted_options(record, name)
131
- # only trust the metadata when migrating
132
- # as earlier versions of Lockbox won't have it
133
- # and it's not a good practice to trust modifiable data
134
- encrypted = options && (!options[:migrating] || blob.metadata["encrypted"])
135
- if encrypted
136
- result = Utils.decrypt_result(record, name, options, file.read)
137
- file.rewind
138
- # truncate may not be available on all platforms
139
- # according to the Ruby docs
140
- # may need to create a new temp file instead
141
- file.truncate(0)
142
- file.write(result)
143
- file.rewind
144
- end
145
-
146
- yield file
107
+ if ActiveStorage::VERSION::STRING.to_f == 7.1 && ActiveStorage.version >= "7.1.4"
108
+ def transform_variants_later
109
+ blob.instance_variable_set(:@lockbox_encrypted, true) if Utils.encrypted_options(record, name)
110
+ super
111
+ end
112
+ end
113
+
114
+ def open(**options)
115
+ blob.open(**options) do |file|
116
+ options = Utils.encrypted_options(record, name)
117
+ # only trust the metadata when migrating
118
+ # as earlier versions of Lockbox won't have it
119
+ # and it's not a good practice to trust modifiable data
120
+ encrypted = options && (!options[:migrating] || blob.metadata["encrypted"])
121
+ if encrypted
122
+ result = Utils.decrypt_result(record, name, options, file.read)
123
+ file.rewind
124
+ # truncate may not be available on all platforms
125
+ # according to the Ruby docs
126
+ # may need to create a new temp file instead
127
+ file.truncate(0)
128
+ file.write(result)
129
+ file.rewind
147
130
  end
131
+
132
+ yield file
148
133
  end
149
134
  end
150
135
  end
151
136
 
152
137
  module Blob
138
+ if ActiveStorage::VERSION::STRING.to_f == 7.1 && ActiveStorage.version >= "7.1.4"
139
+ def preview_image_needed_before_processing_variants?
140
+ !instance_variable_defined?(:@lockbox_encrypted) && super
141
+ end
142
+ end
143
+
153
144
  private
154
145
 
155
146
  def extract_content_type(io)
data/lib/lockbox/model.rb CHANGED
@@ -60,7 +60,7 @@ module Lockbox
60
60
  class_eval do
61
61
  # Lockbox uses custom inspect
62
62
  # but this could be useful for other gems
63
- if activerecord && ActiveRecord::VERSION::MAJOR >= 6
63
+ if activerecord
64
64
  # only add virtual attribute
65
65
  # need to use regexp since strings do partial matching
66
66
  # also, need to use += instead of <<
@@ -114,12 +114,6 @@ module Lockbox
114
114
  k = lockbox_encrypted_attributes[k]
115
115
  elsif values.key?(k)
116
116
  v = respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : values[k].inspect
117
-
118
- # fix for https://github.com/rails/rails/issues/40725
119
- # TODO only apply to Active Record 6.0
120
- if respond_to?(:inspection_filter, true) && v != "nil"
121
- v = inspection_filter.filter_param(k, v)
122
- end
123
117
  else
124
118
  next
125
119
  end
@@ -148,7 +142,40 @@ module Lockbox
148
142
  end
149
143
  end
150
144
  end
151
- super
145
+
146
+ # remove attributes that do not have a ciphertext attribute
147
+ attributes = super
148
+ self.class.lockbox_attributes.each do |k, lockbox_attribute|
149
+ if !attributes.include?(lockbox_attribute[:encrypted_attribute].to_s)
150
+ attributes.delete(k.to_s)
151
+ attributes.delete(lockbox_attribute[:attribute])
152
+ end
153
+ end
154
+ attributes
155
+ end
156
+
157
+ # remove attribute names that do not have a ciphertext attribute
158
+ def attribute_names
159
+ # hash preserves key order
160
+ names_set = super.to_h { |v| [v, true] }
161
+ self.class.lockbox_attributes.each do |k, lockbox_attribute|
162
+ if !names_set.include?(lockbox_attribute[:encrypted_attribute].to_s)
163
+ names_set.delete(k.to_s)
164
+ names_set.delete(lockbox_attribute[:attribute])
165
+ end
166
+ end
167
+ names_set.keys
168
+ end
169
+
170
+ # check the ciphertext attribute for encrypted attributes
171
+ def has_attribute?(attr_name)
172
+ attr_name = attr_name.to_s
173
+ _, lockbox_attribute = self.class.lockbox_attributes.find { |_, la| la[:attribute] == attr_name }
174
+ if lockbox_attribute
175
+ super(lockbox_attribute[:encrypted_attribute])
176
+ else
177
+ super
178
+ end
152
179
  end
153
180
 
154
181
  # needed for in-place modifications
@@ -232,71 +259,69 @@ module Lockbox
232
259
  result
233
260
  end
234
261
 
235
- if ActiveRecord::VERSION::MAJOR >= 6
236
- if ActiveRecord::VERSION::STRING.to_f >= 7.2
237
- def self.insert(attributes, **options)
238
- super(lockbox_map_record_attributes(attributes), **options)
239
- end
240
-
241
- def self.insert!(attributes, **options)
242
- super(lockbox_map_record_attributes(attributes), **options)
243
- end
244
-
245
- def self.upsert(attributes, **options)
246
- super(lockbox_map_record_attributes(attributes, check_readonly: true), **options)
247
- end
262
+ if ActiveRecord::VERSION::STRING.to_f >= 7.2
263
+ def self.insert(attributes, **options)
264
+ super(lockbox_map_record_attributes(attributes), **options)
248
265
  end
249
266
 
250
- def self.insert_all(attributes, **options)
251
- super(lockbox_map_attributes(attributes), **options)
267
+ def self.insert!(attributes, **options)
268
+ super(lockbox_map_record_attributes(attributes), **options)
252
269
  end
253
270
 
254
- def self.insert_all!(attributes, **options)
255
- super(lockbox_map_attributes(attributes), **options)
271
+ def self.upsert(attributes, **options)
272
+ super(lockbox_map_record_attributes(attributes, check_readonly: true), **options)
256
273
  end
274
+ end
257
275
 
258
- def self.upsert_all(attributes, **options)
259
- super(lockbox_map_attributes(attributes, check_readonly: true), **options)
260
- end
276
+ def self.insert_all(attributes, **options)
277
+ super(lockbox_map_attributes(attributes), **options)
278
+ end
261
279
 
262
- # private
263
- # does not try to handle :returning option for simplicity
264
- def self.lockbox_map_attributes(records, check_readonly: false)
265
- return records unless records.is_a?(Array)
280
+ def self.insert_all!(attributes, **options)
281
+ super(lockbox_map_attributes(attributes), **options)
282
+ end
266
283
 
267
- records.map do |attributes|
268
- lockbox_map_record_attributes(attributes, check_readonly: false)
269
- end
270
- end
284
+ def self.upsert_all(attributes, **options)
285
+ super(lockbox_map_attributes(attributes, check_readonly: true), **options)
286
+ end
271
287
 
272
- # private
273
- def self.lockbox_map_record_attributes(attributes, check_readonly: false)
274
- return attributes unless attributes.is_a?(Hash)
288
+ # private
289
+ # does not try to handle :returning option for simplicity
290
+ def self.lockbox_map_attributes(records, check_readonly: false)
291
+ return records unless records.is_a?(Array)
275
292
 
276
- # transform keys like Active Record
277
- attributes = attributes.transform_keys do |key|
278
- n = key.to_s
279
- attribute_aliases[n] || n
280
- end
293
+ records.map do |attributes|
294
+ lockbox_map_record_attributes(attributes, check_readonly: false)
295
+ end
296
+ end
281
297
 
282
- lockbox_attributes = self.lockbox_attributes.slice(*attributes.keys.map(&:to_sym))
283
- lockbox_attributes.each do |key, lockbox_attribute|
284
- attribute = key.to_s
285
- # check read only
286
- # users should mark both plaintext and ciphertext columns
287
- if check_readonly && readonly_attributes.include?(attribute) && !readonly_attributes.include?(lockbox_attribute[:encrypted_attribute].to_s)
288
- warn "[lockbox] WARNING: Mark attribute as readonly: #{lockbox_attribute[:encrypted_attribute]}"
289
- end
298
+ # private
299
+ def self.lockbox_map_record_attributes(attributes, check_readonly: false)
300
+ return attributes unless attributes.is_a?(Hash)
290
301
 
291
- message = attributes[attribute]
292
- attributes.delete(attribute) unless lockbox_attribute[:migrating]
293
- encrypted_attribute = lockbox_attribute[:encrypted_attribute]
294
- ciphertext = send("generate_#{encrypted_attribute}", message)
295
- attributes[encrypted_attribute] = ciphertext
302
+ # transform keys like Active Record
303
+ attributes = attributes.transform_keys do |key|
304
+ n = key.to_s
305
+ attribute_aliases[n] || n
306
+ end
307
+
308
+ lockbox_attributes = self.lockbox_attributes.slice(*attributes.keys.map(&:to_sym))
309
+ lockbox_attributes.each do |key, lockbox_attribute|
310
+ attribute = key.to_s
311
+ # check read only
312
+ # users should mark both plaintext and ciphertext columns
313
+ if check_readonly && readonly_attributes.include?(attribute) && !readonly_attributes.include?(lockbox_attribute[:encrypted_attribute].to_s)
314
+ warn "[lockbox] WARNING: Mark attribute as readonly: #{lockbox_attribute[:encrypted_attribute]}"
296
315
  end
297
316
 
298
- attributes
317
+ message = attributes[attribute]
318
+ attributes.delete(attribute) unless lockbox_attribute[:migrating]
319
+ encrypted_attribute = lockbox_attribute[:encrypted_attribute]
320
+ ciphertext = send("generate_#{encrypted_attribute}", message)
321
+ attributes[encrypted_attribute] = ciphertext
299
322
  end
323
+
324
+ attributes
300
325
  end
301
326
  else
302
327
  def reload
@@ -327,13 +352,8 @@ module Lockbox
327
352
  elsif attributes_to_define_after_schema_loads.key?(name.to_s)
328
353
  opt = attributes_to_define_after_schema_loads[name.to_s][1]
329
354
 
330
- has_default =
331
- if ActiveRecord::VERSION::MAJOR >= 7
332
- # not ideal, since NO_DEFAULT_PROVIDED is private
333
- opt != ActiveRecord::Attributes::ClassMethods.const_get(:NO_DEFAULT_PROVIDED)
334
- else
335
- opt.is_a?(Hash) && opt.key?(:default)
336
- end
355
+ # not ideal, since NO_DEFAULT_PROVIDED is private
356
+ has_default = opt != ActiveRecord::Attributes::ClassMethods.const_get(:NO_DEFAULT_PROVIDED)
337
357
 
338
358
  if has_default
339
359
  warn "[lockbox] WARNING: attributes with `:default` option are not supported. Use `after_initialize` instead."
@@ -408,21 +428,14 @@ module Lockbox
408
428
  else
409
429
  attribute name, :string
410
430
  end
411
- else
431
+ elsif attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
412
432
  # hack for Active Record 6.1+ to set string type after serialize
413
433
  # otherwise, type gets set to ActiveModel::Type::Value
414
434
  # which always returns false for changed_in_place?
415
435
  # earlier versions of Active Record take the previous code path
416
- if ActiveRecord::VERSION::STRING.to_f >= 7.0 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
417
- attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call(nil)
418
- if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
419
- attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
420
- end
421
- elsif ActiveRecord::VERSION::STRING.to_f >= 6.1 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
422
- attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call
423
- if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
424
- attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
425
- end
436
+ attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call(nil)
437
+ if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
438
+ attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
426
439
  end
427
440
  end
428
441
 
@@ -581,7 +594,6 @@ module Lockbox
581
594
  case options[:type]
582
595
  when :boolean
583
596
  message = ActiveRecord::Type::Boolean.new.serialize(message)
584
- message = nil if message == "" # for Active Record < 5.2
585
597
  message = message ? "t" : "f" unless message.nil?
586
598
  when :date
587
599
  message = ActiveRecord::Type::Date.new.serialize(message)
@@ -589,7 +601,6 @@ module Lockbox
589
601
  message = message.strftime("%Y-%m-%d") unless message.nil?
590
602
  when :datetime
591
603
  message = ActiveRecord::Type::DateTime.new.serialize(message)
592
- message = nil unless message.respond_to?(:iso8601) # for Active Record < 5.2
593
604
  message = message.iso8601(9) unless message.nil?
594
605
  when :time
595
606
  message = ActiveRecord::Type::Time.new.serialize(message)
@@ -606,14 +617,7 @@ module Lockbox
606
617
  # double precision, big endian
607
618
  message = [message].pack("G") unless message.nil?
608
619
  when :decimal
609
- message =
610
- if ActiveRecord::VERSION::MAJOR >= 6
611
- ActiveRecord::Type::Decimal.new.serialize(message)
612
- else
613
- # issue with serialize in Active Record < 6
614
- # https://github.com/rails/rails/commit/a741208f80dd33420a56486bd9ed2b0b9862234a
615
- ActiveRecord::Type::Decimal.new.cast(message)
616
- end
620
+ message = ActiveRecord::Type::Decimal.new.serialize(message)
617
621
  # Postgres stores 4 decimal digits in 2 bytes
618
622
  # plus 3 to 8 bytes of overhead
619
623
  # but use string for simplicity
@@ -716,12 +720,6 @@ module Lockbox
716
720
  end
717
721
  end
718
722
 
719
- def lockbox_encrypts(*attributes, **options)
720
- deprecator = ActiveSupport::VERSION::STRING.to_f >= 7.2 ? ActiveSupport.deprecator : ActiveSupport::Deprecation
721
- deprecator.warn("`#{__callee__}` is deprecated in favor of `has_encrypted`")
722
- has_encrypted(*attributes, **options)
723
- end
724
-
725
723
  module Attached
726
724
  def encrypts_attached(*attributes, **options)
727
725
  attributes.each do |name|
@@ -12,32 +12,15 @@ module Lockbox
12
12
  require "lockbox/active_storage_extensions"
13
13
 
14
14
  ActiveStorage::Attached.prepend(Lockbox::ActiveStorageExtensions::Attached)
15
- if ActiveStorage::VERSION::MAJOR >= 6
16
- ActiveStorage::Attached::Changes::CreateOne.prepend(Lockbox::ActiveStorageExtensions::CreateOne)
17
- end
15
+ ActiveStorage::Attached::Changes::CreateOne.prepend(Lockbox::ActiveStorageExtensions::CreateOne)
18
16
  ActiveStorage::Attached::One.prepend(Lockbox::ActiveStorageExtensions::AttachedOne)
19
17
  ActiveStorage::Attached::Many.prepend(Lockbox::ActiveStorageExtensions::AttachedMany)
20
18
 
21
- # use load hooks when possible
22
- if ActiveStorage::VERSION::MAJOR >= 7
23
- ActiveSupport.on_load(:active_storage_attachment) do
24
- prepend Lockbox::ActiveStorageExtensions::Attachment
25
- end
26
- ActiveSupport.on_load(:active_storage_blob) do
27
- prepend Lockbox::ActiveStorageExtensions::Blob
28
- end
29
- elsif ActiveStorage::VERSION::MAJOR >= 6
30
- ActiveSupport.on_load(:active_storage_attachment) do
31
- include Lockbox::ActiveStorageExtensions::Attachment
32
- end
33
- ActiveSupport.on_load(:active_storage_blob) do
34
- prepend Lockbox::ActiveStorageExtensions::Blob
35
- end
36
- else
37
- app.config.to_prepare do
38
- ActiveStorage::Attachment.include(Lockbox::ActiveStorageExtensions::Attachment)
39
- ActiveStorage::Blob.prepend(Lockbox::ActiveStorageExtensions::Blob)
40
- end
19
+ ActiveSupport.on_load(:active_storage_attachment) do
20
+ prepend Lockbox::ActiveStorageExtensions::Attachment
21
+ end
22
+ ActiveSupport.on_load(:active_storage_blob) do
23
+ prepend Lockbox::ActiveStorageExtensions::Blob
41
24
  end
42
25
  end
43
26
  end
@@ -1,3 +1,3 @@
1
1
  module Lockbox
2
- VERSION = "1.4.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/lockbox.rb CHANGED
@@ -99,8 +99,10 @@ end
99
99
  if defined?(ActiveSupport.on_load)
100
100
  ActiveSupport.on_load(:active_record) do
101
101
  ar_version = ActiveRecord::VERSION::STRING.to_f
102
- if ar_version < 5.2
103
- if ar_version >= 5
102
+ if ar_version < 7
103
+ if ar_version >= 5.2
104
+ raise Lockbox::Error, "Active Record #{ActiveRecord::VERSION::STRING} requires Lockbox < 2"
105
+ elsif ar_version >= 5
104
106
  raise Lockbox::Error, "Active Record #{ActiveRecord::VERSION::STRING} requires Lockbox < 0.7"
105
107
  else
106
108
  raise Lockbox::Error, "Active Record #{ActiveRecord::VERSION::STRING} not supported"
@@ -109,12 +111,19 @@ if defined?(ActiveSupport.on_load)
109
111
 
110
112
  extend Lockbox::Model
111
113
  extend Lockbox::Model::Attached
112
- singleton_class.alias_method(:encrypts, :lockbox_encrypts) if ActiveRecord::VERSION::MAJOR < 7
113
114
  ActiveRecord::Relation.prepend Lockbox::Calculations
114
115
  end
115
116
 
116
117
  ActiveSupport.on_load(:mongoid) do
118
+ mongoid_version = Mongoid::VERSION.to_i
119
+ if mongoid_version < 8
120
+ if mongoid_version >= 6
121
+ raise Lockbox::Error, "Mongoid #{Mongoid::VERSION} requires Lockbox < 2"
122
+ else
123
+ raise Lockbox::Error, "Mongoid #{Mongoid::VERSION} not supported"
124
+ end
125
+ end
126
+
117
127
  Mongoid::Document::ClassMethods.include(Lockbox::Model)
118
- Mongoid::Document::ClassMethods.alias_method(:encrypts, :lockbox_encrypts)
119
128
  end
120
129
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lockbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-10 00:00:00.000000000 Z
11
+ date: 2024-10-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: andrew@ankane.org
@@ -51,14 +51,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '2.6'
54
+ version: '3.1'
55
55
  required_rubygems_version: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
59
  version: '0'
60
60
  requirements: []
61
- rubygems_version: 3.5.11
61
+ rubygems_version: 3.5.16
62
62
  signing_key:
63
63
  specification_version: 4
64
64
  summary: Modern encryption for Ruby and Rails