From 99ff89de3254ec98d67b31a917a4004655d7230a Mon Sep 17 00:00:00 2001 From: Joe Julian Date: Mon, 6 Apr 2026 19:36:38 -0700 Subject: [PATCH] Use saved bindings in Advanced Sync lookup --- main.go | 48 +++++++++++++++++++++++++++++++++++++++++++++--- main_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 5bc6890..1aee591 100644 --- a/main.go +++ b/main.go @@ -2193,12 +2193,54 @@ func (u *ui) matchingAdvancedSyncRemoteCredentialEntries() []vault.Entry { if baseURL == "" { return nil } - var matches []vault.Entry - for _, entry := range u.availableRemoteCredentialEntries() { + remotePath := strings.TrimSpace(u.syncRemotePath.Text()) + 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 { 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 } diff --git a/main_test.go b/main_test.go index 7f99476..5cd044f 100644 --- a/main_test.go +++ b/main_test.go @@ -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) { t.Parallel()