1use std::path::PathBuf;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum BrowserType {
5 Chrome,
6 Edge,
7 Brave,
8 Chromium,
9 Vivaldi,
10 Comet,
11 Dia,
12 Atlas,
13 Firefox,
14 Safari,
15}
16
17impl BrowserType {
18 pub fn name(&self) -> &str {
19 match self {
20 BrowserType::Chrome => "Chrome",
21 BrowserType::Edge => "Edge",
22 BrowserType::Brave => "Brave",
23 BrowserType::Chromium => "Chromium",
24 BrowserType::Vivaldi => "Vivaldi",
25 BrowserType::Comet => "Comet",
26 BrowserType::Dia => "Dia",
27 BrowserType::Atlas => "Atlas",
28 BrowserType::Firefox => "Firefox",
29 BrowserType::Safari => "Safari",
30 }
31 }
32
33 pub fn is_chromium_based(&self) -> bool {
34 matches!(
35 self,
36 BrowserType::Chrome
37 | BrowserType::Edge
38 | BrowserType::Brave
39 | BrowserType::Chromium
40 | BrowserType::Vivaldi
41 | BrowserType::Comet
42 | BrowserType::Dia
43 | BrowserType::Atlas
44 )
45 }
46}
47
48impl std::str::FromStr for BrowserType {
49 type Err = String;
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 match s.to_lowercase().as_str() {
52 "chrome" => Ok(BrowserType::Chrome),
53 "edge" => Ok(BrowserType::Edge),
54 "brave" => Ok(BrowserType::Brave),
55 "chromium" => Ok(BrowserType::Chromium),
56 "vivaldi" => Ok(BrowserType::Vivaldi),
57 "comet" => Ok(BrowserType::Comet),
58 "dia" => Ok(BrowserType::Dia),
59 "atlas" => Ok(BrowserType::Atlas),
60 "firefox" => Ok(BrowserType::Firefox),
61 "safari" => Ok(BrowserType::Safari),
62 other => Err(format!("Unknown browser: {}", other)),
63 }
64 }
65}
66
67#[derive(Debug, Clone)]
68pub struct Profile {
69 pub name: String,
70 pub path: PathBuf,
71 pub browser_type: BrowserType,
72}
73
74impl Profile {
75 pub fn new(name: String, path: PathBuf, browser_type: BrowserType) -> Self {
76 Self {
77 name,
78 path,
79 browser_type,
80 }
81 }
82
83 pub fn cookies_path(&self) -> PathBuf {
84 match self.browser_type {
85 BrowserType::Firefox => self.path.join("cookies.sqlite"),
86 BrowserType::Safari => self.path.clone(),
87 _ => self.path.join("Cookies"),
88 }
89 }
90
91 pub fn local_state_path(&self) -> PathBuf {
92 self.path
93 .parent()
94 .map(|p| p.join("Local State"))
95 .unwrap_or_else(|| PathBuf::from("Local State"))
96 }
97}
98
99#[derive(Debug, Clone)]
100pub struct Cookie {
101 pub name: String,
102 pub value: String,
103 pub domain: String,
104 pub path: String,
105 pub expires_utc: i64,
106 pub is_secure: bool,
107 pub is_httponly: bool,
108 pub same_site: i32,
109}
110
111impl Cookie {
112 pub fn is_expired(&self) -> bool {
113 use std::time::{SystemTime, UNIX_EPOCH};
114 let now = SystemTime::now()
115 .duration_since(UNIX_EPOCH)
116 .unwrap()
117 .as_secs() as i64;
118
119 let unix_timestamp = (self.expires_utc / 1_000_000) - 11644473600;
122 unix_timestamp > 0 && unix_timestamp < now
123 }
124}