From 72fef38c3b3f9689d7cb85748df9c345579234a0 Mon Sep 17 00:00:00 2001 From: der_On Date: Sat, 21 Jan 2023 13:58:43 +0100 Subject: [PATCH 01/13] Adds Encryptable model behavior --- src/Database/Behaviors/Encryptable.php | 130 +++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/Database/Behaviors/Encryptable.php diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php new file mode 100644 index 000000000..61dedc134 --- /dev/null +++ b/src/Database/Behaviors/Encryptable.php @@ -0,0 +1,130 @@ +model = $parent; + $this->bootEncryptable(); + } + + /** + * Boot the encryptable trait for a model. + * @return void + */ + public function bootEncryptable() + { + $self = $this; + + if (!$this->model->methodExists('getEncryptableAttributes')) { + throw new Exception(sprintf( + 'You must define a getEncryptableAttributes method in %s to use the Encryptable trait.', + $this->model::class, + )); + } + + /* + * Encrypt required fields when necessary + */ + $this->model::extend(function ($model) use ($self) { + $encryptable = $model->getEncryptableAttributes(); + $model->bindEvent('model.beforeSetAttribute', function ($key, $value) use ($model, $encryptable, $self) { + if (in_array($key, $encryptable) && !is_null($value)) { + return $self->makeEncryptableValue($key, $value); + } + }); + $model->bindEvent('model.beforeGetAttribute', function ($key) use ($model, $encryptable, $self) { + $attributes = $model->getAttributes(); + if (in_array($key, $encryptable) && array_get($attributes, $key) != null) { + return $self->getEncryptableValue($model, $key); + } + }); + }); + } + + /** + * Encrypts an attribute value and saves it in the original locker. + * @param string $key Attribute + * @param string $value Value to encrypt + * @return string Encrypted value + */ + public function makeEncryptableValue($key, $value) + { + $this->originalEncryptableValues[$key] = $value; + return $this->getEncrypter()->encrypt($value); + } + + /** + * Decrypts an attribute value + * @param string $model Model + * @param string $key Attribute + * @return string Decrypted value + */ + public function getEncryptableValue($model, $key) + { + $attributes = $model->getAttributes(); + return isset($attributes[$key]) + ? $this->getEncrypter()->decrypt($attributes[$key]) + : null; + } + + /** + * Returns the original values of any encrypted attributes. + * @return array + */ + public function getOriginalEncryptableValues() + { + return $this->originalEncryptableValues; + } + + /** + * Returns the original values of any encrypted attributes. + * @return mixed + */ + public function getOriginalEncryptableValue($attribute) + { + return $this->originalEncryptableValues[$attribute] ?? null; + } + + /** + * Provides the encrypter instance. + * + * @return \Illuminate\Contracts\Encryption\Encrypter + */ + public function getEncrypter() + { + return (!is_null($this->encrypterInstance)) ? $this->encrypterInstance : App::make('encrypter'); + } + + /** + * Sets the encrypter instance. + * + * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter + * @return void + */ + public function setEncrypter(\Illuminate\Contracts\Encryption\Encrypter $encrypter) + { + $this->encrypterInstance = $encrypter; + } +} From 5218ea098e77ea3c31a9095e837305a3cbc3e597 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sun, 22 Jan 2023 11:34:04 -0600 Subject: [PATCH 02/13] WIP Tweaks for typehinting and inline docs --- src/Database/Behaviors/Encryptable.php | 100 +++++++++++++++---------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 61dedc134..d23af3676 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -2,26 +2,58 @@ use App; use Exception; +use Illuminate\Contracts\Encryption\Encrypter; +use Winter\Storm\Extension\ExtensionBase; -class Encryptable extends \Winter\Storm\Extension\ExtensionBase +/** + * Encryptable model behavior + * + * Usage: + * + * In the model class definition: + * + * public $implement = [ + * \Winter\Storm\Database\Behaviors\Encryptable::class, + * ]; + * + * /** + * * List of attributes to encrypt. + * * / + * protected array $encryptable = ['api_key', 'api_secret']; + * + * Dynamically attached to third party model: + * + * TargetModel::extend(function ($model) { + * $model->addDynamicProperty('encryptable', ['encrypt_this']); + * $model->extendClassWith(\Winter\Storm\Database\Behaviors\Encryptable::class); + * }); + * + * >**NOTE**: Encrypted attributes will be serialized and unserialized + * as a part of the encryption / decryption process. Do not make an + * attribute that is encryptable also jsonable at the same time as the + * jsonable process will attempt to decode a value that has already been + * unserialized by the encrypter. + * + */ +class Encryptable extends ExtensionBase { protected $model; /** - * @var array List of attribute names which should be encrypted + * List of attribute names which should be encrypted * - * protected $encryptable = []; + * protected array $encryptable = []; */ /** - * @var \Illuminate\Contracts\Encryption\Encrypter Encrypter instance. + * Encrypter instance. */ - protected $encrypterInstance; + protected Encrypter $encrypterInstance; /** - * @var array List of original attribute values before they were encrypted. + * List of original attribute values before they were encrypted. */ - protected $originalEncryptableValues = []; + protected array $originalEncryptableValues = []; public function __construct($parent) { @@ -31,11 +63,15 @@ public function __construct($parent) /** * Boot the encryptable trait for a model. - * @return void */ - public function bootEncryptable() + public function bootEncryptable(): void { - $self = $this; + if (!property_exists(get_class(), 'encryptable')) { + throw new Exception(sprintf( + 'You must define a $encryptable property in %s to use the Encryptable trait.', + get_called_class() + )); + } if (!$this->model->methodExists('getEncryptableAttributes')) { throw new Exception(sprintf( @@ -47,17 +83,16 @@ public function bootEncryptable() /* * Encrypt required fields when necessary */ - $this->model::extend(function ($model) use ($self) { + $this->model::extend(function ($model) { $encryptable = $model->getEncryptableAttributes(); - $model->bindEvent('model.beforeSetAttribute', function ($key, $value) use ($model, $encryptable, $self) { + $model->bindEvent('model.beforeSetAttribute', function ($key, $value) use ($model, $encryptable) { if (in_array($key, $encryptable) && !is_null($value)) { - return $self->makeEncryptableValue($key, $value); + return $model->makeEncryptableValue($key, $value); } }); - $model->bindEvent('model.beforeGetAttribute', function ($key) use ($model, $encryptable, $self) { - $attributes = $model->getAttributes(); - if (in_array($key, $encryptable) && array_get($attributes, $key) != null) { - return $self->getEncryptableValue($model, $key); + $model->bindEvent('model.beforeGetAttribute', function ($key) use ($model, $encryptable) { + if (in_array($key, $encryptable) && array_get($model->getAttributes(), $key) != null) { + return $model->getEncryptableValue($key); } }); }); @@ -65,65 +100,52 @@ public function bootEncryptable() /** * Encrypts an attribute value and saves it in the original locker. - * @param string $key Attribute - * @param string $value Value to encrypt - * @return string Encrypted value */ - public function makeEncryptableValue($key, $value) + public function makeEncryptableValue(string $key, mixed $value): string { $this->originalEncryptableValues[$key] = $value; - return $this->getEncrypter()->encrypt($value); + return $this->model->getEncrypter()->encrypt($value); } /** * Decrypts an attribute value - * @param string $model Model - * @param string $key Attribute - * @return string Decrypted value */ - public function getEncryptableValue($model, $key) + public function getEncryptableValue(string $key): ?mixed { - $attributes = $model->getAttributes(); + $attributes = $this->model->getAttributes(); return isset($attributes[$key]) - ? $this->getEncrypter()->decrypt($attributes[$key]) + ? $this->model->getEncrypter()->decrypt($attributes[$key]) : null; } /** * Returns the original values of any encrypted attributes. - * @return array */ - public function getOriginalEncryptableValues() + public function getOriginalEncryptableValues(): array { return $this->originalEncryptableValues; } /** * Returns the original values of any encrypted attributes. - * @return mixed */ - public function getOriginalEncryptableValue($attribute) + public function getOriginalEncryptableValue(string $attribute): ?mixed { return $this->originalEncryptableValues[$attribute] ?? null; } /** * Provides the encrypter instance. - * - * @return \Illuminate\Contracts\Encryption\Encrypter */ - public function getEncrypter() + public function getEncrypter(): Encrypter { return (!is_null($this->encrypterInstance)) ? $this->encrypterInstance : App::make('encrypter'); } /** * Sets the encrypter instance. - * - * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter - * @return void */ - public function setEncrypter(\Illuminate\Contracts\Encryption\Encrypter $encrypter) + public function setEncrypter(Encrypter $encrypter): void { $this->encrypterInstance = $encrypter; } From b6ddc46ac44c0e716ace3780a97dc16ad07287ae Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sun, 22 Jan 2023 13:00:13 -0600 Subject: [PATCH 03/13] Update Encryptable.php --- src/Database/Behaviors/Encryptable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index d23af3676..e67f91761 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -29,7 +29,7 @@ * }); * * >**NOTE**: Encrypted attributes will be serialized and unserialized - * as a part of the encryption / decryption process. Do not make an + * as a part of the encryption / decryption process. Do not make an * attribute that is encryptable also jsonable at the same time as the * jsonable process will attempt to decode a value that has already been * unserialized by the encrypter. From 5d9baee9ed8090ccadd72d3e5d30569b273fd5ba Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sun, 22 Jan 2023 13:04:21 -0600 Subject: [PATCH 04/13] Update Encryptable.php --- src/Database/Behaviors/Encryptable.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index e67f91761..8fa3cfe81 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -48,7 +48,7 @@ class Encryptable extends ExtensionBase /** * Encrypter instance. */ - protected Encrypter $encrypterInstance; + protected ?Encrypter $encrypterInstance = null; /** * List of original attribute values before they were encrypted. @@ -66,17 +66,10 @@ public function __construct($parent) */ public function bootEncryptable(): void { - if (!property_exists(get_class(), 'encryptable')) { + if (!$this->model->propertyExists('encryptable')) { throw new Exception(sprintf( - 'You must define a $encryptable property in %s to use the Encryptable trait.', - get_called_class() - )); - } - - if (!$this->model->methodExists('getEncryptableAttributes')) { - throw new Exception(sprintf( - 'You must define a getEncryptableAttributes method in %s to use the Encryptable trait.', - $this->model::class, + 'You must define an $encryptable property on the %s class to use the Encryptable behavior.', + get_class($model) )); } From d032637b9d8cb8c8d67a0cd5ed784e29cb6a52b8 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Mon, 23 Jan 2023 09:29:29 +0800 Subject: [PATCH 05/13] Add encryptable behavior test, apply fixes to make it work --- src/Database/Behaviors/Encryptable.php | 35 +++++---- .../Behaviors/EncryptableBehaviorTest.php | 71 +++++++++++++++++++ 2 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 tests/Database/Behaviors/EncryptableBehaviorTest.php diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 8fa3cfe81..8fe113c10 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -69,25 +69,22 @@ public function bootEncryptable(): void if (!$this->model->propertyExists('encryptable')) { throw new Exception(sprintf( 'You must define an $encryptable property on the %s class to use the Encryptable behavior.', - get_class($model) + get_class($this->model) )); } /* * Encrypt required fields when necessary */ - $this->model::extend(function ($model) { - $encryptable = $model->getEncryptableAttributes(); - $model->bindEvent('model.beforeSetAttribute', function ($key, $value) use ($model, $encryptable) { - if (in_array($key, $encryptable) && !is_null($value)) { - return $model->makeEncryptableValue($key, $value); - } - }); - $model->bindEvent('model.beforeGetAttribute', function ($key) use ($model, $encryptable) { - if (in_array($key, $encryptable) && array_get($model->getAttributes(), $key) != null) { - return $model->getEncryptableValue($key); - } - }); + $this->model->bindEvent('model.beforeSetAttribute', function ($key, $value) { + if (in_array($key, $this->model->getEncryptableAttributes()) && !is_null($value)) { + return $this->model->makeEncryptableValue($key, $value); + } + }); + $this->model->bindEvent('model.beforeGetAttribute', function ($key) { + if (in_array($key, $this->model->getEncryptableAttributes()) && array_get($this->model->getAttributes(), $key) != null) { + return $this->model->getEncryptableValue($key); + } }); } @@ -103,7 +100,7 @@ public function makeEncryptableValue(string $key, mixed $value): string /** * Decrypts an attribute value */ - public function getEncryptableValue(string $key): ?mixed + public function getEncryptableValue(string $key): mixed { $attributes = $this->model->getAttributes(); return isset($attributes[$key]) @@ -111,6 +108,14 @@ public function getEncryptableValue(string $key): ?mixed : null; } + /** + * Returns a collection of fields that will be encrypted. + */ + public function getEncryptableAttributes(): array + { + return $this->model->encryptable; + } + /** * Returns the original values of any encrypted attributes. */ @@ -122,7 +127,7 @@ public function getOriginalEncryptableValues(): array /** * Returns the original values of any encrypted attributes. */ - public function getOriginalEncryptableValue(string $attribute): ?mixed + public function getOriginalEncryptableValue(string $attribute): mixed { return $this->originalEncryptableValues[$attribute] ?? null; } diff --git a/tests/Database/Behaviors/EncryptableBehaviorTest.php b/tests/Database/Behaviors/EncryptableBehaviorTest.php new file mode 100644 index 000000000..812808037 --- /dev/null +++ b/tests/Database/Behaviors/EncryptableBehaviorTest.php @@ -0,0 +1,71 @@ +createTable(); + + $this->encrypter = new Encrypter(self::TEST_CRYPT_KEY, 'AES-128-CBC'); + } + + public function testEncryptableBehavior() + { + $testModel = new TestModelEncryptableBehavior(); + $testModel->setEncrypter($this->encrypter); + + $testModel->fill(['secret' => 'test']); + $this->assertEquals('test', $testModel->secret); + $this->assertNotEquals('test', $testModel->attributes['secret']); + $payloadOne = json_decode(base64_decode($testModel->attributes['secret']), true); + $this->assertEquals(['iv', 'value', 'mac', 'tag'], array_keys($payloadOne)); + + $testModel->secret = ''; + $this->assertEquals('', $testModel->secret); + $this->assertNotEquals('', $testModel->attributes['secret']); + $payloadTwo = json_decode(base64_decode($testModel->attributes['secret']), true); + $this->assertEquals(['iv', 'value', 'mac', 'tag'], array_keys($payloadTwo)); + $this->assertNotEquals($payloadOne['value'], $payloadTwo['value']); + + $testModel->secret = 0; + $this->assertEquals(0, $testModel->secret); + $this->assertNotEquals(0, $testModel->attributes['secret']); + $payloadThree = json_decode(base64_decode($testModel->attributes['secret']), true); + $this->assertEquals(['iv', 'value', 'mac', 'tag'], array_keys($payloadThree)); + $this->assertNotEquals($payloadTwo['value'], $payloadThree['value']); + + $testModel->secret = null; + $this->assertNull($testModel->secret); + $this->assertNull($testModel->attributes['secret']); + } + + protected function createTable() + { + $this->getBuilder()->create('secrets', function ($table) { + $table->increments('id'); + $table->string('secret'); + $table->timestamps(); + }); + } +} + +class TestModelEncryptableBehavior extends \Winter\Storm\Database\Model +{ + public $implement = [ + \Winter\Storm\Database\Behaviors\Encryptable::class, + ]; + + public $encryptable = ['secret']; + protected $fillable = ['secret']; + protected $table = 'secrets'; +} From 108e471fda8637684be20396d16d8d30f4420195 Mon Sep 17 00:00:00 2001 From: der_On Date: Mon, 11 Sep 2023 17:05:33 +0200 Subject: [PATCH 06/13] calls behavior methods directly within itself, not using the model --- src/Database/Behaviors/Encryptable.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 8fe113c10..ee0c85d4f 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -77,13 +77,13 @@ public function bootEncryptable(): void * Encrypt required fields when necessary */ $this->model->bindEvent('model.beforeSetAttribute', function ($key, $value) { - if (in_array($key, $this->model->getEncryptableAttributes()) && !is_null($value)) { - return $this->model->makeEncryptableValue($key, $value); + if (in_array($key, $this->getEncryptableAttributes()) && !is_null($value)) { + return $this->makeEncryptableValue($key, $value); } }); $this->model->bindEvent('model.beforeGetAttribute', function ($key) { - if (in_array($key, $this->model->getEncryptableAttributes()) && array_get($this->model->getAttributes(), $key) != null) { - return $this->model->getEncryptableValue($key); + if (in_array($key, $this->getEncryptableAttributes()) && array_get($this->model->getAttributes(), $key) != null) { + return $this->getEncryptableValue($key); } }); } @@ -94,7 +94,7 @@ public function bootEncryptable(): void public function makeEncryptableValue(string $key, mixed $value): string { $this->originalEncryptableValues[$key] = $value; - return $this->model->getEncrypter()->encrypt($value); + return $this->getEncrypter()->encrypt($value); } /** @@ -104,7 +104,7 @@ public function getEncryptableValue(string $key): mixed { $attributes = $this->model->getAttributes(); return isset($attributes[$key]) - ? $this->model->getEncrypter()->decrypt($attributes[$key]) + ? $this->getEncrypter()->decrypt($attributes[$key]) : null; } From 5c6505822571cc735fa1425f4efc956bce9371d3 Mon Sep 17 00:00:00 2001 From: der_On Date: Mon, 11 Sep 2023 19:52:53 +0200 Subject: [PATCH 07/13] Encryptable Behavior: Uses closures to get protected encryptable Attributes --- src/Database/Behaviors/Encryptable.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index ee0c85d4f..c262a5102 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -66,7 +66,11 @@ public function __construct($parent) */ public function bootEncryptable(): void { - if (!$this->model->propertyExists('encryptable')) { + $isEncryptable = $this->model->extend(function () { + return $this->propertyExists('encryptable'); + }); + + if (!$isEncryptable) { throw new Exception(sprintf( 'You must define an $encryptable property on the %s class to use the Encryptable behavior.', get_class($this->model) @@ -113,7 +117,9 @@ public function getEncryptableValue(string $key): mixed */ public function getEncryptableAttributes(): array { - return $this->model->encryptable; + return $this->model->extend(function () { + return $this->encryptable; + }); } /** From 5b6400bcf89e937e818d5f037b09ae79feb4953f Mon Sep 17 00:00:00 2001 From: der_On Date: Mon, 11 Sep 2023 19:53:48 +0200 Subject: [PATCH 08/13] Encryptable Behavior: Adjusts test to use protected array of encryptable attributes --- tests/Database/Behaviors/EncryptableBehaviorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Database/Behaviors/EncryptableBehaviorTest.php b/tests/Database/Behaviors/EncryptableBehaviorTest.php index 812808037..54dfd4a86 100644 --- a/tests/Database/Behaviors/EncryptableBehaviorTest.php +++ b/tests/Database/Behaviors/EncryptableBehaviorTest.php @@ -65,7 +65,7 @@ class TestModelEncryptableBehavior extends \Winter\Storm\Database\Model \Winter\Storm\Database\Behaviors\Encryptable::class, ]; - public $encryptable = ['secret']; + protected $encryptable = ['secret']; protected $fillable = ['secret']; protected $table = 'secrets'; } From 7571b781f8cfe5769350e826592f60ac98c3e5a3 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Wed, 13 Sep 2023 10:21:12 +0800 Subject: [PATCH 09/13] Fix PHPStan errors --- src/Database/Behaviors/Encryptable.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index c262a5102..3500ed987 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -3,6 +3,7 @@ use App; use Exception; use Illuminate\Contracts\Encryption\Encrypter; +use Winter\Storm\Database\Model; use Winter\Storm\Extension\ExtensionBase; /** @@ -37,7 +38,7 @@ */ class Encryptable extends ExtensionBase { - protected $model; + protected Model $model; /** * List of attribute names which should be encrypted @@ -67,9 +68,10 @@ public function __construct($parent) public function bootEncryptable(): void { $isEncryptable = $this->model->extend(function () { + /** @var Model $this */ return $this->propertyExists('encryptable'); }); - + if (!$isEncryptable) { throw new Exception(sprintf( 'You must define an $encryptable property on the %s class to use the Encryptable behavior.', @@ -118,7 +120,7 @@ public function getEncryptableValue(string $key): mixed public function getEncryptableAttributes(): array { return $this->model->extend(function () { - return $this->encryptable; + return $this->encryptable ?? []; }); } From 34e8f95e7551da7c7be8c63990f133e283203a1e Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Wed, 13 Sep 2023 10:33:09 +0800 Subject: [PATCH 10/13] Change implied signature of Model::extend() --- src/Database/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Model.php b/src/Database/Model.php index 073566e0c..7e436569c 100644 --- a/src/Database/Model.php +++ b/src/Database/Model.php @@ -19,7 +19,7 @@ * @author Alexey Bobkov, Samuel Georges * * @phpstan-property \Illuminate\Contracts\Events\Dispatcher|null $dispatcher - * @method static void extend(callable $callback, bool $scoped = false, ?object $outerScope = null) + * @method static mixed extend(callable $callback, bool $scoped = false, ?object $outerScope = null) */ class Model extends EloquentModel implements ModelInterface { From 38f53a10b30184e782dffca332df173cf79ec55b Mon Sep 17 00:00:00 2001 From: der_On Date: Wed, 13 Sep 2023 21:36:41 +0200 Subject: [PATCH 11/13] mostly cosmetic adjustments to EncryptableBehavior --- src/Database/Behaviors/Encryptable.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 3500ed987..6414f1713 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -1,7 +1,7 @@ model) )); @@ -88,7 +88,7 @@ public function bootEncryptable(): void } }); $this->model->bindEvent('model.beforeGetAttribute', function ($key) { - if (in_array($key, $this->getEncryptableAttributes()) && array_get($this->model->getAttributes(), $key) != null) { + if (in_array($key, $this->getEncryptableAttributes()) && array_get($this->model->attributes, $key) != null) { return $this->getEncryptableValue($key); } }); @@ -137,7 +137,7 @@ public function getOriginalEncryptableValues(): array */ public function getOriginalEncryptableValue(string $attribute): mixed { - return $this->originalEncryptableValues[$attribute] ?? null; + return array_get($this->originalEncryptableValues, $attribute, null); } /** From 795496860633c46e83f63aad5fe36eb42cacb24f Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 13 Sep 2023 15:51:36 -0400 Subject: [PATCH 12/13] need full path in storm --- src/Database/Behaviors/Encryptable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 6414f1713..6cd5560b5 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -1,7 +1,7 @@ Date: Wed, 13 Sep 2023 15:59:39 -0400 Subject: [PATCH 13/13] reorder dependencies --- src/Database/Behaviors/Encryptable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Behaviors/Encryptable.php b/src/Database/Behaviors/Encryptable.php index 6cd5560b5..9f525a234 100644 --- a/src/Database/Behaviors/Encryptable.php +++ b/src/Database/Behaviors/Encryptable.php @@ -1,9 +1,9 @@