88
99 "github.com/moond4rk/hackbrowserdata/browser/chromium"
1010 "github.com/moond4rk/hackbrowserdata/browser/firefox"
11+ "github.com/moond4rk/hackbrowserdata/crypto/keyretriever"
1112 "github.com/moond4rk/hackbrowserdata/log"
1213 "github.com/moond4rk/hackbrowserdata/types"
1314)
@@ -34,19 +35,27 @@ func PickBrowsers(opts PickOptions) ([]Browser, error) {
3435 return pickFromConfigs (platformBrowsers (), opts )
3536}
3637
37- // pickFromConfigs is the testable core of PickBrowsers.
38+ // pickFromConfigs is the testable core of PickBrowsers. It iterates over
39+ // platform browser configs, discovers installed profiles, and injects a
40+ // shared key retriever into Chromium browsers for decryption.
3841func pickFromConfigs (configs []types.BrowserConfig , opts PickOptions ) ([]Browser , error ) {
3942 name := strings .ToLower (opts .Name )
4043 if name == "" {
4144 name = "all"
4245 }
4346
47+ // Create a single key retriever shared across all Chromium browsers.
48+ // On macOS this avoids repeated password prompts; on other platforms
49+ // it's harmless (DPAPI reads Local State per-profile, D-Bus is stateless).
50+ retriever := keyretriever .DefaultRetriever (opts .KeychainPassword )
51+
4452 var browsers []Browser
4553 for _ , cfg := range configs {
4654 if name != "all" && cfg .Key != name {
4755 continue
4856 }
4957
58+ // Override profile directory when targeting a specific browser.
5059 if opts .ProfilePath != "" && name != "all" {
5160 if cfg .Kind == types .Firefox {
5261 cfg .UserDataDir = filepath .Dir (filepath .Clean (opts .ProfilePath ))
@@ -55,48 +64,60 @@ func pickFromConfigs(configs []types.BrowserConfig, opts PickOptions) ([]Browser
5564 }
5665 }
5766
58- if opts .KeychainPassword != "" {
59- cfg .KeychainPassword = opts .KeychainPassword
60- }
61-
62- bs , err := newBrowsers (cfg )
67+ found , err := newBrowsers (cfg )
6368 if err != nil {
6469 log .Errorf ("browser %s: %v" , cfg .Name , err )
6570 continue
6671 }
67- if len (bs ) == 0 {
72+ if len (found ) == 0 {
6873 log .Debugf ("browser %s not found at %s" , cfg .Name , cfg .UserDataDir )
6974 continue
7075 }
71- browsers = append (browsers , bs ... )
76+
77+ // Inject the shared key retriever into browsers that need it.
78+ // Chromium browsers implement retrieverSetter; Firefox does not.
79+ for _ , b := range found {
80+ if setter , ok := b .(retrieverSetter ); ok {
81+ setter .SetRetriever (retriever )
82+ }
83+ }
84+ browsers = append (browsers , found ... )
7285 }
7386 return browsers , nil
7487}
7588
76- // newBrowsers dispatches to the correct engine based on BrowserKind.
89+ // retrieverSetter is implemented by browsers that need an external key retriever.
90+ // This allows pickFromConfigs to inject the shared retriever after construction
91+ // without coupling the Browser interface to Chromium-specific concerns.
92+ type retrieverSetter interface {
93+ SetRetriever (keyretriever.KeyRetriever )
94+ }
95+
96+ // newBrowsers dispatches to the correct engine based on BrowserKind
97+ // and converts engine-specific types to the Browser interface.
7798func newBrowsers (cfg types.BrowserConfig ) ([]Browser , error ) {
7899 switch cfg .Kind {
79100 case types .Chromium , types .ChromiumYandex , types .ChromiumOpera :
80- bs , err := chromium .NewBrowsers (cfg )
101+ found , err := chromium .NewBrowsers (cfg )
81102 if err != nil {
82103 return nil , err
83104 }
84- browsers := make ([]Browser , len (bs ))
85- for i , b := range bs {
86- browsers [i ] = b
105+ result := make ([]Browser , len (found ))
106+ for i , b := range found {
107+ result [i ] = b
87108 }
88- return browsers , nil
109+ return result , nil
89110
90111 case types .Firefox :
91- bs , err := firefox .NewBrowsers (cfg )
112+ found , err := firefox .NewBrowsers (cfg )
92113 if err != nil {
93114 return nil , err
94115 }
95- browsers := make ([]Browser , len (bs ))
96- for i , b := range bs {
97- browsers [i ] = b
116+ result := make ([]Browser , len (found ))
117+ for i , b := range found {
118+ result [i ] = b
98119 }
99- return browsers , nil
120+ return result , nil
100121
101122 default :
102123 return nil , fmt .Errorf ("unknown browser kind: %d" , cfg .Kind )
0 commit comments