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.
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