Skip to content

Commit dfa629c

Browse files
committed
fix(auth): --profile matches against directory path, not just display name
User reported `--profile "Profile 6"` failing because kooky returns the human display name (e.g. "Tammie") as `Browser.Profile()`, not the directory ("Profile 6"). The on-disk directory only appears in the cookie file path. Users see "Profile 6" in the path output and expect to be able to pass it as --profile, so make that work. internal/browsercookies.profileMatches: Substring-match the user's `--profile` argument against EITHER the human profile name (e.g. "Tammie", "Default") OR the cookie file path (e.g. ".../Chrome/Profile 6/Cookies"). Case-insensitive on both. The kooky-traversal call now goes through this helper. Both forms now work: x auth import --profile Tammie x auth import --profile tammie x auth import --profile "Profile 6" x auth import --profile "profile 6" Plus a TestProfileMatches with eight cases pinning the rule (display name match, substring match, path match, and three negative cases).
1 parent 6613b98 commit dfa629c

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

internal/browsercookies/browsercookies.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,14 @@ func Load(ctx context.Context, browser, profile, domain string) (*Result, error)
102102
}
103103
actualBrowser := c.Browser.Browser()
104104
actualProfile := c.Browser.Profile()
105+
actualPath := c.Browser.FilePath()
105106
if browser != "" && !strings.EqualFold(actualBrowser, browser) {
106107
continue
107108
}
108-
if profile != "" && !strings.Contains(strings.ToLower(actualProfile), strings.ToLower(profile)) {
109+
if profile != "" && !profileMatches(profile, actualProfile, actualPath) {
109110
continue
110111
}
111-
key := storeKey{browser: actualBrowser, profile: actualProfile, source: c.Browser.FilePath()}
112+
key := storeKey{browser: actualBrowser, profile: actualProfile, source: actualPath}
112113
b, ok := stores[key]
113114
if !ok {
114115
b = &bucket{key: key, cookies: map[string]string{}}
@@ -196,6 +197,22 @@ func List(ctx context.Context, domain string) ([]Match, error) {
196197
return out, nil
197198
}
198199

200+
// profileMatches returns true when `want` (the user-supplied --profile
201+
// substring) matches either the human profile name from kooky (e.g.
202+
// "Tammie", "Default", "Work") OR a path component of the cookie file
203+
// (e.g. "Profile 6" from ".../Chrome/Profile 6/Cookies"). Case-
204+
// insensitive substring on both. This keeps `--profile "Profile 6"`
205+
// working alongside `--profile tammie`.
206+
func profileMatches(want, name, path string) bool {
207+
w := strings.ToLower(want)
208+
if strings.Contains(strings.ToLower(name), w) {
209+
return true
210+
}
211+
// Match against the directory path so users can pass the on-disk
212+
// "Profile N" name they see in `x auth browsers`.
213+
return strings.Contains(strings.ToLower(path), w)
214+
}
215+
199216
// FormatCookieHeader joins the relevant subset of a cookie map into a
200217
// `name=value; name=value` string suitable for `Cookie:` headers and
201218
// for x-cli's auth-import parser. Only names in `wanted` are kept; pass

internal/browsercookies/browsercookies_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,32 @@ func TestListEmptyDomain(t *testing.T) {
8383
t.Error("expected error for empty domain")
8484
}
8585
}
86+
87+
func TestProfileMatches(t *testing.T) {
88+
cases := []struct {
89+
want string
90+
name string
91+
path string
92+
expect bool
93+
}{
94+
// Match by human profile name (kooky's Browser.Profile()).
95+
{"tammie", "Tammie", "/x/Chrome/Profile 6/Cookies", true},
96+
{"Tammie", "Tammie", "/x/Chrome/Profile 6/Cookies", true},
97+
{"tam", "Tammie", "/x/Chrome/Profile 6/Cookies", true},
98+
// Match by on-disk directory name (what users see in errors).
99+
{"Profile 6", "Tammie", "/x/Chrome/Profile 6/Cookies", true},
100+
{"profile 6", "Tammie", "/x/Chrome/Profile 6/Cookies", true},
101+
// Default profile.
102+
{"default", "Default", "/x/Chrome/Default/Cookies", true},
103+
// Misses.
104+
{"profile 7", "Tammie", "/x/Chrome/Profile 6/Cookies", false},
105+
{"work", "Tammie", "/x/Chrome/Profile 6/Cookies", false},
106+
}
107+
for _, tc := range cases {
108+
got := profileMatches(tc.want, tc.name, tc.path)
109+
if got != tc.expect {
110+
t.Errorf("profileMatches(%q, %q, %q) = %v, want %v",
111+
tc.want, tc.name, tc.path, got, tc.expect)
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)