Files
HackBrowserData/browser/chromium/extract_extension.go
T
Roger 1b8bb1df3d feat: add Chromium Browser with new v2 architecture (#530)
* feat: add Chromium Browser implementation with new architecture
* refactor: replace Walk with ReadDir+Stat for profile discovery
* refactor: remove queries override, use extractors for Yandex passwords
* refactor: remove dataSource wrapper, use []sourcePath directly
* fix: address Copilot review feedback on chromium_new.go
* fix: always call key retriever regardless of Local State existence
2026-04-04 01:41:02 +08:00

77 lines
2.2 KiB
Go

package chromium
import (
"fmt"
"os"
"github.com/tidwall/gjson"
"github.com/moond4rk/hackbrowserdata/types"
)
// defaultExtensionKeys are the JSON paths tried for standard Chromium browsers.
var defaultExtensionKeys = []string{
"extensions.settings",
"settings.extensions",
"settings.settings",
}
func extractExtensions(path string) ([]types.ExtensionEntry, error) {
return extractExtensionsWithKeys(path, defaultExtensionKeys)
}
// extractExtensionsWithKeys reads Secure Preferences and looks for extension
// settings under the given JSON key paths. This allows browser variants
// (e.g. Opera with "extensions.opsettings") to reuse the same parsing logic.
func extractExtensionsWithKeys(path string, keys []string) ([]types.ExtensionEntry, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var settings gjson.Result
for _, key := range keys {
settings = gjson.GetBytes(data, key)
if settings.Exists() {
break
}
}
if !settings.Exists() {
return nil, fmt.Errorf("cannot find extensions in settings")
}
var extensions []types.ExtensionEntry
settings.ForEach(func(id, ext gjson.Result) bool {
// Skip system/component extensions
// https://source.chromium.org/chromium/chromium/src/+/main:extensions/common/mojom/manifest.mojom
location := ext.Get("location").Int()
if location == 5 || location == 10 {
return true
}
manifest := ext.Get("manifest")
if !manifest.Exists() {
return true
}
extensions = append(extensions, types.ExtensionEntry{
Name: manifest.Get("name").String(),
ID: id.String(),
Description: manifest.Get("description").String(),
Version: manifest.Get("version").String(),
HomepageURL: manifest.Get("homepage_url").String(),
Enabled: ext.Get("state").Int() == 1,
})
return true
})
return extensions, nil
}
// extractOperaExtensions extracts extensions from Opera's Secure Preferences,
// which stores extension data under "extensions.opsettings" instead of the
// standard "extensions.settings".
func extractOperaExtensions(path string) ([]types.ExtensionEntry, error) {
return extractExtensionsWithKeys(path, []string{"extensions.opsettings"})
}