pwstore: keepassxc LIVE-VM proof + root-group entry-path fix
Proven end-to-end (scan→plan→commit→restore-from-backup) against the real keepassxc-cli 2.7.6 in the incredigo-sbx sandbox VM. The live run surfaced an adapter bug the fake CSV masked: KeePassXC's CSV "Group" column is the full path including the root group name (default root is "Passwords"), but keepassxc-cli addresses entries relative to root (/GitHub, not /Passwords/GitHub). kpEntryPath now drops the leading root segment; the unit test that encoded the buggy /Root/GitHub form is corrected and a nested-group table test added. Records the proof as data: docs/BROWSER-ROTATION.md promotes keepassxc MOCK-ONLY -> LIVE-VM (the others stay MOCK-ONLY). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -92,15 +92,24 @@ func (k *KeePassXC) Export(ctx context.Context, v *vault.Vault) ([]Account, erro
|
||||
return accts, nil
|
||||
}
|
||||
|
||||
// kpEntryPath builds the "/Group/Title" path keepassxc-cli edit expects. KeePassXC
|
||||
// exports the root group as "Root"; entries live under "/Root/<…>" but the CLI also
|
||||
// accepts the group path as exported, so we join them verbatim.
|
||||
// kpEntryPath builds the entry path keepassxc-cli edit/show expect. KeePassXC's CSV
|
||||
// "Group" column is the FULL group path INCLUDING the root group name (e.g. the
|
||||
// default DB names its root group "Passwords", so a top-level entry exports with
|
||||
// Group="Passwords"). The CLI, however, addresses entries RELATIVE to the root —
|
||||
// the root group name is omitted from the path: a root entry is "/GitHub", and a
|
||||
// nested entry "Passwords/Web/GitHub" is addressed "/Web/GitHub". So we drop the
|
||||
// first (root) segment of the exported group path. Verified against real
|
||||
// keepassxc-cli 2.7.6 in the sandbox VM (the buggy "/Root/GitHub" form 404s).
|
||||
func kpEntryPath(group, title string) string {
|
||||
group = strings.Trim(group, "/")
|
||||
if group == "" {
|
||||
return "/" + title
|
||||
}
|
||||
return "/" + group + "/" + title
|
||||
// Strip the leading root-group segment; keep any remaining nested subgroups.
|
||||
if _, rest, ok := strings.Cut(group, "/"); ok {
|
||||
return "/" + rest + "/" + title
|
||||
}
|
||||
return "/" + title
|
||||
}
|
||||
|
||||
// UpdatePassword changes one entry's password via `keepassxc-cli edit -p <db> <entry>`.
|
||||
|
||||
Reference in New Issue
Block a user