mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-07-04 21:37:47 +02:00
* feat(restore): cross-platform restore via dump engine rebuild (#606) Restore previously required the dump's origin OS, overlaying keys onto locally-discovered browsers. It now rebuilds Chromium engines from the dump's vaults (v2 adds engine kind), so copied data or an archive zip decrypts on any OS. * fix(restore): polish help text, drop dead check, dedup dump kinds pflag treats backticked words in flag usage as the value placeholder, so --data-zip rendered as "--data-zip archive" in help output.
This commit is contained in:
@@ -54,9 +54,10 @@ func NewBrowser(cfg types.BrowserConfig) (*Browser, error) {
|
||||
// Extract; unused tiers stay nil.
|
||||
func (b *Browser) SetRetrievers(r masterkey.Retrievers) { b.retrievers = r }
|
||||
|
||||
func (b *Browser) BrowserName() string { return b.cfg.Name }
|
||||
func (b *Browser) BrowserKey() string { return b.cfg.Key }
|
||||
func (b *Browser) UserDataDir() string { return b.cfg.UserDataDir }
|
||||
func (b *Browser) BrowserName() string { return b.cfg.Name }
|
||||
func (b *Browser) BrowserKey() string { return b.cfg.Key }
|
||||
func (b *Browser) UserDataDir() string { return b.cfg.UserDataDir }
|
||||
func (b *Browser) Kind() types.BrowserKind { return b.cfg.Kind }
|
||||
|
||||
// Profiles returns the identity of every profile in this installation.
|
||||
func (b *Browser) Profiles() []types.Profile {
|
||||
@@ -162,12 +163,25 @@ func discoverProfiles(userDataDir string, sources map[types.Category][]sourcePat
|
||||
}
|
||||
}
|
||||
|
||||
// Flat layout fallback (older Opera): data files directly in userDataDir.
|
||||
// Opera stores data alongside Local State in userDataDir itself, so check
|
||||
// for any known source file instead of Preferences.
|
||||
// Flat layout (older Opera): data files directly under userDataDir with no profile subdir. Check the
|
||||
// root before the subdir fallback so a stray source-bearing subdir can't suppress root discovery.
|
||||
if len(profiles) == 0 && hasAnySource(sources, userDataDir) {
|
||||
profiles = append(profiles, userDataDir)
|
||||
}
|
||||
|
||||
// Restored/copied trees may omit the Preferences marker (it is no extraction source). When the marker
|
||||
// scan and flat-layout check both find nothing, treat any source-bearing subdir as a profile.
|
||||
if len(profiles) == 0 {
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() || isSkippedDir(e.Name()) {
|
||||
continue
|
||||
}
|
||||
dir := filepath.Join(userDataDir, e.Name())
|
||||
if hasAnySource(sources, dir) {
|
||||
profiles = append(profiles, dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
return profiles
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,50 @@ func TestNewBrowsers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// discoverProfiles: fallback boundaries (marker-less copies, flat-layout precedence)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func TestDiscoverProfiles(t *testing.T) {
|
||||
t.Run("markerless multi-subdir resolves all source-bearing dirs", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mkFile(dir, "Default", "History")
|
||||
mkFile(dir, "Profile 1", "History")
|
||||
assert.Len(t, discoverProfiles(dir, chromiumSources), 2)
|
||||
})
|
||||
|
||||
t.Run("marker present keeps fallback dormant", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mkFile(dir, "Default", "Preferences")
|
||||
mkFile(dir, "Default", "History")
|
||||
mkFile(dir, "NotAProfile", "History")
|
||||
got := discoverProfiles(dir, chromiumSources)
|
||||
require.Len(t, got, 1)
|
||||
assert.Equal(t, filepath.Join(dir, "Default"), got[0])
|
||||
})
|
||||
|
||||
t.Run("skipped dir ignored by markerless fallback", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mkFile(dir, "System Profile", "History")
|
||||
assert.Empty(t, discoverProfiles(dir, chromiumSources))
|
||||
})
|
||||
|
||||
t.Run("sourceless subdir ignored", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mkDir(dir, "Crashpad")
|
||||
assert.Empty(t, discoverProfiles(dir, chromiumSources))
|
||||
})
|
||||
|
||||
t.Run("flat-layout root wins over source-bearing subdir", func(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
mkFile(dir, "History")
|
||||
mkFile(dir, "Subthing", "History")
|
||||
got := discoverProfiles(dir, chromiumSources)
|
||||
require.Len(t, got, 1)
|
||||
assert.Equal(t, dir, got[0], "flat-layout root must win; subdir must not hijack discovery")
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user