@@ -391,6 +391,98 @@ public function testDecryptionWorksForRelationshipLoadedModels()
391391 $ this ->assertEquals ('123 Main Street ' , $ array ['street_1 ' ]);
392392 $ this ->assertEquals ('Apt 4B ' , $ array ['street_2 ' ]);
393393 }
394+
395+ public function testDoubleEncryptionDecryption ()
396+ {
397+ // Create a test table
398+ $ this ->app ['db ' ]->connection ()->getSchemaBuilder ()->create ('test_models ' , function ($ table ) {
399+ $ table ->increments ('id ' );
400+ $ table ->text ('address ' )->nullable ();
401+ $ table ->timestamps ();
402+ });
403+
404+ $ encryptionService = $ this ->app ->make (EncryptionService::class);
405+
406+ // Use reflection to access compact encryption
407+ $ reflection = new \ReflectionClass ($ encryptionService );
408+ $ compactEncryptMethod = $ reflection ->getMethod ('compactEncrypt ' );
409+ $ compactEncryptMethod ->setAccessible (true );
410+
411+ // Create a double-encrypted scenario:
412+ // 1. First encrypt with Laravel standard encryption
413+ // 2. Then encrypt that result with compact encryption
414+ $ originalValue = '123 Main Street ' ;
415+ $ firstEncryption = $ encryptionService ->encrypt ($ originalValue ); // Laravel standard
416+ $ doubleEncrypted = $ compactEncryptMethod ->invokeArgs ($ encryptionService , [$ firstEncryption ]); // Compact of encrypted
417+
418+ // Manually insert into database with double encryption
419+ $ id = $ this ->app ['db ' ]->connection ()->table ('test_models ' )->insertGetId ([
420+ 'address ' => $ doubleEncrypted ,
421+ 'created_at ' => now (),
422+ 'updated_at ' => now (),
423+ ]);
424+
425+ // Retrieve using Eloquent - this should handle double decryption
426+ $ model = TestEncryptableModel::find ($ id );
427+
428+ // Check that the value is properly decrypted (should handle double encryption)
429+ $ this ->assertEquals ($ originalValue , $ model ->address );
430+
431+ // Verify the raw database value is the double encrypted value
432+ $ rawData = $ this ->app ['db ' ]->connection ()->table ('test_models ' )->where ('id ' , $ id )->first ();
433+ $ this ->assertTrue (strpos ($ rawData ->address , 'c: ' ) === 0 );
434+ $ this ->assertNotEquals ($ originalValue , $ rawData ->address );
435+ }
436+
437+ public function testSingleEncryptionOnSaveOnly ()
438+ {
439+ // Create a test table
440+ $ this ->app ['db ' ]->connection ()->getSchemaBuilder ()->create ('test_models ' , function ($ table ) {
441+ $ table ->increments ('id ' );
442+ $ table ->text ('email ' )->nullable ();
443+ $ table ->text ('phone ' )->nullable ();
444+ $ table ->timestamps ();
445+ });
446+
447+ // Create a new model
448+ $ model = new TestEncryptableModel ();
449+
450+ // Set values - these should NOT be encrypted yet
451+ $ model->
email =
'[email protected] ' ;
452+ $ model ->phone = '123-456-7890 ' ;
453+
454+ // Check that the values are still plain text before save
455+ $ this ->
assertEquals (
'[email protected] ' ,
$ model->
email );
456+ $ this ->assertEquals ('123-456-7890 ' , $ model ->phone );
457+
458+ // Check the raw attributes are also plain text
459+ $ this ->
assertEquals (
'[email protected] ' ,
$ model->
getAttributes ()[
'email ' ]);
460+ $ this ->assertEquals ('123-456-7890 ' , $ model ->getAttributes ()['phone ' ]);
461+
462+ // Now save the model - this should encrypt the values
463+ $ model ->save ();
464+
465+ // After save, when accessed, they should still return the original values
466+ $ this ->
assertEquals (
'[email protected] ' ,
$ model->
email );
467+ $ this ->assertEquals ('123-456-7890 ' , $ model ->phone );
468+
469+ // But the raw database should be encrypted
470+ $ rawData = $ this ->app ['db ' ]->connection ()->table ('test_models ' )->where ('id ' , $ model ->id )->first ();
471+ $ this ->
assertNotEquals (
'[email protected] ' ,
$ rawData->
email );
472+ $ this ->assertNotEquals ('123-456-7890 ' , $ rawData ->phone );
473+
474+ // And they should be detectable as encrypted
475+ $ reflection = new \ReflectionClass ($ model );
476+ $ method = $ reflection ->getMethod ('isValueEncrypted ' );
477+ $ method ->setAccessible (true );
478+ $ this ->assertTrue ($ method ->invokeArgs ($ model , [$ rawData ->email ]));
479+ $ this ->assertTrue ($ method ->invokeArgs ($ model , [$ rawData ->phone ]));
480+
481+ // Retrieve a fresh instance and verify decryption works
482+ $ freshModel = TestEncryptableModel::find ($ model ->id );
483+ $ this ->
assertEquals (
'[email protected] ' ,
$ freshModel->
email );
484+ $ this ->assertEquals ('123-456-7890 ' , $ freshModel ->phone );
485+ }
394486}
395487
396488class TestEncryptableModel extends Model
0 commit comments