Actually delete legacy incoming media on explicit delete and /clear

Explicit deletion of LEGACY (non-stable-ID) incoming media left the
decrypted payload on disk indefinitely, waiting for 100MB oldest-first
quota cleanup. Restore real deletion safely with the machinery this PR
built: BLEIncomingFileStore.removeLegacyIncomingFile unlinks under the
payload-coordination lock only when the path is not pending delivery,
not held by a deletion reservation, and not owned by a stable receipt
or journal entry; otherwise the file keeps the leave-for-quota
fallback. The view model routes per-bubble deletes and /clear through
the gated unlink once no bubble in any conversation references the
basename.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jack
2026-07-26 14:15:38 +02:00
co-authored by Claude Opus 4.8
parent c030e38420
commit d2e5afd6e7
8 changed files with 350 additions and 55 deletions
+12
View File
@@ -255,6 +255,18 @@ final class MockTransport: Transport, PrivateMediaDeletionPersisting {
completion(result ?? persistDeletedPrivateMediaResult)
}
/// Real store instance so view-model tests exercise the gated legacy
/// unlink end to end (same Application Support tree the tests write to).
let legacyIncomingFileStore = BLEIncomingFileStore()
private(set) var removedLegacyPrivateMediaPaths: [String] = []
func removeLegacyPrivateMediaPayload(relativePath: String) {
removedLegacyPrivateMediaPaths.append(relativePath)
legacyIncomingFileStore.removeLegacyIncomingFile(
relativePath: relativePath
)
}
func sendVerifyChallenge(to peerID: PeerID, noiseKeyHex: String, nonceA: Data) {
sentVerifyChallenges.append((peerID, noiseKeyHex, nonceA))
}