refactor(db): drop cleartext title/tags column refs (columns removed)
User dropped the title + tags cleartext columns too — all four searchable metadata columns are now gone. Removed their refs from GET emission and the POST/PUT/bulk INSERT/UPDATE (columns + params + binds). Only *_enc columns remain; the client reads everything via decryptEntryMeta. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -118,9 +118,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
LObj := TJSONObject.Create;
|
LObj := TJSONObject.Create;
|
||||||
LObj.AddPair('id', TJSONNumber.Create(LQ.FieldByName('id').AsInteger));
|
LObj.AddPair('id', TJSONNumber.Create(LQ.FieldByName('id').AsInteger));
|
||||||
// site + username cleartext columns were dropped — client reads them
|
// site/username/title/tags cleartext columns dropped — the client
|
||||||
// from *_enc only (decryptEntryMeta). title/tags cleartext still exist.
|
// reads them from *_enc only (decryptEntryMeta).
|
||||||
LObj.AddPair('title', LQ.FieldByName('title').AsString);
|
|
||||||
if LQ.FieldByName('username_enc').IsNull then
|
if LQ.FieldByName('username_enc').IsNull then
|
||||||
LObj.AddPair('username_enc', TJSONNull.Create)
|
LObj.AddPair('username_enc', TJSONNull.Create)
|
||||||
else
|
else
|
||||||
@@ -148,7 +147,6 @@ begin
|
|||||||
LObj.AddPair('deleted_at', ISODateTimeField(LQ.FieldByName('deleted_at')));
|
LObj.AddPair('deleted_at', ISODateTimeField(LQ.FieldByName('deleted_at')));
|
||||||
LObj.AddPair('favorite', TJSONNumber.Create(LQ.FieldByName('favorite').AsInteger));
|
LObj.AddPair('favorite', TJSONNumber.Create(LQ.FieldByName('favorite').AsInteger));
|
||||||
LObj.AddPair('pinned', TJSONNumber.Create(LQ.FieldByName('pinned').AsInteger));
|
LObj.AddPair('pinned', TJSONNumber.Create(LQ.FieldByName('pinned').AsInteger));
|
||||||
LObj.AddPair('tags', LQ.FieldByName('tags').AsString);
|
|
||||||
// TOTP fields are NULL when the entry has no 2FA configured. We emit
|
// TOTP fields are NULL when the entry has no 2FA configured. We emit
|
||||||
// JSON null instead of '' so the client can distinguish "no TOTP" from
|
// JSON null instead of '' so the client can distinguish "no TOTP" from
|
||||||
// "TOTP configured with empty ciphertext" (which shouldn't happen).
|
// "TOTP configured with empty ciphertext" (which shouldn't happen).
|
||||||
@@ -399,17 +397,16 @@ begin
|
|||||||
LQ.Connection := DB.Connection;
|
LQ.Connection := DB.Connection;
|
||||||
LQ.SQL.Text :=
|
LQ.SQL.Text :=
|
||||||
'INSERT INTO vault_entries ' +
|
'INSERT INTO vault_entries ' +
|
||||||
'(user_id, title, username_enc, username_iv, ' +
|
'(user_id, username_enc, username_iv, ' +
|
||||||
' site_enc, site_iv, title_enc, title_iv, tags_enc, tags_iv, ' +
|
' site_enc, site_iv, title_enc, title_iv, tags_enc, tags_iv, ' +
|
||||||
' encrypted_password, iv, encryption_method, ' +
|
' encrypted_password, iv, encryption_method, ' +
|
||||||
' folder, tags, totp_secret, totp_iv, kind, custom_fields, custom_fields_iv,' +
|
' folder, totp_secret, totp_iv, kind, custom_fields, custom_fields_iv,' +
|
||||||
' icon_b64, template, uuid, created_at, updated_at, password_changed_at) ' +
|
' icon_b64, template, uuid, created_at, updated_at, password_changed_at) ' +
|
||||||
'VALUES (:uid, :tt, :uenc, :uiv, :senc, :siv, :tenc, :tiv2, :genc, :giv, ' +
|
'VALUES (:uid, :uenc, :uiv, :senc, :siv, :tenc, :tiv2, :genc, :giv, ' +
|
||||||
' :e, :i, ''client'', :f, :t, :ts, :tiv, :k, ' +
|
' :e, :i, ''client'', :f, :ts, :tiv, :k, ' +
|
||||||
' :cf, :cfiv, :ic, :tpl, :uuid, :c, :c2, :c)';
|
' :cf, :cfiv, :ic, :tpl, :uuid, :c, :c2, :c)';
|
||||||
LQ.ParamByName('uid').AsInteger := LUserId;
|
LQ.ParamByName('uid').AsInteger := LUserId;
|
||||||
LQ.ParamByName('tt').AsString := LTitle;
|
// site/username/title/tags cleartext columns dropped — only *_enc written.
|
||||||
// site/username cleartext columns dropped — only *_enc are written.
|
|
||||||
BindNullable(LQ, 'uenc', LUserEnc);
|
BindNullable(LQ, 'uenc', LUserEnc);
|
||||||
BindNullable(LQ, 'uiv', LUserIv);
|
BindNullable(LQ, 'uiv', LUserIv);
|
||||||
BindNullable(LQ, 'senc', LSiteEnc);
|
BindNullable(LQ, 'senc', LSiteEnc);
|
||||||
@@ -421,7 +418,6 @@ begin
|
|||||||
LQ.ParamByName('e').AsString := LEnc;
|
LQ.ParamByName('e').AsString := LEnc;
|
||||||
LQ.ParamByName('i').AsString := LIV;
|
LQ.ParamByName('i').AsString := LIV;
|
||||||
LQ.ParamByName('f').AsString := LFolder;
|
LQ.ParamByName('f').AsString := LFolder;
|
||||||
LQ.ParamByName('t').AsString := LTags;
|
|
||||||
// FireDAC needs an explicit DataType on params that are sometimes
|
// FireDAC needs an explicit DataType on params that are sometimes
|
||||||
// assigned a string and sometimes Clear()ed to NULL — without a
|
// assigned a string and sometimes Clear()ed to NULL — without a
|
||||||
// prior typed assignment, .Clear raises "data type unknown" on
|
// prior typed assignment, .Clear raises "data type unknown" on
|
||||||
@@ -588,18 +584,18 @@ begin
|
|||||||
if LHasTemplate then LTemplateSet := ', template=:tpl';
|
if LHasTemplate then LTemplateSet := ', template=:tpl';
|
||||||
LQ.SQL.Text :=
|
LQ.SQL.Text :=
|
||||||
'UPDATE vault_entries ' +
|
'UPDATE vault_entries ' +
|
||||||
'SET title=:tt, username_enc=:uenc, username_iv=:uiv, ' +
|
'SET username_enc=:uenc, username_iv=:uiv, ' +
|
||||||
' site_enc=:senc, site_iv=:siv, title_enc=:tenc, title_iv=:tiv2, ' +
|
' site_enc=:senc, site_iv=:siv, title_enc=:tenc, title_iv=:tiv2, ' +
|
||||||
' tags_enc=:genc, tags_iv=:giv, ' +
|
' tags_enc=:genc, tags_iv=:giv, ' +
|
||||||
' encrypted_password=:e, iv=:i, ' +
|
' encrypted_password=:e, iv=:i, ' +
|
||||||
' folder=:f, tags=:t, totp_secret=:ts, totp_iv=:tiv, kind=:k, ' +
|
' folder=:f, totp_secret=:ts, totp_iv=:tiv, kind=:k, ' +
|
||||||
' custom_fields=:cf, custom_fields_iv=:cfiv, ' +
|
' custom_fields=:cf, custom_fields_iv=:cfiv, ' +
|
||||||
' updated_at=:c, ' +
|
' updated_at=:c, ' +
|
||||||
' password_changed_at = CASE WHEN encrypted_password <> :e ' +
|
' password_changed_at = CASE WHEN encrypted_password <> :e ' +
|
||||||
' THEN :c ELSE password_changed_at END' +
|
' THEN :c ELSE password_changed_at END' +
|
||||||
LTemplateSet + ' ' +
|
LTemplateSet + ' ' +
|
||||||
'WHERE id=:id AND user_id=:uid';
|
'WHERE id=:id AND user_id=:uid';
|
||||||
LQ.ParamByName('tt').AsString := LTitle;
|
// site/username/title/tags cleartext columns dropped — only *_enc written.
|
||||||
BindNullable(LQ, 'uenc', LUserEnc);
|
BindNullable(LQ, 'uenc', LUserEnc);
|
||||||
BindNullable(LQ, 'uiv', LUserIv);
|
BindNullable(LQ, 'uiv', LUserIv);
|
||||||
BindNullable(LQ, 'senc', LSiteEnc);
|
BindNullable(LQ, 'senc', LSiteEnc);
|
||||||
@@ -611,7 +607,6 @@ begin
|
|||||||
LQ.ParamByName('e').AsString := LEnc;
|
LQ.ParamByName('e').AsString := LEnc;
|
||||||
LQ.ParamByName('i').AsString := LIV;
|
LQ.ParamByName('i').AsString := LIV;
|
||||||
LQ.ParamByName('f').AsString := LFolder;
|
LQ.ParamByName('f').AsString := LFolder;
|
||||||
LQ.ParamByName('t').AsString := LTags;
|
|
||||||
// Declare TOTP param types so .Clear works on first use (FireDAC
|
// Declare TOTP param types so .Clear works on first use (FireDAC
|
||||||
// needs an inferred or explicit DataType before NULL binding).
|
// needs an inferred or explicit DataType before NULL binding).
|
||||||
LQ.ParamByName('ts').DataType := ftMemo;
|
LQ.ParamByName('ts').DataType := ftMemo;
|
||||||
@@ -1233,13 +1228,13 @@ begin
|
|||||||
'WHERE user_id = :uid AND uuid = :uuid';
|
'WHERE user_id = :uid AND uuid = :uuid';
|
||||||
LQ.SQL.Text :=
|
LQ.SQL.Text :=
|
||||||
'INSERT INTO vault_entries ' +
|
'INSERT INTO vault_entries ' +
|
||||||
'(user_id, title, username_enc, username_iv, ' +
|
'(user_id, username_enc, username_iv, ' +
|
||||||
' site_enc, site_iv, title_enc, title_iv, tags_enc, tags_iv, ' +
|
' site_enc, site_iv, title_enc, title_iv, tags_enc, tags_iv, ' +
|
||||||
' encrypted_password, iv, encryption_method, ' +
|
' encrypted_password, iv, encryption_method, ' +
|
||||||
' folder, tags, totp_secret, totp_iv, kind, custom_fields, custom_fields_iv,' +
|
' folder, totp_secret, totp_iv, kind, custom_fields, custom_fields_iv,' +
|
||||||
' icon_b64, template, uuid, created_at, updated_at) ' +
|
' icon_b64, template, uuid, created_at, updated_at) ' +
|
||||||
'VALUES (:uid, :tt, :uenc, :uiv, :senc, :siv, :tenc, :tiv2, :genc, :giv, ' +
|
'VALUES (:uid, :uenc, :uiv, :senc, :siv, :tenc, :tiv2, :genc, :giv, ' +
|
||||||
' :e, :i, ''client'', :f, :t, :ts, :tiv, :k, ' +
|
' :e, :i, ''client'', :f, :ts, :tiv, :k, ' +
|
||||||
' :cf, :cfiv, :ic, :tpl, :uuid, :c, :c2)';
|
' :cf, :cfiv, :ic, :tpl, :uuid, :c, :c2)';
|
||||||
// Declare optional param types ONCE — the prepared statement is
|
// Declare optional param types ONCE — the prepared statement is
|
||||||
// reused across every imported entry, and FireDAC needs the
|
// reused across every imported entry, and FireDAC needs the
|
||||||
@@ -1306,7 +1301,6 @@ begin
|
|||||||
// row carries site_enc); the client validated before import.
|
// row carries site_enc); the client validated before import.
|
||||||
|
|
||||||
LQ.ParamByName('uid').AsInteger := LUserId;
|
LQ.ParamByName('uid').AsInteger := LUserId;
|
||||||
LQ.ParamByName('tt').AsString := LTitle;
|
|
||||||
BindNullable(LQ, 'uenc', LUserEnc);
|
BindNullable(LQ, 'uenc', LUserEnc);
|
||||||
BindNullable(LQ, 'uiv', LUserIv);
|
BindNullable(LQ, 'uiv', LUserIv);
|
||||||
BindNullable(LQ, 'senc', LSiteEnc);
|
BindNullable(LQ, 'senc', LSiteEnc);
|
||||||
@@ -1318,7 +1312,6 @@ begin
|
|||||||
LQ.ParamByName('e').AsString := LEnc;
|
LQ.ParamByName('e').AsString := LEnc;
|
||||||
LQ.ParamByName('i').AsString := LIV;
|
LQ.ParamByName('i').AsString := LIV;
|
||||||
LQ.ParamByName('f').AsString := LFolder;
|
LQ.ParamByName('f').AsString := LFolder;
|
||||||
LQ.ParamByName('t').AsString := LTags;
|
|
||||||
if LTotpSec = '' then LQ.ParamByName('ts').Clear
|
if LTotpSec = '' then LQ.ParamByName('ts').Clear
|
||||||
else LQ.ParamByName('ts').Value := LTotpSec;
|
else LQ.ParamByName('ts').Value := LTotpSec;
|
||||||
if LTotpIv = '' then LQ.ParamByName('tiv').Clear
|
if LTotpIv = '' then LQ.ParamByName('tiv').Clear
|
||||||
|
|||||||
Reference in New Issue
Block a user