fix(db): enable SQLite foreign_keys explicitly (audit 6c-9)

SQLite defaults foreign_keys OFF per connection, and the schema relies on
ON DELETE CASCADE (entry_attachments, entries_password_history, recovery_keys).
FireDAC is said to default it On but that's undocumented here — set
ForeignKeys=On so a permanent delete never orphans encrypted blobs. Correct
in both cases (no-op if already On). Base check before fix: 0 orphans.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-20 05:33:46 +01:00
parent 19b66b7bbd
commit 2e7aebf651
2 changed files with 13 additions and 0 deletions
+7
View File
@@ -896,6 +896,13 @@ TJSONHelper.SendJSON(AResponse, LArr); // libère LArr (AOwnsObj=True)
### 6c-9. ❓ `PRAGMA foreign_keys` — à vérifier, non tranché ### 6c-9. ❓ `PRAGMA foreign_keys` — à vérifier, non tranché
> ✅ **RÉSOLU 2026-07-16.** `FConn.Params.Values['ForeignKeys'] := 'On'` ajouté
> à la config de connexion FireDAC ([PM.Database.pas](delphi-backend/Source/PM.Database.pas)).
> Correct dans les deux cas (no-op si c'était déjà le défaut). **Vérif base
> avant fix : 0 attachment / 0 history orphelin** — soit le défaut FireDAC était
> déjà On, soit aucun delete-permanent-avec-attachments n'a encore eu lieu ;
> l'explicite lève le doute pour de bon.
`PRAGMA foreign_keys` n'est défini **nulle part**. Le schéma s'appuie pourtant sur `PRAGMA foreign_keys` n'est défini **nulle part**. Le schéma s'appuie pourtant sur
`ON DELETE CASCADE` : [Entries.pas:704](delphi-backend/Handlers/PM.Handler.Entries.pas:704) `ON DELETE CASCADE` : [Entries.pas:704](delphi-backend/Handlers/PM.Handler.Entries.pas:704)
(delete permanent) ne nettoie **ni** `entry_attachments` **ni** (delete permanent) ne nettoie **ni** `entry_attachments` **ni**
+6
View File
@@ -83,6 +83,12 @@ begin
FConn.Params.Values['Synchronous'] := 'Normal'; FConn.Params.Values['Synchronous'] := 'Normal';
FConn.Params.Values['BusyTimeout'] := '5000'; FConn.Params.Values['BusyTimeout'] := '5000';
FConn.Params.Values['JournalMode'] := 'WAL'; FConn.Params.Values['JournalMode'] := 'WAL';
// Explicit ON: SQLite defaults foreign_keys OFF per-connection, and the
// schema relies on ON DELETE CASCADE (entry_attachments, entries_password_
// history, recovery_keys on user/entry delete). FireDAC is *said* to default
// this On but it's undocumented for us — set it so a permanent delete never
// leaves orphaned encrypted blobs. No-op if it was already On (§6c-9).
FConn.Params.Values['ForeignKeys'] := 'On';
FConn.Open; FConn.Open;
CreateSchema; CreateSchema;
ApplyMigrations; ApplyMigrations;