refactor(db): drop cleartext template refs, fix ghost columns + fresh-DB schema
Migration verified (0 unmigrated cleartext templates across both accounts) before contracting: - GET/POST/PUT/bulk no longer read or write the cleartext template column (only template_enc/iv); the PUT partial-update gate stays keyed on the 'template' JSON key presence. - Removed AddColumnIfMissing for template AND tags/title — those two had silently re-added the dropped columns as empty ghosts at every start. - CREATE TABLE: removed site/username NOT NULL cleartext columns — a FRESH database rejected the very first INSERT (which no longer ships them). User can now DROP COLUMN template (and re-drop the ghost tags/title). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -164,8 +164,9 @@ begin
|
||||
'CREATE TABLE IF NOT EXISTS vault_entries (' +
|
||||
' id INTEGER PRIMARY KEY AUTOINCREMENT,' +
|
||||
' user_id INTEGER NOT NULL,' +
|
||||
' site TEXT NOT NULL,' +
|
||||
' username TEXT NOT NULL,' +
|
||||
// site/username cleartext columns are gone (§1.3 metadata-at-rest —
|
||||
// only site_enc/username_enc below). Keeping them NOT NULL here made a
|
||||
// FRESH database reject the very first INSERT (which no longer ships them).
|
||||
' encrypted_password TEXT NOT NULL,' +
|
||||
' iv TEXT NOT NULL,' +
|
||||
' encryption_method TEXT DEFAULT ''server'',' +
|
||||
@@ -329,13 +330,10 @@ begin
|
||||
AddColumnIfMissing('vault_entries', 'deleted', 'INTEGER DEFAULT 0');
|
||||
AddColumnIfMissing('vault_entries', 'deleted_at', 'DATETIME');
|
||||
AddColumnIfMissing('vault_entries', 'favorite', 'INTEGER DEFAULT 0');
|
||||
// UI V2: tags stored as comma-separated TEXT (e.g. "work,important,2fa").
|
||||
// Simple format, search via LIKE %tag%. Frontend handles parsing/joining.
|
||||
AddColumnIfMissing('vault_entries', 'tags', 'TEXT DEFAULT ''''');
|
||||
// Optional human-friendly display name. When empty, the UI falls back
|
||||
// to `site`. Lets the user store the raw URL/host (used for autofill
|
||||
// domain matching) while showing something nicer on cards/slideovers.
|
||||
AddColumnIfMissing('vault_entries', 'title', 'TEXT DEFAULT ''''');
|
||||
// NOTE (§1.3 contraction): the cleartext `tags` / `title` / `template`
|
||||
// AddColumnIfMissing lines were REMOVED — those columns were dropped after
|
||||
// the metadata-at-rest migration, and keeping the lines here silently
|
||||
// re-added empty ghost columns at every start. Only *_enc/_iv survive.
|
||||
// TOTP (2FA) — RFC 6238. Secret + IV are AES-GCM ciphertext / IV pair
|
||||
// encrypted client-side with the user's master-derived key, exactly like
|
||||
// encrypted_password. The server treats them as opaque blobs and never
|
||||
@@ -393,11 +391,8 @@ begin
|
||||
// Pinned entries float to the top of every view, regardless of sort.
|
||||
// Independent from favorite (which is a filter, not a sort override).
|
||||
AddColumnIfMissing('vault_entries', 'pinned', 'INTEGER DEFAULT 0');
|
||||
// Template identifier: empty/NULL = generic login or note; otherwise a
|
||||
// string like 'credit-card', 'ssh-key', 'server', 'recovery-codes'.
|
||||
// Drives the card/table label so notes-with-fields read as "Credit card"
|
||||
// instead of the generic "Encrypted note" placeholder.
|
||||
AddColumnIfMissing('vault_entries', 'template', 'TEXT');
|
||||
// Template identifier lives encrypted in template_enc/iv (see above) —
|
||||
// its cleartext column was dropped post-migration, line removed here.
|
||||
// Stable identity that survives export/import + cross-device sync.
|
||||
// SQLite `id` is autoincrement local-only — useless to match the same
|
||||
// logical entry across two installs. Populate existing rows with a
|
||||
|
||||
Reference in New Issue
Block a user