initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
//go:build darwin
|
||||
|
||||
package browser
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"recovery/recovery/types"
|
||||
)
|
||||
|
||||
var Browsers = []types.BrowserConfig{
|
||||
// Chromium family
|
||||
{Name: "Chrome", UserDataPath: "Google/Chrome", ProcessName: "Google Chrome"},
|
||||
{Name: "Chrome Beta", UserDataPath: "Google/Chrome Beta", ProcessName: "Google Chrome Beta"},
|
||||
{Name: "Chrome Canary", UserDataPath: "Google/Chrome Canary", ProcessName: "Google Chrome Canary"},
|
||||
{Name: "Chromium", UserDataPath: "Chromium", ProcessName: "Chromium"},
|
||||
{Name: "Edge", UserDataPath: "Microsoft Edge", ProcessName: "Microsoft Edge"},
|
||||
{Name: "Brave", UserDataPath: "BraveSoftware/Brave-Browser", ProcessName: "Brave Browser"},
|
||||
{Name: "Vivaldi", UserDataPath: "Vivaldi", ProcessName: "Vivaldi"},
|
||||
{Name: "Opera", UserDataPath: "com.operasoftware.Opera", ProcessName: "Opera", FlatProfile: true},
|
||||
{Name: "Opera GX", UserDataPath: "com.operasoftware.OperaGX", ProcessName: "Opera GX", FlatProfile: true},
|
||||
{Name: "Arc", UserDataPath: "Arc/User Data", ProcessName: "Arc"},
|
||||
{Name: "Yandex", UserDataPath: "Yandex/YandexBrowser", ProcessName: "Yandex"},
|
||||
// Firefox family
|
||||
{Name: "Firefox", UserDataPath: "Firefox", ProcessName: "firefox", IsFirefox: true},
|
||||
{Name: "LibreWolf", UserDataPath: "LibreWolf", ProcessName: "librewolf", IsFirefox: true},
|
||||
{Name: "Waterfox", UserDataPath: "Waterfox", ProcessName: "waterfox", IsFirefox: true},
|
||||
}
|
||||
|
||||
func GetLocalAppData() string {
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, "Library", "Application Support")
|
||||
}
|
||||
|
||||
func GetUserDataRoot(cfg types.BrowserConfig) string {
|
||||
return filepath.Join(GetLocalAppData(), 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")
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//go:build linux
|
||||
|
||||
package browser
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"recovery/recovery/types"
|
||||
)
|
||||
|
||||
var Browsers = []types.BrowserConfig{
|
||||
// Chromium family
|
||||
{Name: "Chrome", UserDataPath: "google-chrome", ProcessName: "chrome"},
|
||||
{Name: "Chrome Beta", UserDataPath: "google-chrome-beta", ProcessName: "chrome"},
|
||||
{Name: "Chrome Dev", UserDataPath: "google-chrome-unstable", ProcessName: "chrome"},
|
||||
{Name: "Chromium", UserDataPath: "chromium", ProcessName: "chromium"},
|
||||
{Name: "Edge", UserDataPath: "microsoft-edge", ProcessName: "msedge"},
|
||||
{Name: "Brave", UserDataPath: "BraveSoftware/Brave-Browser", ProcessName: "brave"},
|
||||
{Name: "Vivaldi", UserDataPath: "vivaldi", ProcessName: "vivaldi"},
|
||||
{Name: "Opera", UserDataPath: "opera", ProcessName: "opera", FlatProfile: true},
|
||||
// Firefox family
|
||||
{Name: "Firefox", UserDataPath: ".mozilla/firefox", ProcessName: "firefox", IsFirefox: true},
|
||||
{Name: "LibreWolf", UserDataPath: ".librewolf", ProcessName: "librewolf", IsFirefox: true},
|
||||
{Name: "Waterfox", UserDataPath: ".waterfox", ProcessName: "waterfox", IsFirefox: true},
|
||||
}
|
||||
|
||||
func GetLocalAppData() string {
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, ".config")
|
||||
}
|
||||
|
||||
func GetUserDataRoot(cfg types.BrowserConfig) string {
|
||||
if cfg.IsFirefox {
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, cfg.UserDataPath)
|
||||
}
|
||||
return filepath.Join(GetLocalAppData(), 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 := root
|
||||
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")
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
//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")
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package browser
|
||||
|
||||
import "log"
|
||||
|
||||
func logf(format string, args ...interface{}) {
|
||||
log.Printf("[browser] "+format, args...)
|
||||
}
|
||||
Reference in New Issue
Block a user