Add browser save and update workflow

This commit is contained in:
Joe Julian
2026-04-23 21:00:29 -07:00
parent 14c9bc72f6
commit f82ddf7435
11 changed files with 683 additions and 52 deletions
+93
View File
@@ -170,6 +170,89 @@ func TestHandleRequestSearchLogins(t *testing.T) {
}
}
func TestHandleRequestSaveLoginUpdatesExistingEntry(t *testing.T) {
t.Parallel()
client := &fakeClient{
entries: []*keepassgov1.Entry{
{
Id: "vault-console",
Title: "Vault Console",
Username: "dannyocean",
Password: "old-password",
Url: "https://vault.example.invalid/login",
Path: []string{"Crew", "Internet"},
Fields: map[string]string{
"URL1": "vault.example.invalid",
"X-Role": "inside-man",
},
Tags: []string{"vault"},
Notes: "Original notes stay intact.",
},
},
}
resp := HandleRequest(context.Background(), Request{
Action: "save-login",
BearerToken: "secret",
EntryID: "vault-console",
Username: "dannyocean",
Password: "new-password",
URL: "https://vault.example.invalid/login",
}, "", client)
if !resp.Success {
t.Fatalf("HandleRequest(save-login update) success = false, error = %q", resp.Error)
}
if client.upserted == nil {
t.Fatal("HandleRequest(save-login update) did not upsert an entry")
}
if got := client.upserted.Id; got != "vault-console" {
t.Fatalf("upserted.Id = %q, want vault-console", got)
}
if got := client.upserted.Password; got != "new-password" {
t.Fatalf("upserted.Password = %q, want new-password", got)
}
if got := client.upserted.Fields["X-Role"]; got != "inside-man" {
t.Fatalf("upserted.Fields[X-Role] = %q, want inside-man", got)
}
if got := client.upserted.Notes; got != "Original notes stay intact." {
t.Fatalf("upserted.Notes = %q, want original notes", got)
}
}
func TestHandleRequestSaveLoginCreatesNewEntryInChosenPath(t *testing.T) {
t.Parallel()
client := &fakeClient{}
resp := HandleRequest(context.Background(), Request{
Action: "save-login",
BearerToken: "secret",
Title: "Bellagio Login",
Username: "linuscaldwell",
Password: "yellow-chip",
URL: "https://bellagio.example.invalid/login",
Path: []string{"Crew", "Internet"},
}, "", client)
if !resp.Success {
t.Fatalf("HandleRequest(save-login create) success = false, error = %q", resp.Error)
}
if client.upserted == nil {
t.Fatal("HandleRequest(save-login create) did not upsert an entry")
}
if got := client.upserted.Title; got != "Bellagio Login" {
t.Fatalf("upserted.Title = %q, want Bellagio Login", got)
}
if got := client.upserted.Username; got != "linuscaldwell" {
t.Fatalf("upserted.Username = %q, want linuscaldwell", got)
}
if got := client.upserted.Path; !slices.Equal(got, []string{"Crew", "Internet"}) {
t.Fatalf("upserted.Path = %v, want [Crew Internet]", got)
}
if got := client.upserted.Id; got == "" {
t.Fatal("upserted.Id = empty, want generated id")
}
}
func TestHandleRequestFindLoginsInfersLockedStatusFromRPC(t *testing.T) {
t.Parallel()
@@ -332,10 +415,12 @@ type fakeClient struct {
matches []*keepassgov1.BrowserLoginMatch
entries []*keepassgov1.Entry
credential *keepassgov1.GetBrowserCredentialResponse
upserted *keepassgov1.Entry
err error
matchesErr error
entriesErr error
credentialErr error
upsertErr error
statusCalls int
}
@@ -427,3 +512,11 @@ func (f *fakeClient) GetBrowserCredential(context.Context, string, string) (*kee
}
return f.credential, nil
}
func (f *fakeClient) UpsertEntry(_ context.Context, entry *keepassgov1.Entry) (*keepassgov1.Entry, error) {
if f.upsertErr != nil {
return nil, f.upsertErr
}
f.upserted = entry
return entry, nil
}