From b581206a356eb10aaf8a012910977040c781794c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20Falco=CC=81n?= Date: Sat, 20 Jun 2026 12:58:06 +0200 Subject: [PATCH] fix(encryption): align stale account encrypted flags with plaintext names A handful of legacy accounts are still flagged encrypted=true while their name is stored in plaintext (name_iv is null). The client-side decrypt- migration only clears the flag for accounts with an actually-encrypted name, so these stale flags never resolve and keep the user perpetually counted as "has encrypted accounts". Backfill the flag to match reality. Transaction decryption is unaffected: it is driven by each transaction's description_iv / notes_iv, not by this account flag. --- ...ts_encrypted_flag_with_plaintext_names.php | 35 +++++++++++++++++++ ...lignAccountsEncryptedFlagMigrationTest.php | 21 +++++++++++ 2 files changed, 56 insertions(+) create mode 100644 database/migrations/2026_06_20_105609_align_accounts_encrypted_flag_with_plaintext_names.php create mode 100644 tests/Feature/AlignAccountsEncryptedFlagMigrationTest.php diff --git a/database/migrations/2026_06_20_105609_align_accounts_encrypted_flag_with_plaintext_names.php b/database/migrations/2026_06_20_105609_align_accounts_encrypted_flag_with_plaintext_names.php new file mode 100644 index 00000000..6021920b --- /dev/null +++ b/database/migrations/2026_06_20_105609_align_accounts_encrypted_flag_with_plaintext_names.php @@ -0,0 +1,35 @@ +where('encrypted', true) + ->whereNull('name_iv') + ->update(['encrypted' => false]); + } + + /** + * Irreversible: once flipped, a migration-corrected account is + * indistinguishable from an account that was always plaintext, so blanket + * re-flagging would wrongly encrypt legitimately unencrypted accounts. + */ + public function down(): void + { + // + } +}; diff --git a/tests/Feature/AlignAccountsEncryptedFlagMigrationTest.php b/tests/Feature/AlignAccountsEncryptedFlagMigrationTest.php new file mode 100644 index 00000000..70bd3566 --- /dev/null +++ b/tests/Feature/AlignAccountsEncryptedFlagMigrationTest.php @@ -0,0 +1,21 @@ +up(); +} + +it('clears the encrypted flag only for accounts whose name is plaintext', function () { + $staleFlag = Account::factory()->create(['encrypted' => true, 'name_iv' => null]); + $encryptedName = Account::factory()->create(['encrypted' => true, 'name_iv' => str_repeat('a', 16)]); + $alreadyPlaintext = Account::factory()->create(['encrypted' => false, 'name_iv' => null]); + + runAlignEncryptedFlagMigration(); + + expect($staleFlag->fresh()->encrypted)->toBeFalse() + ->and($encryptedName->fresh()->encrypted)->toBeTrue() + ->and($alreadyPlaintext->fresh()->encrypted)->toBeFalse(); +});