refactor(browser): split installation and profile abstractions (#603)

* refactor(browser): split installation and profile abstractions

A Chromium installation shares one master key across its profiles, but
modeling each profile as its own Browser re-derived the key per profile.
Browser now represents one installation holding its profiles and derives
the key once; new types.Profile/ExtractResult/CountResult carry per-profile
results.

* style: gofumpt safari_test.go

* test(chromium): rename shadowed loop var to path
This commit is contained in:
Roger
2026-05-31 16:37:23 +08:00
committed by GitHub
parent d5dc81f1c0
commit b901f7dff0
28 changed files with 1359 additions and 1206 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ func dumpCmd() *cobra.Command {
hack-browser-data dump -f cookie-editor
hack-browser-data dump --zip`,
RunE: func(cmd *cobra.Command, args []string) error {
browsers, err := browser.PickBrowsers(browser.PickOptions{
browsers, err := browser.DiscoverBrowsersWithKeys(browser.PickOptions{
Name: browserName,
ProfilePath: profilePath,
KeychainPassword: keychainPw,
+6 -4
View File
@@ -17,12 +17,14 @@ func extractAndWrite(browsers []browser.Browser, categories []types.Category, ou
return err
}
for _, b := range browsers {
log.Infof("Extracting %s/%s...", b.BrowserName(), b.ProfileName())
data, extractErr := b.Extract(categories)
log.Infof("Extracting %s...", b.BrowserName())
results, extractErr := b.Extract(categories)
if extractErr != nil {
log.Errorf("extract %s/%s: %v", b.BrowserName(), b.ProfileName(), extractErr)
log.Errorf("extract %s: %v", b.BrowserName(), extractErr)
}
for _, r := range results {
w.Add(b.BrowserName(), r.Name, r.Data)
}
w.Add(b.BrowserName(), b.ProfileName(), data)
}
if err := w.Write(); err != nil {
return err
+1 -1
View File
@@ -35,7 +35,7 @@ func keysExportCmd() *cobra.Command {
Example: ` hack-browser-data keys export -o dump.json
hack-browser-data keys export -b chrome`,
RunE: func(cmd *cobra.Command, args []string) error {
browsers, err := browser.PickBrowsers(browser.PickOptions{
browsers, err := browser.DiscoverBrowsersWithKeys(browser.PickOptions{
Name: browserName,
KeychainPassword: keychainPw,
})
+10 -6
View File
@@ -43,7 +43,9 @@ func printBasic(out io.Writer, browsers []browser.Browser) error {
w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0)
fmt.Fprintln(w, "Browser\tProfile\tPath")
for _, b := range browsers {
fmt.Fprintf(w, "%s\t%s\t%s\n", b.BrowserName(), b.ProfileName(), b.ProfileDir())
for _, p := range b.Profiles() {
fmt.Fprintf(w, "%s\t%s\t%s\n", b.BrowserName(), p.Name, p.Dir)
}
}
return w.Flush()
}
@@ -58,12 +60,14 @@ func printDetail(out io.Writer, browsers []browser.Browser) error {
fmt.Fprintln(w)
for _, b := range browsers {
counts, _ := b.CountEntries(types.AllCategories)
fmt.Fprintf(w, "%s\t%s", b.BrowserName(), b.ProfileName())
for _, c := range types.AllCategories {
fmt.Fprintf(w, "\t%d", counts[c])
results, _ := b.CountEntries(types.AllCategories)
for _, r := range results {
fmt.Fprintf(w, "%s\t%s", b.BrowserName(), r.Name)
for _, c := range types.AllCategories {
fmt.Fprintf(w, "\t%d", r.Counts[c])
}
fmt.Fprintln(w)
}
fmt.Fprintln(w)
}
return w.Flush()
}