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