Use saved bindings in Advanced Sync lookup

This commit is contained in:
Joe Julian
2026-04-06 19:36:38 -07:00
parent fc59fb4869
commit 99ff89de32
2 changed files with 88 additions and 3 deletions
+45 -3
View File
@@ -2193,12 +2193,54 @@ func (u *ui) matchingAdvancedSyncRemoteCredentialEntries() []vault.Entry {
if baseURL == "" { if baseURL == "" {
return nil return nil
} }
var matches []vault.Entry remotePath := strings.TrimSpace(u.syncRemotePath.Text())
for _, entry := range u.availableRemoteCredentialEntries() { entries := u.availableRemoteCredentialEntries()
byID := make(map[string]vault.Entry, len(entries))
for _, entry := range entries {
byID[entry.ID] = entry
}
matches := make([]vault.Entry, 0, len(entries))
seen := make(map[string]struct{}, len(entries))
appendMatch := func(entry vault.Entry) {
if strings.TrimSpace(entry.ID) == "" {
return
}
if _, ok := seen[entry.ID]; ok {
return
}
seen[entry.ID] = struct{}{}
matches = append(matches, entry)
}
for _, entry := range entries {
if normalizeRemoteCredentialURL(entry.URL) != baseURL { if normalizeRemoteCredentialURL(entry.URL) != baseURL {
continue continue
} }
matches = append(matches, entry) appendMatch(entry)
}
profilesByID := make(map[string]vault.RemoteProfile)
for _, profile := range u.availableRemoteProfiles() {
profilesByID[profile.ID] = profile
}
localVaultPath := strings.TrimSpace(u.vaultPath.Text())
for _, record := range u.recentRemotes {
if localVaultPath != "" && strings.TrimSpace(record.LocalVaultPath) != localVaultPath {
continue
}
profile, ok := profilesByID[strings.TrimSpace(record.RemoteProfileID)]
if !ok {
continue
}
if normalizeRemoteCredentialURL(profile.BaseURL) != baseURL {
continue
}
if remotePath != "" && strings.TrimSpace(profile.Path) != remotePath && strings.TrimSpace(record.Path) != remotePath {
continue
}
entry, ok := byID[strings.TrimSpace(record.CredentialEntryID)]
if !ok {
continue
}
appendMatch(entry)
} }
return matches return matches
} }
+43
View File
@@ -5868,6 +5868,49 @@ func TestUIAdvancedSyncMatchingRemoteCredentialEntriesUsesBaseURL(t *testing.T)
} }
} }
func TestUIAdvancedSyncMatchingRemoteCredentialEntriesUsesSavedBindingForCurrentVault(t *testing.T) {
t.Parallel()
localVaultPath := filepath.Join(t.TempDir(), "family.kdbx")
u := newUIWithState("desktop", &uiSession{model: vault.Model{
Entries: []vault.Entry{
{ID: "remote-creds-1", Title: "WebDAV Sign-In", Username: "tjulian", Path: []string{"Crew", "Internet"}},
{ID: "entry-2", Title: "Vault Console", Username: "dannyocean", URL: "https://vault.crew.example.invalid", Path: []string{"Crew", "Internet"}},
},
RemoteProfiles: []vault.RemoteProfile{{
ID: "family-webdav",
Name: "Family Vault",
Backend: vault.RemoteBackendWebDAV,
BaseURL: "https://dav.example.invalid/remote.php/dav",
Path: "files/family/keepass.kdbx",
}},
}}, statePaths{
DefaultSaveAsPath: filepath.Join(t.TempDir(), "default.kdbx"),
RecentVaultsPath: filepath.Join(t.TempDir(), "recent-vaults.json"),
RecentRemotesPath: filepath.Join(t.TempDir(), "recent-remotes.json"),
UIPreferencesPath: filepath.Join(t.TempDir(), "ui-prefs.json"),
})
u.vaultPath.SetText(localVaultPath)
u.syncSourceMode = syncSourceRemote
u.syncRemoteBaseURL.SetText("https://dav.example.invalid/remote.php/dav")
u.syncRemotePath.SetText("files/family/keepass.kdbx")
u.recentRemotes = []recentRemoteRecord{{
BaseURL: "https://dav.example.invalid/remote.php/dav",
Path: "files/family/keepass.kdbx",
LocalVaultPath: localVaultPath,
RemoteProfileID: "family-webdav",
CredentialEntryID: "remote-creds-1",
}}
got := u.matchingAdvancedSyncRemoteCredentialEntries()
if len(got) != 1 {
t.Fatalf("len(matchingAdvancedSyncRemoteCredentialEntries()) = %d, want 1 from saved binding", len(got))
}
if got[0].ID != "remote-creds-1" {
t.Fatalf("matchingAdvancedSyncRemoteCredentialEntries() = %#v, want remote-creds-1 from saved binding", got)
}
}
func TestUIApplyAdvancedSyncRemoteCredentialEntryFillsCredentials(t *testing.T) { func TestUIApplyAdvancedSyncRemoteCredentialEntryFillsCredentials(t *testing.T) {
t.Parallel() t.Parallel()