mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
feat: add output package with Formatter interface (#537)
* docs: add RFC-004 for CLI (cobra) and output design * feat: add output package with Formatter interface and BrowserData.Each * fix: golangci config array syntax + add output package tests * refactor: encapsulated Output as Writer, collect-then-write pattern * refactor: unified row type with reflection-based CSV/JSON output * fix: ProfileName empty guard, writeFile close error check, sync RFC-004
This commit is contained in:
@@ -14,7 +14,6 @@ import (
|
||||
// Browser represents a single Chromium profile ready for extraction.
|
||||
type Browser struct {
|
||||
cfg types.BrowserConfig
|
||||
name string // display name: "Chrome-Default"
|
||||
profileDir string // absolute path to profile directory
|
||||
sources map[types.Category][]sourcePath // Category → candidate paths (priority order)
|
||||
extractors map[types.Category]categoryExtractor // Category → custom extract function override
|
||||
@@ -41,7 +40,6 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
}
|
||||
browsers = append(browsers, &Browser{
|
||||
cfg: cfg,
|
||||
name: cfg.Name + "-" + filepath.Base(profileDir),
|
||||
profileDir: profileDir,
|
||||
sources: sources,
|
||||
extractors: extractors,
|
||||
@@ -51,8 +49,12 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
return browsers, nil
|
||||
}
|
||||
|
||||
func (b *Browser) Name() string {
|
||||
return b.name
|
||||
func (b *Browser) BrowserName() string { return b.cfg.Name }
|
||||
func (b *Browser) ProfileName() string {
|
||||
if b.profileDir == "" {
|
||||
return ""
|
||||
}
|
||||
return filepath.Base(b.profileDir)
|
||||
}
|
||||
|
||||
// Extract copies browser files to a temp directory, retrieves the master key,
|
||||
@@ -68,7 +70,7 @@ func (b *Browser) Extract(categories []types.Category) (*types.BrowserData, erro
|
||||
|
||||
masterKey, err := b.getMasterKey(session)
|
||||
if err != nil {
|
||||
log.Debugf("get master key for %s: %v", b.name, err)
|
||||
log.Debugf("get master key for %s: %v", b.BrowserName()+"/"+b.ProfileName(), err)
|
||||
}
|
||||
|
||||
data := &types.BrowserData{}
|
||||
@@ -134,7 +136,7 @@ func (b *Browser) getMasterKey(session *filemanager.Session) ([]byte, error) {
|
||||
func (b *Browser) extractCategory(data *types.BrowserData, cat types.Category, masterKey []byte, path string) {
|
||||
if ext, ok := b.extractors[cat]; ok {
|
||||
if err := ext.extract(masterKey, path, data); err != nil {
|
||||
log.Debugf("extract %s for %s: %v", cat, b.name, err)
|
||||
log.Debugf("extract %s for %s: %v", cat, b.BrowserName()+"/"+b.ProfileName(), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -161,7 +163,7 @@ func (b *Browser) extractCategory(data *types.BrowserData, cat types.Category, m
|
||||
data.SessionStorage, err = extractSessionStorage(path)
|
||||
}
|
||||
if err != nil {
|
||||
log.Debugf("extract %s for %s: %v", cat, b.name, err)
|
||||
log.Debugf("extract %s for %s: %v", cat, b.BrowserName()+"/"+b.ProfileName(), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,6 @@ func TestExtractCategory_DefaultFallback(t *testing.T) {
|
||||
)
|
||||
|
||||
b := &Browser{
|
||||
name: "Test",
|
||||
extractors: nil, // no custom extractors
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
// Browser represents a single Firefox profile ready for extraction.
|
||||
type Browser struct {
|
||||
cfg types.BrowserConfig
|
||||
name string // display name: "Firefox-97nszz88.default-release"
|
||||
profileDir string // absolute path to profile directory
|
||||
sources map[types.Category][]sourcePath // Category → candidate paths (priority order)
|
||||
sourcePaths map[types.Category]resolvedPath // Category → discovered absolute path
|
||||
@@ -39,7 +38,6 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
}
|
||||
browsers = append(browsers, &Browser{
|
||||
cfg: cfg,
|
||||
name: cfg.Name + "-" + filepath.Base(profileDir),
|
||||
profileDir: profileDir,
|
||||
sources: firefoxSources,
|
||||
sourcePaths: sourcePaths,
|
||||
@@ -48,8 +46,12 @@ func NewBrowsers(cfg types.BrowserConfig) ([]*Browser, error) {
|
||||
return browsers, nil
|
||||
}
|
||||
|
||||
func (b *Browser) Name() string {
|
||||
return b.name
|
||||
func (b *Browser) BrowserName() string { return b.cfg.Name }
|
||||
func (b *Browser) ProfileName() string {
|
||||
if b.profileDir == "" {
|
||||
return ""
|
||||
}
|
||||
return filepath.Base(b.profileDir)
|
||||
}
|
||||
|
||||
// Extract copies browser files to a temp directory, retrieves the master key,
|
||||
@@ -65,7 +67,7 @@ func (b *Browser) Extract(categories []types.Category) (*types.BrowserData, erro
|
||||
|
||||
masterKey, err := b.getMasterKey(session, tempPaths)
|
||||
if err != nil {
|
||||
log.Debugf("get master key for %s: %v", b.name, err)
|
||||
log.Debugf("get master key for %s: %v", b.BrowserName()+"/"+b.ProfileName(), err)
|
||||
}
|
||||
|
||||
data := &types.BrowserData{}
|
||||
@@ -169,7 +171,7 @@ func (b *Browser) extractCategory(data *types.BrowserData, cat types.Category, m
|
||||
// Firefox does not support CreditCard or SessionStorage extraction.
|
||||
}
|
||||
if err != nil {
|
||||
log.Debugf("extract %s for %s: %v", cat, b.name, err)
|
||||
log.Debugf("extract %s for %s: %v", cat, b.BrowserName()+"/"+b.ProfileName(), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ func TestExtractCategory(t *testing.T) {
|
||||
insertMozPlace(1, "https://example.com", "Example", 3, 1000000),
|
||||
insertMozPlace(2, "https://go.dev", "Go", 1, 2000000),
|
||||
)
|
||||
b := &Browser{name: "Test"}
|
||||
b := &Browser{}
|
||||
data := &types.BrowserData{}
|
||||
b.extractCategory(data, types.History, nil, path)
|
||||
|
||||
@@ -199,7 +199,7 @@ func TestExtractCategory(t *testing.T) {
|
||||
[]string{mozCookiesSchema},
|
||||
insertMozCookie("session", "abc", ".example.com", "/", 1000000000000, 0, 0, 0),
|
||||
)
|
||||
b := &Browser{name: "Test"}
|
||||
b := &Browser{}
|
||||
data := &types.BrowserData{}
|
||||
b.extractCategory(data, types.Cookie, nil, path)
|
||||
|
||||
@@ -214,7 +214,7 @@ func TestExtractCategory(t *testing.T) {
|
||||
insertMozPlace(1, "https://github.com", "GitHub", 1, 1000000),
|
||||
insertMozBookmark(1, 1, 1, "GitHub", 1000000),
|
||||
)
|
||||
b := &Browser{name: "Test"}
|
||||
b := &Browser{}
|
||||
data := &types.BrowserData{}
|
||||
b.extractCategory(data, types.Bookmark, nil, path)
|
||||
|
||||
@@ -239,7 +239,7 @@ func TestExtractCategory(t *testing.T) {
|
||||
}
|
||||
]
|
||||
}`)
|
||||
b := &Browser{name: "Test"}
|
||||
b := &Browser{}
|
||||
data := &types.BrowserData{}
|
||||
b.extractCategory(data, types.Extension, nil, path)
|
||||
|
||||
@@ -248,7 +248,7 @@ func TestExtractCategory(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("UnsupportedCategory", func(t *testing.T) {
|
||||
b := &Browser{name: "Test"}
|
||||
b := &Browser{}
|
||||
data := &types.BrowserData{}
|
||||
// CreditCard and SessionStorage are not supported by Firefox
|
||||
b.extractCategory(data, types.CreditCard, nil, "unused")
|
||||
|
||||
Reference in New Issue
Block a user